#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
void pipeline( char * ar[], int pos, int in_fd);
void error_exit(const char*);
static int child = 0; /* whether it is a child process relative to main() */
int main(int argc, char * argv[]) {
if(argc < 2){
printf("Usage: %s option (option) ...\n", argv
[0]); }
pipeline(argv, 1, STDIN_FILENO);
return 0;
}
void error_exit(const char *kom){
(child
? _exit
: exit)(EXIT_FAILURE
); }
void pipeline(char *ar[], int pos, int in_fd){
if(ar[pos+1] == NULL){ /*last command */
if(in_fd != STDIN_FILENO){
if(dup2(in_fd, STDIN_FILENO) != -1)
close(in_fd); /*successfully redirected*/
else error_exit("dup2");
}
execlp(ar[pos], ar[pos], NULL);
error_exit("execlp last");
}
else{
int fd[2];
pid_t childpid;
if ((pipe(fd) == -1) || ((childpid = fork()) == -1)) {
error_exit("Failed to setup pipeline");
}
if (childpid == 0){ /* child executes current command */
child = 1;
close(fd[0]);
if (dup2(in_fd, STDIN_FILENO) == -1) /*read from in_fd */
perror("Failed to redirect stdin"); if (dup2(fd[1], STDOUT_FILENO) == -1) /*write to fd[1]*/
perror("Failed to redirect stdout"); else if ((close(fd[1]) == -1) || (close(in_fd) == - 1))
perror("Failed to close extra pipe descriptors"); else {
execlp(ar[pos], ar[pos], NULL);
error_exit("Failed to execlp");
}
}
close(fd[1]); /* parent executes the rest of commands */
close(in_fd);
pipeline(ar, pos+1, fd[0]);
}
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3RkbGliLmg+Cgp2b2lkIHBpcGVsaW5lKCBjaGFyICogYXJbXSwgaW50IHBvcywgaW50IGluX2ZkKTsKdm9pZCBlcnJvcl9leGl0KGNvbnN0IGNoYXIqKTsKc3RhdGljIGludCBjaGlsZCA9IDA7IC8qIHdoZXRoZXIgaXQgaXMgYSBjaGlsZCBwcm9jZXNzIHJlbGF0aXZlIHRvIG1haW4oKSAqLwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiBhcmd2W10pIHsKICBpZihhcmdjIDwgMil7CiAgICBwcmludGYoIlVzYWdlOiAlcyBvcHRpb24gKG9wdGlvbikgLi4uXG4iLCBhcmd2WzBdKTsKICAgIGV4aXQoMSk7CiAgfQogIHBpcGVsaW5lKGFyZ3YsIDEsIFNURElOX0ZJTEVOTyk7CiAgcmV0dXJuIDA7Cn0KCnZvaWQgZXJyb3JfZXhpdChjb25zdCBjaGFyICprb20pewogICBwZXJyb3Ioa29tKTsKICAgKGNoaWxkID8gX2V4aXQgOiBleGl0KShFWElUX0ZBSUxVUkUpOwp9Cgp2b2lkIHBpcGVsaW5lKGNoYXIgKmFyW10sIGludCBwb3MsIGludCBpbl9mZCl7CiAgIGlmKGFyW3BvcysxXSA9PSBOVUxMKXsgLypsYXN0IGNvbW1hbmQgKi8KICAgICBpZihpbl9mZCAhPSBTVERJTl9GSUxFTk8pewogICAgICAgIGlmKGR1cDIoaW5fZmQsIFNURElOX0ZJTEVOTykgIT0gLTEpCiAgICAgICAgICBjbG9zZShpbl9mZCk7IC8qc3VjY2Vzc2Z1bGx5IHJlZGlyZWN0ZWQqLwogICAgICAgIGVsc2UgZXJyb3JfZXhpdCgiZHVwMiIpOwogICAgIH0KICAgICBleGVjbHAoYXJbcG9zXSwgYXJbcG9zXSwgTlVMTCk7CiAgICAgZXJyb3JfZXhpdCgiZXhlY2xwIGxhc3QiKTsKICAgfQogICBlbHNlewogICAgIGludCBmZFsyXTsKICAgICBwaWRfdCBjaGlsZHBpZDsKCiAgICAgaWYgKChwaXBlKGZkKSA9PSAtMSkgfHwgKChjaGlsZHBpZCA9IGZvcmsoKSkgPT0gLTEpKSB7CiAgICAgICAgZXJyb3JfZXhpdCgiRmFpbGVkIHRvIHNldHVwIHBpcGVsaW5lIik7CiAgICAgfQogICAgIGlmIChjaGlsZHBpZCA9PSAwKXsJCQkJCS8qIGNoaWxkIGV4ZWN1dGVzIGN1cnJlbnQgY29tbWFuZCAqLwogICAgICAgIGNoaWxkID0gMTsKICAgICAgICBjbG9zZShmZFswXSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIGlmIChkdXAyKGluX2ZkLCBTVERJTl9GSUxFTk8pID09IC0xKSAgICAgICAgICAgLypyZWFkIGZyb20gaW5fZmQgKi8KICAgICAgICAgICBwZXJyb3IoIkZhaWxlZCB0byByZWRpcmVjdCBzdGRpbiIpOyAgICAgICAgIAogICAgICAgIGlmIChkdXAyKGZkWzFdLCBTVERPVVRfRklMRU5PKSA9PSAtMSkJCQkvKndyaXRlIHRvIGZkWzFdKi8KICAgICAgICAgICBwZXJyb3IoIkZhaWxlZCB0byByZWRpcmVjdCBzdGRvdXQiKTsKICAgICAgICBlbHNlIGlmICgoY2xvc2UoZmRbMV0pID09IC0xKSB8fCAoY2xvc2UoaW5fZmQpID09IC0gMSkpCiAgICAgICAgICAgcGVycm9yKCJGYWlsZWQgdG8gY2xvc2UgZXh0cmEgcGlwZSBkZXNjcmlwdG9ycyIpOwogICAgICAgIGVsc2UgewogICAgICAgICAgIGV4ZWNscChhcltwb3NdLCBhcltwb3NdLCBOVUxMKTsKICAgICAgICAgICBlcnJvcl9leGl0KCJGYWlsZWQgdG8gZXhlY2xwIik7CiAgICAgICAgfQogICAgIH0gCiAgICAgY2xvc2UoZmRbMV0pOwkJLyogcGFyZW50IGV4ZWN1dGVzIHRoZSByZXN0IG9mIGNvbW1hbmRzICovCiAgICAgY2xvc2UoaW5fZmQpOwogICAgIHBpcGVsaW5lKGFyLCBwb3MrMSwgZmRbMF0pOwogICB9Cn0KCg==