plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

t19.c (2403B)


      1 #include "a.h"
      2 
      3 /*
      4  * 19. Input/output file switching.
      5  */
      6 
      7 /* .so - push new source file */
      8 void
      9 r_so(int argc, Rune **argv)
     10 {
     11 	USED(argc);
     12 	pushinputfile(erunesmprint("%s", unsharp(esmprint("%S", argv[1]))));
     13 }
     14 
     15 /* .nx - end this file, switch to arg */
     16 void
     17 r_nx(int argc, Rune **argv)
     18 {
     19 	int n;
     20 
     21 	if(argc == 1){
     22 		while(popinput())
     23 			;
     24 	}else{
     25 		if(argc > 2)
     26 			warn("too many arguments for .nx");
     27 		while((n=popinput()) && n != 2)
     28 			;
     29 		pushinputfile(argv[1]);
     30 	}
     31 }
     32 
     33 /* .sy - system: run string */
     34 void
     35 r_sy(Rune *name)
     36 {
     37 	USED(name);
     38 	warn(".sy not implemented");
     39 }
     40 
     41 /* .pi - pipe output to string */
     42 void
     43 r_pi(Rune *name)
     44 {
     45 	USED(name);
     46 	warn(".pi not implemented");
     47 }
     48 
     49 /* .cf - copy contents of filename to output */
     50 void
     51 r_cf(int argc, Rune **argv)
     52 {
     53 	int c;
     54 	char *p;
     55 	Biobuf *b;
     56 
     57 	USED(argc);
     58 	p = esmprint("%S", argv[1]);
     59 	if((b = Bopen(p, OREAD)) == nil){
     60 		fprint(2, "%L: open %s: %r\n", p);
     61 		free(p);
     62 		return;
     63 	}
     64 	free(p);
     65 
     66 	while((c = Bgetrune(b)) >= 0)
     67 		outrune(c);
     68 	Bterm(b);
     69 }
     70 
     71 void
     72 r_inputpipe(Rune *name)
     73 {
     74 	Rune *cmd, *stop, *line;
     75 	int n, pid, p[2], len;
     76 	Waitmsg *w;
     77 
     78 	USED(name);
     79 	if(pipe(p) < 0){
     80 		warn("pipe: %r");
     81 		return;
     82 	}
     83 	stop = copyarg();
     84 	cmd = readline(CopyMode);
     85 	pid = fork();
     86 	switch(pid){
     87 	case 0:
     88 		if(p[0] != 0){
     89 			dup(p[0], 0);
     90 			close(p[0]);
     91 		}
     92 		close(p[1]);
     93 		execl(unsharp("#9/bin/rc"), "rc", "-c", esmprint("%S", cmd), nil);
     94 		warn("%Cdp %S: %r", dot, cmd);
     95 		_exits(nil);
     96 	case -1:
     97 		warn("fork: %r");
     98 	default:
     99 		close(p[0]);
    100 		len = runestrlen(stop);
    101 		fprint(p[1], ".ps %d\n", getnr(L(".s")));
    102 		fprint(p[1], ".vs %du\n", getnr(L(".v")));
    103 		fprint(p[1], ".ft %d\n", getnr(L(".f")));
    104 		fprint(p[1], ".ll 8i\n");
    105 		fprint(p[1], ".pl 30i\n");
    106 		while((line = readline(~0)) != nil){
    107 			if(runestrncmp(line, stop, len) == 0
    108 			&& (line[len]==' ' || line[len]==0 || line[len]=='\t'
    109 				|| (line[len]=='\\' && line[len+1]=='}')))
    110 				break;
    111 			n = runestrlen(line);
    112 			line[n] = '\n';
    113 			fprint(p[1], "%.*S", n+1, line);
    114 			free(line);
    115 		}
    116 		free(stop);
    117 		close(p[1]);
    118 		w = wait();
    119 		if(w == nil){
    120 			warn("wait: %r");
    121 			return;
    122 		}
    123 		if(w->msg[0])
    124 			sysfatal("%C%S %S: %s", dot, name, cmd, w->msg);
    125 		free(cmd);
    126 		free(w);
    127 	}
    128 }
    129 
    130 void
    131 t19init(void)
    132 {
    133 	addreq(L("so"), r_so, 1);
    134 	addreq(L("nx"), r_nx, -1);
    135 	addraw(L("sy"), r_sy);
    136 	addraw(L("inputpipe"), r_inputpipe);
    137 	addraw(L("pi"), r_pi);
    138 	addreq(L("cf"), r_cf, 1);
    139 
    140 	nr(L("$$"), getpid());
    141 }