/* test-pipe.c - Steven Arnow , 2014 */ #include #include #include #include #include #include #include #define FD_SET_NO_BLOCK(fd) (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK)) int main(int argc, char **argv) { int pipeout[2], pipeerr[2]; int pid, sz, outa, erra, max; siginfo_t info; char buff[512]; fd_set set; pipe(pipeout); pipe(pipeerr); pid = fork(); if (!pid) { dup2(pipeout[1], STDOUT_FILENO); dup2(pipeerr[1], STDERR_FILENO); close(pipeout[0]); close(pipeerr[0]); system("./test"); exit(-1); } else { close(pipeout[1]); close(pipeerr[1]); FD_SET_NO_BLOCK(pipeout[0]); FD_SET_NO_BLOCK(pipeerr[0]); outa = erra = 1; max = ((pipeout[1] > pipeerr[1]) ? pipeout[1] : pipeerr[1]) + 1; while (outa || erra) { FD_ZERO(&set); if (outa) FD_SET(pipeout[0], &set); if (erra) FD_SET(pipeerr[0], &set); select(max, &set, NULL, NULL, NULL); if (FD_ISSET(pipeout[0], &set)) { sz = read(pipeout[0], buff, 512); write(STDOUT_FILENO, buff, sz); if (sz <= 0) outa = 0; } if (FD_ISSET(pipeerr[0], &set)) { sz = read(pipeerr[0], buff, 512); write(STDERR_FILENO, buff, sz); if (sz <= 0) erra = 0; } } /* Wait for process to die */ waitid(P_PID, pid, &info, WEXITED); if (info.si_code != CLD_EXITED) { fprintf(stderr, "===== Abnormal termination =====\n"); return -1; } } return info.si_status; }