view toys/posix/tee.c @ 674:7e846e281e38

New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
author Rob Landley <>
date Mon, 08 Oct 2012 00:02:30 -0500
parents 6df4ccc0acbe
children 786841fdb1e0
line wrap: on
line source

/* vi: set sw=4 ts=4:
 * tee.c - cat to multiple outputs.
 * Copyright 2008 Rob Landley <>
 * See


config TEE
    bool "tee"
    default y
      usage: tee [-ai] [file...]

      Copy stdin to each listed file, and also to stdout.
      Filename "-" is a synonym for stdout.

      -a	append to files.
      -i	ignore SIGINT.

#define FOR_tee
#include "toys.h"

    void *outputs;

struct fd_list {
    struct fd_list *next;
    int fd;

// Open each output file, saving filehandles to a linked list.

static void do_tee_open(int fd, char *name)
    struct fd_list *temp;

    temp = xmalloc(sizeof(struct fd_list));
    temp->next = TT.outputs;
    temp->fd = fd;
    TT.outputs = temp;

void tee_main(void)
    if (toys.optflags & FLAG_i) signal(SIGINT, SIG_IGN);

    // Open output files
		O_RDWR|O_CREAT|((toys.optflags & FLAG_a)?O_APPEND:O_TRUNC),
		0666, 0, do_tee_open);

    for (;;) {
        struct fd_list *fdl;
        int len;

        // Read data from stdin
        len = xread(0, toybuf, sizeof(toybuf));
        if (len<1) break;

        // Write data to each output file, plus stdout.
        fdl = TT.outputs;
        for (;;) {
            if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1;
            if (!fdl) break;
            fdl = fdl->next;