Mods to tee...

Dan Ts'o dan at rna.UUCP
Mon Jan 14 13:25:17 AEST 1985


Hi,
	Recent I had reason to dig up an old mod I made to /bin/tee. Basically
the mods allow tee to accept shell pipeline commands as descriptors to
copy stdin to in addition to regular files. That is,

	$ tee file1 "|prog1 | prog2" file2

is possible, where the second argument is a shell pipeline which receives a
copy of stdin as well as a file1 and file2. This property is useful when, for
example, you want to view the data as its passing down the pipeline. I'm
forever doing something like,

	$ prog1 | tee /dev/tty | prog2

to view the pipeline data. Now it is also possible to do,

	$ prog1 | tee "|more" | prog2

or

	$ plot | tee "|gd" | spool_plot_to_laser_printer

where "gd" is the GPS graphics code dump program.

	Note that the stdout of each pipeline argument of this new tee is
that of the tee command itself. Thus it is often desireable to redirect
each pipeline's stdout explicitly,

	$ prog1 | tee "|more > /dev/tty" | prog2

so you don't have the pipeline output (if you expect any) to mix with "prog2"'s
input.

	Below are the diffs for 4.2BSD's tee...


					Cheers,
					Dan Ts'o
					Dept. Neurobiology
					Rockefeller Univ.
					1230 York Ave.
					NY, NY 10021
					212-570-7671
					...cmcl2!rna!dan


*** tee.c.org	Sun Jan 13 21:33:12 1985
--- tee.c	Sun Jan 13 22:01:29 1985
***************
*** 4,9
  /*
   * tee-- pipe fitting
   */
  
  #include <signal.h>
  #include <sys/types.h>

--- 4,21 -----
  /*
   * tee-- pipe fitting
   */
+ /*
+  * tee [files] [shell commandlines]
+  *
+  * Modified 1/85 by D. Ts'o to create multiple pipelines by calling the
+  *	shell upon arguments of the form
+  *	"| pipeline"	or
+  *	"^ pipeline"
+  * The standard input of the new pipeline is the tee program while the
+  *	standard output is the same as the tee program's standard output.
+  * Useful for branching off and filtering the same data several different
+  *	ways.
+  */
  
  #include <signal.h>
  #include <sys/types.h>
***************
*** 45,50
  	if(lseek(1,0L,1)==-1&&errno==ESPIPE)
  		t++;
  	while(argc-->1) {
  		if(aflag) {
  			openf[n] = open(argv[1],1);
  			if(openf[n] < 0)

--- 57,70 -----
  	if(lseek(1,0L,1)==-1&&errno==ESPIPE)
  		t++;
  	while(argc-->1) {
+ 	    /*
+ 	     * dyt - do pipelines
+ 	     */
+ 	    if(*argv[1] == '|' || *argv[1] == '^') {
+ 		if ((openf[n++] = mkpipe(argv[1])) < 0)
+ 			n--;
+ 	    }
+ 	    else {
  		if(aflag) {
  			openf[n] = open(argv[1],1);
  			if(openf[n] < 0)
***************
*** 62,67
  			n--;
  		}
  		argv++;
  	}
  	r = w = 0;
  	for(;;) {

--- 82,88 -----
  			n--;
  		}
  		argv++;
+ 	    }
  	}
  	r = w = 0;
  	for(;;) {
***************
*** 97,100
  {
  	while(*s)
  		write(2,s++,1);
  }

--- 118,158 -----
  {
  	while(*s)
  		write(2,s++,1);
+ }
+ 
+ mkpipe(cmd)
+ char *cmd;
+ {
+ 	register int i;
+ 	int p[2];
+ 
+ 	if(pipe(p)) {
+ 		puts("tee: bad pipe call: ");
+ 		puts(cmd);
+ 		puts("\n");
+ 		return(-1);
+ 	}
+ 
+ 	if((i = fork()) == 0) {
+ 		close(0);
+ 		close(p[1]);
+ 		dup(p[0]);
+ 		close(p[0]);
+ 		cmd++; 	/* Skip over | character */
+ 		execl("/bin/sh", "sh", "-c", cmd, 0);
+ 		puts("tee: no shell: ");
+ 		puts(cmd);
+ 		puts("\n");
+ 		exit(-1);
+ 	}
+ 
+ 	if(i == -1) {
+ 		puts("tee: bad fork call: ");
+ 		puts(cmd);
+ 		puts("\n");
+ 		return(-1);
+ 	}
+ 
+ 	close(p[0]);
+ 	return(p[1]);
  }



More information about the Comp.sources.unix mailing list