父子行中的dup2

时间:2014-01-02 11:23:48

标签: c dup2

我用C语言编写的服务器有一个奇怪的问题。

我有一个函数来处理连接到我的服务器的每个客户端,因此该函数为服务器接收的每个连接调用fork()。

问题是我在client-fork内部有其他的forks,它们应该在我创建的文件中写一个exec()的输出.I dup2()该文件的描述符带有stdout这样在第二个子进程(具有exec()调用的进程)之后,可以从父进程内的文件中读取输出。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>

#define PORT 2021

extern int errno;

void signal_handler( int sig )
{
  printf("[Server]Cought signal SIGCHLD\n");
  while( waitpid(-1, NULL, WNOHANG) > 0 )
    {
    }
}

int TreatClient(int clientSocket, int nr)
{
    int pid1,wait1;
    if ((pid1 = fork()) == -1)
    {
        printf("eroare pid");
        exit(1);
    }
    if(pid1 == 0) // treat client 
    {
        printf("START TREAT CLIENT!\n");
        nr++;
        int saved_stdout;
        char filename[3];
        snprintf(filename, 3,"%d",nr);
        int pid2,wait2;
        saved_stdout = dup(1);
        if ((pid2 = fork()) == -1)
        {
            printf("eroare pid");
            exit(1);
        }
        if(pid2 == 0)
        {
            printf("START DUP child!\n");
            int fd = open("fisier",O_CREAT|O_RDWR,00700);
            dup2(fd,1);
            printf("child 2 !\n");
            close(fd);
            return 1;
        }
        else
        {
            int fil;
            char chara;
            wait(&wait2);
            dup2(saved_stdout,1);
            close(saved_stdout);
            fil = open("fisier",O_RDONLY,00700);
            while(read(fil,&chara,1)!=-1 && chara != '\n')              printf("%c",chara);
            printf("\nEND PARENT dup !\n");
        }
        printf("TREAT CLIENT END!\n");
        return 1;
    }
    else
    {
        wait(&wait1);
        printf("END MAIN!\n");
    }
    return 1;
    }               /* while */
  return 0;
    return 1;
}

int main()
{
  struct sockaddr_in server;    
  struct sockaddr_in from;  
  char msg[100];        
  char rply[100]=" ";        
  int sd;           
  int on, status, nr = 0;

  if( signal(SIGCHLD, signal_handler) < 0 )
    {
      printf("[Server]Signal Error : %d !\n", errno);
      exit(-5);
    }

  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("[server]Socket Error !\n");
      return errno;
    }

  on = 1;
  status = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on));

  if ( status == -1 )
    {
      printf("[server]Setsockopt() Error : %d !\n", errno);
      exit(-1);
    }

  bzero (&server, sizeof (server));
  bzero (&from, sizeof (from));

    server.sin_family = AF_INET;    
    server.sin_addr.s_addr = htonl (INADDR_ANY);
    server.sin_port = htons (PORT);

  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
    {
      printf("[server]Bind Error : %d!\n", errno);
      exit(-2);
    }

  if (listen (sd, 5) == -1)
    {
      printf ("[server]Listen Error : %d!\n", errno);
      exit(-3);
    }
    ///////////////////////////////////////////////////////////////////////////////////////////
  /* client-iteration*/
  while (1)
    {
      int client;
      int length = sizeof (from);

      printf ("[server]Waiting at port %d...\n",PORT);
      fflush (stdout);

      client = accept (sd, (struct sockaddr *) &from, &length);
      nr++;

      if (client < 0)
    {
      printf ("[server]Accept Error : %d!\n", errno);
      continue;
    }

      printf("[server]Client number %d connected\n", nr);
      TreatClient(client, nr);
      return 1;
}

所需的输出与此类似:

[server]Waiting at port 2021...
[server]Client number 1 connected
START TREAT CLIENT!
START DUP child!
[Server]Cought signal SIGCHLD
child 2 !
END PARENT dup !
TREAT CLIENT END!
[Server]Cought signal SIGCHLD
END MAIN!

代码不会产生所需的输出。它在DUP2之后变得卡住,其余的输出被重定向到文件。但是,如果我用功能块替换TreatClient(client, nr);行,代码就可以正常工作。为什么会这样?另一个奇怪的问题是消息[server]Waiting at port 2021...也打印在文件中,而不是打印在屏幕上。

1 个答案:

答案 0 :(得分:1)

当第二个孩子完成时,它应该exit而不是返回。