|
|
1.1 root 1: #include "sam.h"
2: #include "parse.h"
3: #ifdef SUN
4: /* a hack to get around redef of ushort in sys/types.h .
5: this depends on non-use of ushort in this file */
6: #define ushort USHORT
7: #endif
8: #include <sys/types.h>
9: #include <sys/stat.h>
10: #include <signal.h>
11: #include <setjmp.h>
12:
13: extern jmp_buf mainloop;
14:
15: uchar errfile[64];
16: String unixcmd; /* null terminated */
17:
18: Unix(f, type, s, nest)
19: register File *f;
20: register type;
21: register String *s;
22: {
23: register pid, rpid;
24: int (*onbpipe)();
25: int retcode;
26: int pipe1[2], pipe2[2];
27: if(s->s[0]==0 && unixcmd.s[0]==0)
28: error(Enocmd);
29: else if(s->s[0])
30: strdupstr(&unixcmd, s);
31: if(downloaded){
32: strcpy(errfile, (uchar *)home);
33: strcat((char *)errfile, "/sam.err");
34: }else
35: strcpy(errfile, (uchar *)"/dev/tty");
36: if(type!='!' && pipe(pipe1)==-1)
37: error(Epipe);
38: unlink((char *)errfile);
39: if((pid=fork()) == 0){
40: if(downloaded){ /* also put nasty fd's into errfile */
41: int fd=creat((char *)errfile, 0666);
42: if(fd<0)
43: fd=creat("/dev/null", 0666);
44: #ifdef V8
45: close(3); /* v8 /dev/tty */
46: open("/dev/null", 2);
47: #endif
48: close(2);
49: dup(fd);
50: close(fd);
51: /* 2 now points at err file */
52: close(1);
53: if(type == '>')
54: dup(2);
55: else if(type=='!'){
56: dup(2);
57: fd=open("/dev/null", 0);
58: close(0);
59: dup(fd);
60: close(fd);
61: }
62: }
63: if(type!='!') {
64: if(type=='<' || type=='|'){
65: close(1);
66: dup(pipe1[1]);
67: }else if(type == '>'){
68: close(0);
69: dup(pipe1[0]);
70: }
71: close(pipe1[0]);
72: close(pipe1[1]);
73: }
74: if(type=='|'){
75: if(pipe(pipe2)==-1)
76: exit(1);
77: if((pid=fork())==0){
78: /*
79: * It's ok if we get SIGPIPE here
80: */
81: close(pipe2[0]);
82: io=pipe2[1];
83: if(retcode=!setjmp(mainloop)) /* assignment = */
84: (void)writeio(f);
85: exit(retcode);
86: }
87: if(pid==-1){
88: fprint(2, "Can't fork?!\n");
89: exit(1);
90: }
91: close(0);
92: dup(pipe2[0]);
93: close(pipe2[0]);
94: close(pipe2[1]);
95: }
96: Dclosefd();
97: if(type=='<'){
98: close(0); /* so it won't read from terminal */
99: open("/dev/null", 0);
100: }
101: execlp("sh", "sh", "-c", unixcmd.s, (char *)0);
102: exit(-1);
103: }
104: if(pid==-1)
105: error(Efork);
106: if(type=='<' || type=='|'){
107: if(downloaded)
108: outTl(Hsnarflen, addr.r.p2-addr.r.p1);
109: snarf(f, addr.r.p1, addr.r.p2);
110: Fdelete(f, addr.r.p1, addr.r.p2);
111: close(pipe1[1]);
112: io=pipe1[0];
113: f->dot.r.p2=addr.r.p2+readio(f, (int *)0, 0);
114: f->dot.r.p1=addr.r.p2;
115: closeio((Posn)-1);
116: }else if(type=='>'){
117: onbpipe = signal(SIGPIPE, SIG_IGN);
118: close(pipe1[0]);
119: io=pipe1[1];
120: (void)writeio(f);
121: closeio((Posn)-1);
122: signal(SIGPIPE, onbpipe);
123: }
124: do; while ((rpid = wait(&retcode)) != pid && rpid != -1);
125: retcode=(retcode>>8)&0377;
126: if(type=='|' || type=='<')
127: if(retcode!=0)
128: warn(Wbadstatus);
129: checkerrs();
130: if(!nest)
131: dprint("!\n");
132: }
133: checkerrs(){
134: struct stat statb;
135: char buf[256];
136: register f;
137: register n, nl;
138: register char *p;
139: if(stat((char *)errfile, &statb)==0 && statb.st_size){
140: if((f=open((char *)errfile, 0)) != -1){
141: if((n=read(f, buf, sizeof buf-1))>0){
142: for(nl=0,p=buf; nl<3 && p<&buf[n]; p++)
143: if(*p=='\n')
144: nl++;
145: *p=0;
146: dprint("%s", buf);
147: if(p-buf < statb.st_size-1)
148: dprint("(sam: more in %s)\n", errfile);
149: }
150: close(f);
151: }
152: }else
153: unlink((char *)errfile);
154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.