17aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley/* tee.c - cat to multiple outputs. 22bfaaf25614985ada5490d08e005b36f948d8186Rob Landley * 32bfaaf25614985ada5490d08e005b36f948d8186Rob Landley * Copyright 2008 Rob Landley <rob@landley.net> 42bfaaf25614985ada5490d08e005b36f948d8186Rob Landley * 5f91b7c89bc852868692b9518185421ebb52d67b3Rob Landley * See http://opengroup.org/onlinepubs/9699919799/utilities/tee.html 62bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 71dd3704c5ffea926f61a96bb7de7d9dbee52fa44Paul BarkerUSE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN)) 82bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 92bfaaf25614985ada5490d08e005b36f948d8186Rob Landleyconfig TEE 107aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley bool "tee" 117aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley default y 127aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley help 137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley usage: tee [-ai] [file...] 142bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 157aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley Copy stdin to each listed file, and also to stdout. 167aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley Filename "-" is a synonym for stdout. 172bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 187aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley -a append to files. 197aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley -i ignore SIGINT. 202bfaaf25614985ada5490d08e005b36f948d8186Rob Landley*/ 212bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 22c0e56edaf256adb6c60c5a052525a1ffbb927901Rob Landley#define FOR_tee 232bfaaf25614985ada5490d08e005b36f948d8186Rob Landley#include "toys.h" 242bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 25c0e56edaf256adb6c60c5a052525a1ffbb927901Rob LandleyGLOBALS( 267aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley void *outputs; 272bfaaf25614985ada5490d08e005b36f948d8186Rob Landley) 282bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 292bfaaf25614985ada5490d08e005b36f948d8186Rob Landleystruct fd_list { 307aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley struct fd_list *next; 317aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley int fd; 322bfaaf25614985ada5490d08e005b36f948d8186Rob Landley}; 332bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 342bfaaf25614985ada5490d08e005b36f948d8186Rob Landley// Open each output file, saving filehandles to a linked list. 352bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 362bfaaf25614985ada5490d08e005b36f948d8186Rob Landleystatic void do_tee_open(int fd, char *name) 372bfaaf25614985ada5490d08e005b36f948d8186Rob Landley{ 387aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley struct fd_list *temp; 392bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 407aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley temp = xmalloc(sizeof(struct fd_list)); 417aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley temp->next = TT.outputs; 427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley temp->fd = fd; 437aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley TT.outputs = temp; 442bfaaf25614985ada5490d08e005b36f948d8186Rob Landley} 452bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 462bfaaf25614985ada5490d08e005b36f948d8186Rob Landleyvoid tee_main(void) 472bfaaf25614985ada5490d08e005b36f948d8186Rob Landley{ 48c776bde13bb2767db2943bc3b02df737a465c035Rob Landley if (toys.optflags & FLAG_i) xsignal(SIGINT, SIG_IGN); 492bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 507aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // Open output files 517aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley loopfiles_rw(toys.optargs, 527aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley O_RDWR|O_CREAT|((toys.optflags & FLAG_a)?O_APPEND:O_TRUNC), 537aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley 0666, 0, do_tee_open); 542bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 557aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley for (;;) { 567aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley struct fd_list *fdl; 577aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley int len; 582bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 597aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // Read data from stdin 607aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley len = xread(0, toybuf, sizeof(toybuf)); 617aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (len<1) break; 622bfaaf25614985ada5490d08e005b36f948d8186Rob Landley 637aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // Write data to each output file, plus stdout. 647aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley fdl = TT.outputs; 657aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley for (;;) { 667aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1; 677aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!fdl) break; 687aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley fdl = fdl->next; 692bfaaf25614985ada5490d08e005b36f948d8186Rob Landley } 707aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 712bfaaf25614985ada5490d08e005b36f948d8186Rob Landley} 72