#include #include #include #include #include static int split(int fd[2]); static int redir(int fd, const char *file); static void sig_handler(int sig); static int parent; int main(void) { ssize_t bytes; char buf[256]; int fd[2]; // disable buffering for stdout setvbuf(stdout, NULL, _IONBF, 0); // redirect stdout to write into a file if (redir(1, "log.txt") < 0) { perror("redir()"); exit(-1); } // install the signal handler for Ctrl+C if (signal(SIGINT, sig_handler) == SIG_ERR) { perror("signal()"); exit(-1); } // split processes and assign file descriptors for communication switch (split(fd)) { case -1: // error exit(-1); case 0: // child while ((bytes = read(fd[0], buf, sizeof(buf))) > 0) { printf("[%u]: %s\n", getpid(), buf); sleep(1); write(fd[1], "pong", 5); } break; case 1: // parent parent = 1; write(fd[1], "ping", 5); while ((bytes = read(fd[0], buf, sizeof(buf))) > 0) { printf("[%u]: %s\n", getpid(), buf); sleep(1); write(fd[1], "ping", 5); } break; } // close the file descriptors close(fd[0]); close(fd[1]); return 0; } int split(int fd[2]) { int pfd[2][2]; if (pipe(pfd[0]) < 0) { perror("pipe()"); goto err_pipe1; } if (pipe(pfd[1]) < 0) { perror("pipe()"); goto err_pipe2; } switch (fork()) { case -1: perror("fork()"); goto err_fork; case 0: // child process close(pfd[0][1]); // close write for child close(pfd[1][0]); // close read for parent fd[0] = pfd[0][0]; // keep read for child fd[1] = pfd[1][1]; // keep write for parent return 0; default: // parent process close(pfd[1][1]); // close write for parent close(pfd[0][0]); // close read for child fd[0] = pfd[1][0]; // keep read for parent fd[1] = pfd[0][1]; // keep write for child return 1; } err_fork: close(pfd[1][0]); close(pfd[1][1]); err_pipe2: close(pfd[0][0]); close(pfd[0][1]); err_pipe1: return -1; } int redir(int fd, const char *file) { int fd2 = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd2 < 0) return -1; dup2(fd2, fd); close(fd2); return 0; } void sig_handler(int sig) { if (parent) { const char msg[] = "Programmabbruch durch Nutzer\n"; write(1, msg, sizeof(msg) - 1); } exit(0); }