diff --git a/wip/peek/peek.c b/wip/peek/peek.c index 8569173..59f0f7d 100644 --- a/wip/peek/peek.c +++ b/wip/peek/peek.c @@ -1,11 +1,13 @@ /* #include /* errno */ #include /* fprintf(3), getc(3), putc(3), EOF */ #include /* size_t */ -#if !defined EX_OK || !defined EX_USAGE +#include /* strerror(3) */ +#if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE # include #endif #include /* tcgetattr(3), tcsetattr(3), struct termios, ECHO */ -#include /* getopt(3), write(2), STDERR_FILENO, STDIN_FILENO */ +#include /* fork(2), getopt(3), pipe(2), write(2), STDERR_FILENO, + * STDOUT_FILENO */ static char *program_name = "peek"; @@ -14,43 +16,68 @@ int main(int argc, char *argv[]){ int eof; size_t i; char include_eof; - size_t j; - int outputs[] = {0 /* stdout */, 0 /* stderr */, 0 /* -p */, 0}; + int outputs[] = {0 /* stdout */, 0 /* stderr */, 0 /* -p */}; + int p[2] = {0, 0}; struct termios t; - /* disable terminal echo */ + /* terminal echo */ tcgetattr(STDIN_FILENO, &t); t.c_lflag ^= ECHO; tcsetattr(STDIN_FILENO, TCSAFLUSH, &t); + if(argc < 1) + argv[0] = program_name; + eof = EOF; include_eof = 0; - to_stderr = 0; - to_stdout = 0; while((c = getopt(argc, argv, "1enop:")) != -1) switch(c){ case '1': eof = '\n'; break; case 'n': include_eof = 1; break; - case 'o': outputs[0] = STDIN_FILENO; break; + case 'o': outputs[0] = STDOUT_FILENO; break; case 'e': outputs[1] = STDERR_FILENO; break; - case 'p': printf("not yet implemented\n"); + 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)); + 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; } - /* permute non-zero outputs to front */ - for(i = 0; i < (sizeof outputs) / (sizeof *outputs) - 1; ++i) - if(outputs[i] == 0) - for(j = 1; j < (sizeof outputs) / (sizeof *outputs); - ++j) - outputs[j - 1] = outputs[j]; + 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 */ + } + } do{ if((c = getc(stdin)) != eof || include_eof) - for(i = 0; outputs[i] != 0; ++i); - if(write(outputs[i], &c, 1) != 1) - {/* errro */} + for(i = 0; i < (sizeof outputs)/(sizeof *outputs); ++i) + if(outputs[i] != 0 + && write(outputs[i], &c, 1) + != 1) + {/* errno */} }while(c != eof); tcgetattr(STDIN_FILENO, &t);