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 }