c管道shell守护程序,日志功能不起作用

时间:2012-03-10 18:07:19

标签: c shell logging pipe daemon

我有以下代码:

#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>



int main (void) {
int fd_s=socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
struct sockaddr_in info_s = {.sin_family=AF_INET,.sin_port=htons(1024),.sin_zero={0,0,0,0,0,0,0},.sin_addr.s_addr=0};
bind(fd_s,&info_s,sizeof(info_s));
listen(fd_s,1);
int info_s_len=sizeof(struct sockaddr_in);
int fd_c;
struct sockaddr_in info_c;
while((fd_c=accept(fd_s, &info_c,&info_s_len))){
printf("client connected.\n");
if(!fork()){
int fd=open("log", O_RDWR|O_CREAT|O_APPEND|O_SYNC);
int p0[2],p1[2],p2[2];pipe2(p0, O_NONBLOCK);pipe2(p1, O_NONBLOCK);pipe2(p2, O_NONBLOCK);
dup2(p0[0], 0);
dup2(p1[1], 1);
dup2(p2[1], 2);
if(!fork()){
system("/bin/sh");
close(p0[0]);close(p0[1]);close(p1[0]);close(p1[1]);close(p2[0]);close(p2[1]);
close(fd_c);
close(fd);
printf("client disconnected.");
exit(0);
}else{
fd_set rd,wr;int on=1;//fcntl(fd_c, O_NONBLOCK, &on);
//char b[50];fwrite("ls;",3,1,fp_);fgets(b,50,fp_);printf(b);
FD_ZERO(&rd);FD_ZERO(&wr);
FD_SET(p1[0], &rd);FD_SET(p2[1],&rd);FD_SET(p0[1],&wr);FD_SET(fd_c, &rd);FD_SET(fd_c,&wr);
char *b=0; int bl,i;
while(select(p2[1]+1,&rd,&wr,0,0)){
char c;
if(FD_ISSET(fd_c,&rd)) {
b=realloc(b, 1*sizeof(char));
for(i=0,bl=1*sizeof(char);recv(fd_c,b+i,1,0)==1;i++,bl+=sizeof(char)){b=realloc(b, bl);}
write(p0[1],b,bl);
write(fd,b,bl);
free(b);
b=0;
}else if(FD_ISSET(p1[0],&rd)){
b=realloc(b, 1*sizeof(char));
for(i=0,bl=0;read(p0[0],b+i,1)>0;i++,bl+=sizeof(char)){b=realloc(b, bl);}
send(fd_c,b,bl,0);
write(fd,b,bl);
free(b);b=0;
}else if(FD_ISSET(p2[0],&rd)){
for(i=0,bl=0;read(p2[0],b+i,1)>0;i++,bl+=sizeof(char)){b=realloc(b, bl);}
send(fd_c,b,bl,0);
write(fd,b,bl);
free(b);b=0;
}
FD_ZERO(&rd);FD_ZERO(&wr);
FD_SET(p1[0], &rd);FD_SET(p2[1],&rd);FD_SET(p0[1],&wr);FD_SET(fd_c, &rd);FD_SET(fd_c,&wr);
}
}
}
}
return 0;
}

我做的时候

telnet localhost 1024

我的守护进程产生/bin/sh,所有发送的命令都保存到文件log。 但是,当我写(例如)时:id;我的守护进程没有回到客户端,也没有进入log文件。

我错过了什么?

P.D:当客户端断开关闭功能时,代码需要一些,我将在找到倾倒姿势时添加。

感谢。

2 个答案:

答案 0 :(得分:0)

除非发生错误,否则

execve()不会返回。 因此,此次通话下方的所有行都没有到达。

使用system()以便在孩子退出后继续:

   The value returned is -1 on  error  (e.g.   fork(2)  failed),  and  the
   return  status  of the command otherwise.  This latter return status is
   in the format specified in wait(2).  Thus, the exit code of the command
   will  be  WEXITSTATUS(status).   In case /bin/sh could not be executed,
   the exit status will be that of a command that does exit(127).

   If the value of command is NULL, system() returns nonzero if the  shell
   is available, and zero if not.

   system() does not affect the wait status of any other children.

答案 1 :(得分:0)

以下是我的解决方案。

#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>

int
main (void)
{
  int fd_s = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
  struct sockaddr_in info_s = {.sin_family = AF_INET,.sin_port =
      htons (1024),.sin_zero = {0, 0, 0, 0, 0, 0, 0},.sin_addr.s_addr = 0
  };
  bind (fd_s, &info_s, sizeof (info_s));
  listen (fd_s, 1);
  int info_s_len = sizeof (struct sockaddr_in);
  int fd_c;
  struct sockaddr_in info_c;
  while ((fd_c = accept (fd_s, &info_c, &info_s_len)))
    {
      printf ("client connected.\n");
      if (!fork ())
    {
      int fd = open ("log", O_WRONLY | O_CREAT | O_APPEND);
      int pty, tty;
      char *name;
      openpty (&pty, &tty, NULL, NULL, NULL);
      name = ttyname (tty);
      int p0[2], p1[2], p2[2];
      pipe (p0);
      pipe2 (p1, O_NONBLOCK);
      pipe2 (p2, O_NONBLOCK);
      dup2 (tty, 0);
      dup2 (tty, 1);
      dup2 (tty, 2);
      dup2 (p0[0], 0);
      dup2 (p1[1], 1);
      dup2 (p2[1], 2);
      if (!fork ())
        {
          system ("/bin/sh");
          close (p0[0]);
          close (p0[1]);
          close (p1[0]);
          close (p1[1]);
          close (p2[0]);
          close (p2[1]);
          close (fd_c);
          close (fd);
          // some log
          exit (0);
        }
      else
        {
          fd_set rd, wr;
          fcntl (fd_c, F_SETFL, O_NONBLOCK);
          FD_ZERO (&rd);
          FD_ZERO (&wr);
          FD_SET (p1[0], &rd);
          FD_SET (p2[0], &rd);
          FD_SET (fd_c, &rd);
          char *b = 0;
          int bl, i;
          while (select (p2[1] + 1, &rd, &wr, 0, 0))
        {
          char c;
          if (FD_ISSET (fd_c, &rd))
            {
              for (i = bl = b = 0; 1; i++)
            {
              char c;
              int ret = recv (fd_c, &c, sizeof (c), 0);
              if (ret == sizeof (c))
                {
                  bl += sizeof (char);
                  b = realloc (b, bl);
                  b[i] = c;
                }
              else if (ret == 0)
                {
                  close (fd_c);
                  free (b);
                  exit (0);
                }
              else if (ret == -1)
                {
                  write (p0[1], b, bl);
                  write (fd, b, bl);
                  free (b);
                  break;
                }
            }
            }
          else if (FD_ISSET (p1[0], &rd))
            {
              for (i = bl = b = 0; 1; i++)
            {
              char c;
              int ret = read (p1[0], &c, sizeof (c));
              if (ret == sizeof (c))
                {
                  bl += sizeof (c);
                  b = realloc (b, bl);
                  b[i] = c;
                }
              else if (ret == -1)
                {
                  send (fd_c, b, bl, 0);
                  write (fd, b, bl);
                  free (b);
                  break;
                }
              else
                {
                }
            }
            }
          else if (FD_ISSET (p2[0], &rd))
            {
              for (i = bl = b = 0; 1; i++)
            {
              char c;
              int ret = read (p2[0], &c, sizeof (c));
              if (ret == sizeof (c))
                {
                  bl += sizeof (c);
                  b = realloc (b, bl);
                  b[i] = c;
                }
              else if (ret == -1)
                {
                  send (fd_c, b, bl, 0);
                  write (fd, b, bl);
                  free (b);
                  break;
                }
            }
            }
          FD_ZERO (&rd);
          FD_ZERO (&wr);
          FD_SET (p1[0], &rd);
          FD_SET (p2[0], &rd);
          FD_SET (fd_c, &rd);
        }
        }
    }
    }
  return 0;
}

非常感谢...