scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 23c1e6b3bcd232347fa3cbf1b2d63316b448a5db
parent a1ca74d8062b528533a7e014bb36b97695ee0c6e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  6 Feb 2023 23:02:09 +0100

driver/posix: Implement internal tee command

The work done by tee(1) is very simple and making a exec seems
too much for something that can be done with a small loop. Also
some systems are having problems locating tee(1) in the path
and this patch solves the problem.

Diffstat:
Msrc/cmd/cc/posix/cc.c | 44+++++++++++++++++++++++++++++++++++++++++---
1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/cmd/cc/posix/cc.c b/src/cmd/cc/posix/cc.c @@ -51,11 +51,11 @@ static struct tool { pid_t pid; } tools[] = { [CC1] = {.cmd = "cc1"}, - [TEEIR] = {.bin = "tee", .cmd = "tee"}, + [TEEIR] = {.cmd = "tee"}, [CC2] = {.cmd = "cc2"}, - [TEEQBE] = {.bin = "tee", .cmd = "tee"}, + [TEEQBE] = {.cmd = "tee"}, [QBE] = {.bin = "qbe"}, - [TEEAS] = {.bin = "tee", .cmd = "tee"}, + [TEEAS] = {.cmd = "tee"}, [AS] = {.bin = "as", .cmd = "as"}, [LD] = {.bin = "ld", .cmd = "ld"}, }; @@ -292,6 +292,42 @@ settool(int tool, char *infile, int nexttool) return tool; } +/* + * We cannot call exit() because it would call the atexit() + * handlers. If it finishes correctly we already called + * fflush() in the output buffers so it is not a problem + * not following the normal exit path. + */ +static void +tee(char *fname) +{ + FILE *fp; + int ch; + + if ((fp = fopen(fname, "w")) == NULL) + goto err; + + while ((ch = getchar()) != EOF) { + putc(ch, stdout); + putc(ch, fp); + } + + fflush(stdout); + fflush(fp); + + if (ferror(stdin) || ferror(stdout) || ferror(fp)) + goto err; + _exit(0); + +err: + fprintf(stderr, + "tee: teeing %s: %s\n", + fname, + strerror(errno)); + + _exit(1); +} + static void spawn(int tool) { @@ -315,6 +351,8 @@ spawn(int tool) fprintf(stderr, " %s", *ap); putc('\n', stderr); } + if (strcmp(t->cmd, "tee") == 0) + tee(t->outfile); execvp(t->cmd, t->args.s); if (dflag) { fprintf(stderr,