#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#define MIN(m, n) ((m) < (n) ? (m) : (n))
#define BUFFER_SIZE 512
static int cat(const char *bufin, int inlen, char *bufout, int outlen) {
int pfd_stdin[2];
int pfd_stdout[2];
pid_t pid;
size_t len = 0;
if (pipe(pfd_stdin) == -1) {
perror("pipe");
exit(1);
}
if (pipe(pfd_stdout) == -1) {
perror("pipe");
exit(1);
}
pid = fork();
if (pid > 0) {
char buf[256];
size_t n;
int status;
close(pfd_stdin[0]);
close(pfd_stdout[1]);
if (write(pfd_stdin[1], bufin, inlen) == -1) {
perror("write");
exit(1);
}
close(pfd_stdin[1]);
while ((n = read(pfd_stdout[0], buf, 256)) > 0) {
memcpy(bufout, buf, MIN(n, outlen));
len += MIN(n, outlen);
outlen -= n;
if (outlen <= 0) {
break;
}
}
close(pfd_stdout[0]);
bufout[(outlen < 0 ? len - 1 : len)] = '\0';
if (waitpid(pid, &status, 0) == -1) {
perror("waitpid");
exit(1);
}
printf("exited, status=%d\n", status);
} else if (pid == 0) {
close(pfd_stdin[1]);
close(pfd_stdout[0]);
if (dup2(pfd_stdin[0], STDIN_FILENO) == -1) {
perror("dup2");
exit(1);
}
if (dup2(pfd_stdout[1], STDOUT_FILENO) == -1) {
perror("dup2");
exit(1);
}
if (execlp("cat", "cat", NULL) == -1) {
perror("execlp");
exit(1);
}
} else {
perror("fork");
exit(1);
}
return len;
}
int main() {
char *str = "London bridge is falling down";
char buf[BUFFER_SIZE + 1];
int len;
cat(str, strlen(str), buf, BUFFER_SIZE + 1);
puts(buf);
return 0;
}
~/work$ gcc foo.c -o foo && ./foo.exe
exited, status=0
London bridge is falling down