10f66f451Sopenharmony_ci/* tee.c - cat to multiple outputs. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2008 Rob Landley <rob@landley.net> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/tee.html 60f66f451Sopenharmony_ci 70f66f451Sopenharmony_ciUSE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN)) 80f66f451Sopenharmony_ci 90f66f451Sopenharmony_ciconfig TEE 100f66f451Sopenharmony_ci bool "tee" 110f66f451Sopenharmony_ci default y 120f66f451Sopenharmony_ci help 130f66f451Sopenharmony_ci usage: tee [-ai] [FILE...] 140f66f451Sopenharmony_ci 150f66f451Sopenharmony_ci Copy stdin to each listed file, and also to stdout. 160f66f451Sopenharmony_ci Filename "-" is a synonym for stdout. 170f66f451Sopenharmony_ci 180f66f451Sopenharmony_ci -a Append to files 190f66f451Sopenharmony_ci -i Ignore SIGINT 200f66f451Sopenharmony_ci*/ 210f66f451Sopenharmony_ci 220f66f451Sopenharmony_ci#define FOR_tee 230f66f451Sopenharmony_ci#include "toys.h" 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ciGLOBALS( 260f66f451Sopenharmony_ci void *outputs; 270f66f451Sopenharmony_ci int out; 280f66f451Sopenharmony_ci) 290f66f451Sopenharmony_ci 300f66f451Sopenharmony_cistruct fd_list { 310f66f451Sopenharmony_ci struct fd_list *next; 320f66f451Sopenharmony_ci int fd; 330f66f451Sopenharmony_ci}; 340f66f451Sopenharmony_ci 350f66f451Sopenharmony_ci// Open each output file, saving filehandles to a linked list. 360f66f451Sopenharmony_ci 370f66f451Sopenharmony_cistatic void do_tee_open(int fd, char *name) 380f66f451Sopenharmony_ci{ 390f66f451Sopenharmony_ci struct fd_list *temp; 400f66f451Sopenharmony_ci 410f66f451Sopenharmony_ci temp = xmalloc(sizeof(struct fd_list)); 420f66f451Sopenharmony_ci temp->next = TT.outputs; 430f66f451Sopenharmony_ci if (1 == (temp->fd = fd)) TT.out++; 440f66f451Sopenharmony_ci TT.outputs = temp; 450f66f451Sopenharmony_ci} 460f66f451Sopenharmony_ci 470f66f451Sopenharmony_civoid tee_main(void) 480f66f451Sopenharmony_ci{ 490f66f451Sopenharmony_ci struct fd_list *fdl; 500f66f451Sopenharmony_ci int len; 510f66f451Sopenharmony_ci 520f66f451Sopenharmony_ci if (FLAG(i)) xsignal(SIGINT, SIG_IGN); 530f66f451Sopenharmony_ci 540f66f451Sopenharmony_ci // Open output files (plus stdout if not already in output list) 550f66f451Sopenharmony_ci loopfiles_rw(toys.optargs, 560f66f451Sopenharmony_ci O_RDWR|O_CREAT|WARN_ONLY|(FLAG(a)?O_APPEND:O_TRUNC), 570f66f451Sopenharmony_ci 0666, do_tee_open); 580f66f451Sopenharmony_ci if (!TT.out) do_tee_open(1, 0); 590f66f451Sopenharmony_ci 600f66f451Sopenharmony_ci // Read data from stdin, write to each output file. 610f66f451Sopenharmony_ci for (;;) { 620f66f451Sopenharmony_ci if (1>(len = xread(0, toybuf, sizeof(toybuf)))) break; 630f66f451Sopenharmony_ci for (fdl = TT.outputs; fdl;fdl = fdl->next) 640f66f451Sopenharmony_ci if (len != writeall(fdl->fd, toybuf, len)) toys.exitval = 1; 650f66f451Sopenharmony_ci } 660f66f451Sopenharmony_ci} 67