#include <errno.h> // errno, EINTR
#include <stdio.h> // perror
#include <stdlib.h> // exit
#include <unistd.h> // _exit, close, dup2, execl, fork, pipe, STDOUT_FILENO
#include <sys/wait.h> // wait, pid_t
void handle_child_process_output(char *buffer, ssize_t count);
int main(void)
{
int filedes[2];
if (pipe(filedes) == -1)
{
}
pid_t pid = fork();
if (pid == -1)
{
}
else if (pid == 0)
{
while ((dup2(filedes[1], STDOUT_FILENO) == -1 && (errno == EINTR)))
{
continue;
}
close(filedes[1]);
close(filedes[0]);
static char *argv[] = {"echo", "Sphinx of black quartz, judge my vow.", NULL};
execv("/bin/echo", argv);
exit(EXIT_FAILURE
); // only if execv fails }
close(filedes[1]);
// at this point filedes[1] is open in child process to be written in
// and filedes[0] is open in parent process to be read from
char buffer[4096];
for (;;)
{
ssize_t count = read(filedes[0], buffer, sizeof(buffer));
if (count == -1)
{
if (errno == EINTR)
{
continue;
}
else
{
}
}
else if (count == 0)
{
break;
}
else
{
handle_child_process_output(buffer, count);
}
}
close(filedes[0]);
wait(NULL);
}
void handle_child_process_output(char *buffer, ssize_t count)
{
fwrite(buffer
, count
, sizeof(buffer
[0]), stdout
); }
I2luY2x1ZGUgPGVycm5vLmg+ICAgICAvLyBlcnJubywgRUlOVFIKI2luY2x1ZGUgPHN0ZGlvLmg+ICAgICAvLyBwZXJyb3IKI2luY2x1ZGUgPHN0ZGxpYi5oPiAgICAvLyBleGl0CiNpbmNsdWRlIDx1bmlzdGQuaD4gICAgLy8gX2V4aXQsIGNsb3NlLCBkdXAyLCBleGVjbCwgZm9yaywgcGlwZSwgU1RET1VUX0ZJTEVOTwojaW5jbHVkZSA8c3lzL3dhaXQuaD4gIC8vIHdhaXQsIHBpZF90CgoKdm9pZCBoYW5kbGVfY2hpbGRfcHJvY2Vzc19vdXRwdXQoY2hhciAqYnVmZmVyLCBzc2l6ZV90IGNvdW50KTsKCmludCBtYWluKHZvaWQpCnsKICAgIGludCBmaWxlZGVzWzJdOwogICAgaWYgKHBpcGUoZmlsZWRlcykgPT0gLTEpCiAgICB7CiAgICAgICAgcGVycm9yKCJwaXBlIik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgcGlkX3QgcGlkID0gZm9yaygpOwogICAgaWYgKHBpZCA9PSAtMSkKICAgIHsKICAgICAgICBwZXJyb3IoImZvcmsiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICBlbHNlIGlmIChwaWQgPT0gMCkKICAgIHsKICAgICAgICB3aGlsZSAoKGR1cDIoZmlsZWRlc1sxXSwgU1RET1VUX0ZJTEVOTykgPT0gLTEgJiYgKGVycm5vID09IEVJTlRSKSkpCiAgICAgICAgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgZnByaW50ZihzdGRvdXQsInBvaW50IDFcbiIpOwoKICAgICAgICBjbG9zZShmaWxlZGVzWzFdKTsKICAgICAgICBjbG9zZShmaWxlZGVzWzBdKTsKICAgICAgICBmcHJpbnRmKHN0ZG91dCwicG9pbnQgMlxuIik7CgogICAgICAgIHN0YXRpYyBjaGFyICphcmd2W10gPSB7ImVjaG8iLCAiU3BoaW54IG9mIGJsYWNrIHF1YXJ0eiwganVkZ2UgbXkgdm93LiIsIE5VTEx9OwogICAgICAgIGV4ZWN2KCIvYmluL2VjaG8iLCBhcmd2KTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7IC8vIG9ubHkgaWYgZXhlY3YgZmFpbHMKICAgIH0KICAgIGNsb3NlKGZpbGVkZXNbMV0pOwoKICAgIC8vIGF0IHRoaXMgcG9pbnQgZmlsZWRlc1sxXSBpcyBvcGVuIGluIGNoaWxkIHByb2Nlc3MgdG8gYmUgd3JpdHRlbiBpbgogICAgLy8gYW5kIGZpbGVkZXNbMF0gaXMgb3BlbiBpbiBwYXJlbnQgcHJvY2VzcyB0byBiZSByZWFkIGZyb20KICAgIGNoYXIgYnVmZmVyWzQwOTZdOwogICAgZm9yICg7OykKICAgIHsKICAgICAgICBzc2l6ZV90IGNvdW50ID0gcmVhZChmaWxlZGVzWzBdLCBidWZmZXIsIHNpemVvZihidWZmZXIpKTsKICAgICAgICBpZiAoY291bnQgPT0gLTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAoZXJybm8gPT0gRUlOVFIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcGVycm9yKCJyZWFkIik7CiAgICAgICAgICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoY291bnQgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBoYW5kbGVfY2hpbGRfcHJvY2Vzc19vdXRwdXQoYnVmZmVyLCBjb3VudCk7CiAgICAgICAgfQogICAgfQogICAgY2xvc2UoZmlsZWRlc1swXSk7CiAgICB3YWl0KE5VTEwpOwp9Cgp2b2lkIGhhbmRsZV9jaGlsZF9wcm9jZXNzX291dHB1dChjaGFyICpidWZmZXIsIHNzaXplX3QgY291bnQpCnsKICAgIHByaW50ZigiJXMiLCAiXHgxYlszNG0iKTsKICAgIGZ3cml0ZShidWZmZXIsIGNvdW50LCBzaXplb2YoYnVmZmVyWzBdKSwgc3Rkb3V0KTsKICAgIHByaW50ZigiJXMiLCAiXHgxYlswbSIpOwp9