diff --git a/wip/peek/peek.c b/wip/peek/peek.c index 59f0f7d..fca5335 100644 --- a/wip/peek/peek.c +++ b/wip/peek/peek.c @@ -1,4 +1,4 @@ -/* #include /* errno */ +#include /* errno */ #include /* fprintf(3), getc(3), putc(3), EOF */ #include /* size_t */ #include /* strerror(3) */ @@ -6,8 +6,8 @@ # include #endif #include /* tcgetattr(3), tcsetattr(3), struct termios, ECHO */ -#include /* fork(2), getopt(3), pipe(2), write(2), STDERR_FILENO, - * STDOUT_FILENO */ +#include /* dup(2), execvp(3), fork(2), getopt(3), pipe(2), + * write(2), STDERR_FILENO, STDOUT_FILENO */ static char *program_name = "peek"; @@ -26,58 +26,58 @@ int main(int argc, char *argv[]){ tcsetattr(STDIN_FILENO, TCSAFLUSH, &t); if(argc < 1) - argv[0] = program_name; + goto usage; eof = EOF; include_eof = 0; - while((c = getopt(argc, argv, "1enop:")) != -1) + while((c = getopt(argc, argv, "1enop")) != -1) switch(c){ case '1': eof = '\n'; break; case 'n': include_eof = 1; break; case 'o': outputs[0] = STDOUT_FILENO; break; case 'e': outputs[1] = STDERR_FILENO; break; case 'p': - printf("not implemented\n"); return; if(pipe(p) != 0){ fprintf(stderr, "%s: %s\n", - argv[0] == NULL - ? program_name - : argv[0], - strerror(errno)); + argv[0], strerror(errno)); return EX_OSERR; }else outputs[2] = p[1]; break; - default: - fprintf(stderr, "Usage: %s (-1eno) (-p [program])\n", - argv[0] == NULL ? program_name : argv[0]); - return EX_USAGE; + default: goto usage; } - if(outputs[2] != 0){ - switch(fork()){ - case -1: - fprintf(stderr, "%s: %s\n", argv[0], strerror(errno)); - return EX_OSERR; - case 0: - if(dup2(p[0], STDIN_FILENO) != STDIN_FILENO){ - fprintf(stderr, "%s: %s\n", - argv[0] == NULL - ? program_name - : argv[0], - strerror(errno)); - return EX_OSERR; - } - /* exec */ - } + if((argc > optind && outputs[2] == 0) + || (!(argc > optind) && outputs[2] != 0)){ +usage: fprintf(stderr, "Usage: %s (-1eno)" + " (-p [program [arguments...]])\n", + argv[0] == NULL ? program_name : argv[0]); + return EX_USAGE; } + if(outputs[2] != 0) + switch(fork()){ + case 0: + if(close(p[1]) == 0 + && dup2(p[0], STDIN_FILENO) + == STDIN_FILENO) + execvp(argv[optind], argv + optind); + case -1: + goto die; + default: + if(close(p[0]) != 0) + goto die; + } + do{ if((c = getc(stdin)) != eof || include_eof) for(i = 0; i < (sizeof outputs)/(sizeof *outputs); ++i) if(outputs[i] != 0 && write(outputs[i], &c, 1) - != 1) - {/* errno */} + == -1){ + if(i == 2) + close(outputs[i]); + outputs[i] = 0; + } }while(c != eof); tcgetattr(STDIN_FILENO, &t); @@ -85,4 +85,7 @@ int main(int argc, char *argv[]){ tcsetattr(STDIN_FILENO, TCSAFLUSH, &t); return EX_OK; + +die: fprintf(stderr, "%s: %s\n", argv[0], strerror(errno)); + return EX_USAGE; }