main.c
changeset 15 0acf8c3c4fe0
parent 14 286b248e402a
equal deleted inserted replaced
14:286b248e402a 15:0acf8c3c4fe0
    19     if (a > b)
    19     if (a > b)
    20         return a;
    20         return a;
    21     return b;
    21     return b;
    22 }
    22 }
    23 
    23 
    24 static int fork_app(int *opipe, char * const command[])
    24 static int fork_app(int *opipe /*[3]*/, char * const command[])
    25 {
    25 {
    26     int p_input[2]; /* from mpg321 to us */
    26     int p_input[2]; /* from mpg321 to us */
    27     int p_output[2]; /* from us to mpg321 */
    27     int p_output[2]; /* from us to mpg321 */
       
    28     int p_error[2]; /* from mpg321 to us, its stderr */
    28     int pid;
    29     int pid;
    29     int res;
    30     int res;
    30 
    31 
    31     pipe(p_input);
    32     pipe(p_input);
    32     pipe(p_output);
    33     pipe(p_output);
       
    34     pipe(p_error);
    33     opipe[0] = p_input[0]; /* For us to read */
    35     opipe[0] = p_input[0]; /* For us to read */
    34     opipe[1] = p_output[1]; /* For us to write */
    36     opipe[1] = p_output[1]; /* For us to write */
       
    37     opipe[2] = p_error[0]; /* For us to read */
    35 
    38 
    36     pid = fork();
    39     pid = fork();
    37 
    40 
    38     switch(pid)
    41     switch(pid)
    39     {
    42     {
    40         case 0: /* child */
    43         case 0: /* child */
    41             close(p_input[0]);
    44             close(p_input[0]);
    42             res = dup2(p_input[1], 1);
    45             res = dup2(p_input[1], 1);
    43             if (res == -1) perror("Dup2 1");
    46             if (res == -1) perror("Dup2 1");
    44             res = dup2(p_input[1], 2);
    47             close(p_error[0]);
       
    48             res = dup2(p_error[1], 2);
    45             if (res == -1) perror("Dup2 2");
    49             if (res == -1) perror("Dup2 2");
    46             close(p_input[1]);
    50             close(p_input[1]);
       
    51             close(p_error[1]);
       
    52 
    47             close(p_output[1]);
    53             close(p_output[1]);
    48             res = dup2(p_output[0], 0);
    54             res = dup2(p_output[0], 0);
    49             if (res == -1) perror("Dup2 3");
    55             if (res == -1) perror("Dup2 3");
    50             close(p_output[0]);
    56             close(p_output[0]);
    51 
    57 
    54             error("Cannot execlp %s", command[0]);
    60             error("Cannot execlp %s", command[0]);
    55         case -1:
    61         case -1:
    56             error("Failed fork");
    62             error("Failed fork");
    57         default: /* parent */
    63         default: /* parent */
    58             close(p_input[1]);
    64             close(p_input[1]);
       
    65             close(p_error[1]);
    59             close(p_output[0]);
    66             close(p_output[0]);
    60     }
    67     }
    61 
    68 
    62     return pid;
    69     return pid;
    63 }
    70 }
    76 
    83 
    77 static void loop(const int *child_pipe, int lsocket)
    84 static void loop(const int *child_pipe, int lsocket)
    78 {
    85 {
    79     char buf[100];
    86     char buf[100];
    80     fd_set read_set;
    87     fd_set read_set;
    81     int child_read, child_write;
    88     int child_read, child_write, child_read_error;
    82     int maxfd;
    89     int maxfd;
    83     int opened_socket;
    90     int opened_socket;
    84     int stdin_opened;
    91     int stdin_opened;
       
    92     int child_read_opened, child_read_error_opened;
    85     int res;
    93     int res;
    86 
    94 
    87     child_read = child_pipe[0];
    95     child_read = child_pipe[0];
       
    96     child_read_error = child_pipe[2];
    88     child_write = child_pipe[1];
    97     child_write = child_pipe[1];
    89 
    98 
    90     stdin_opened = 1;
    99     stdin_opened = 1;
    91     opened_socket = -1; /* no socket opened */
   100     opened_socket = -1; /* no socket opened */
       
   101     child_read_opened = 1;
       
   102     child_read_error_opened = 1;
    92     do
   103     do
    93     {
   104     {
    94         FD_ZERO(&read_set);
   105         FD_ZERO(&read_set);
       
   106         maxfd = 0;
    95 
   107 
    96         if (stdin_opened)
   108         if (stdin_opened)
    97             FD_SET(0, &read_set);
   109             FD_SET(0, &read_set);
    98         FD_SET(child_read, &read_set);
   110 
    99         maxfd = child_read;
   111         if (child_read_opened)
       
   112         {
       
   113             FD_SET(child_read, &read_set);
       
   114             maxfd = max(maxfd, child_read);
       
   115         }
       
   116 
       
   117         if (child_read_error_opened)
       
   118         {
       
   119             FD_SET(child_read_error, &read_set);
       
   120             maxfd = max(maxfd, child_read_error);
       
   121         }
       
   122 
   100         if (opened_socket >= 0)
   123         if (opened_socket >= 0)
   101         {
   124         {
   102             FD_SET(opened_socket, &read_set);
   125             FD_SET(opened_socket, &read_set);
   103             maxfd = max(maxfd, opened_socket);
   126             maxfd = max(maxfd, opened_socket);
   104         }
   127         }
   118                 continue;
   141                 continue;
   119             else
   142             else
   120                 error("Error in select()");
   143                 error("Error in select()");
   121         }
   144         }
   122 
   145 
   123         if (FD_ISSET(child_read, &read_set))
   146         if (child_read_opened && FD_ISSET(child_read, &read_set))
   124         {
   147         {
   125             res = forward_app_data(child_read, 1);
   148             res = forward_app_data(child_read, 1);
   126             if (res == 0)
   149             if (res == 0)
   127                 break;
   150             {
       
   151                 close(1);
       
   152                 child_read_opened = 0;
       
   153                 if (child_read_error_opened == 0)
       
   154                     break;
       
   155             }
       
   156         }
       
   157         if (child_read_error_opened && FD_ISSET(child_read_error, &read_set))
       
   158         {
       
   159             res = forward_app_data(child_read_error, 2);
       
   160             if (res == 0)
       
   161             {
       
   162                 close(2);
       
   163                 child_read_error_opened = 0;
       
   164                 if (child_read_opened == 0)
       
   165                     break;
       
   166             }
   128         }
   167         }
   129         if (FD_ISSET(0, &read_set))
   168         if (FD_ISSET(0, &read_set))
   130         {
   169         {
   131             res = forward_app_data(0, child_write);
   170             res = forward_app_data(0, child_write);
   132             if (res == 0)
   171             if (res == 0)
   151     } while(1);
   190     } while(1);
   152 }
   191 }
   153 
   192 
   154 static int server(int argn, char * const argv[])
   193 static int server(int argn, char * const argv[])
   155 {
   194 {
   156     int p[2];
   195     int p[3];
   157     int lsocket;
   196     int lsocket;
   158     int child;
   197     int child;
   159 
   198 
   160     child = fork_app(p, &argv[1]);
   199     child = fork_app(p, &argv[1]);
   161 
   200