File: tee.c

package info (click to toggle)
multitee 3.0-5
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 232 kB
  • ctags: 375
  • sloc: ansic: 1,673; makefile: 7
file content (122 lines) | stat: -rw-r--r-- 2,452 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* tee.c: clone of tee program
Daniel J. Bernstein, brnstnd@nyu.edu.
Depends on getopt.h, ralloc.h, fmt.h, sod.h.
Requires multitee. Otherwise portable to any UNIX system.
7/22/91: Baseline. tee 1.0, public domain.
No known patent problems.

Documentation in tee.1.

XXX: should use optprogname for program name
*/

#include <stdio.h> /* for fprintf(stderr,...) */
#include <signal.h> /* for SIGINT */
#include <sys/file.h>
#ifndef O_WRONLY
#define O_WRONLY 1 /* XXX: aargh */
#endif
#include "getopt.h"
#include "ralloc.h"
#include "fmt.h"
#include "sod.h"

SODdecl(argstack,char *);

main(argc,argv,envp)
int argc;
char *argv[];
char *envp[];
{
 int opt;
 int flagappend;
 int flagign;
 argstack arghead;
 argstack arg;
 char *t;
 int fd;
 unsigned int numargs;
 static char problem[1024];

 flagappend = 0;
 flagign = 0;
 while ((opt = getopt(argc,argv,"ai")) != opteof)
   switch(opt)
    {
     case 'a':
       flagappend = 1;
       break;
     case 'i':
       flagign = 1;
       break;
     case '?':
     default:
       exit(1);
    }
 argc -= optind;
 argv += optind;
 arghead = 0;

 if (flagign)
   signal(SIGINT,SIG_IGN);

 numargs = 2;
 while (*argv)
  {
   fd = open(*argv,O_WRONLY | O_CREAT | (flagappend ? O_APPEND : O_TRUNC),0666);
   if (fd == -1)
    {
     t = problem;
     t += fmt_strncpy(t,"tee: warning: cannot open ",0);
     t += fmt_strncpy(t,*argv,(problem + sizeof(problem)) - t - 3);
     *t = 0;
     perror(problem);
    }
   else
    {
     arg = SODalloc(argstack,arg,ralloc);
     if (!arg)
      {
       fprintf(stderr,"tee: fatal: out of memory\n");
       exit(3);
      }
     SODdata(arg) = ralloc(3 + fmt_uint(FMT_LEN,fd));
     if (!SODdata(arg))
      {
       fprintf(stderr,"tee: fatal: out of memory\n");
       exit(3);
      }
     t = SODdata(arg);
     t += fmt_strncpy(t,"0:",2); t += fmt_uint(t,fd); *t = 0;
     SODpush(arghead,arg);
     ++numargs;
    }
   ++argv;
  }

 argv = RALLOC(char *,numargs + 1);
 if (!argv)
  {
   fprintf(stderr,"tee: fatal: out of memory\n");
   exit(3);
  }

 argv[numargs] = 0;
 while (arghead)
  {
   SODpop(arghead,arg);
   argv[--numargs] = SODdata(arg);
   SODfree(arg,rfree);
  }
 argv[--numargs] = "0:1";
 argv[--numargs] = "multitee";
 /* numargs is now 0 */

 execvp(argv[0],argv);
 t = problem;
 t += fmt_strncpy(t,"tee: fatal: cannot execute ",0);
 t += fmt_strncpy(t,*argv,(problem + sizeof(problem)) - t - 3);
 *t = 0;
 perror(problem);
 exit(4);
}