|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)service.c 4.3 9/9/83";
3: #endif
4:
5: #
6: /*
7: * UNIX shell
8: *
9: * S. R. Bourne
10: * Bell Telephone Laboratories
11: *
12: */
13:
14: #include "defs.h"
15:
16:
17: PROC VOID gsort();
18:
19: #define ARGMK 01
20:
21: INT errno;
22: STRING sysmsg[];
23:
24: /* fault handling */
25: #define ENOMEM 12
26: #define ENOEXEC 8
27: #define E2BIG 7
28: #define ENOENT 2
29: #define ETXTBSY 26
30:
31:
32:
33: /* service routines for `execute' */
34:
35: VOID initio(iop)
36: IOPTR iop;
37: {
38: REG STRING ion;
39: REG INT iof, fd;
40:
41: IF iop
42: THEN iof=iop->iofile;
43: ion=mactrim(iop->ioname);
44: IF *ion ANDF (flags&noexec)==0
45: THEN IF iof&IODOC
46: THEN subst(chkopen(ion),(fd=tmpfil()));
47: close(fd); fd=chkopen(tmpout); unlink(tmpout);
48: ELIF iof&IOMOV
49: THEN IF eq(minus,ion)
50: THEN fd = -1;
51: close(iof&IOUFD);
52: ELIF (fd=stoi(ion))>=USERIO
53: THEN failed(ion,badfile);
54: ELSE fd=dup(fd);
55: FI
56: ELIF (iof&IOPUT)==0
57: THEN fd=chkopen(ion);
58: ELIF flags&rshflg
59: THEN failed(ion,restricted);
60: ELIF iof&IOAPP ANDF (fd=open(ion,1))>=0
61: THEN lseek(fd, 0L, 2);
62: ELSE fd=create(ion);
63: FI
64: IF fd>=0
65: THEN rename(fd,iof&IOUFD);
66: FI
67: FI
68: initio(iop->ionxt);
69: FI
70: }
71:
72: STRING getpath(s)
73: STRING s;
74: {
75: REG STRING path;
76: IF any('/',s)
77: THEN IF flags&rshflg
78: THEN failed(s, restricted);
79: ELSE return(nullstr);
80: FI
81: ELIF (path = pathnod.namval)==0
82: THEN return(defpath);
83: ELSE return(cpystak(path));
84: FI
85: }
86:
87: INT pathopen(path, name)
88: REG STRING path, name;
89: {
90: REG UFD f;
91:
92: REP path=catpath(path,name);
93: PER (f=open(curstak(),0))<0 ANDF path DONE
94: return(f);
95: }
96:
97: STRING catpath(path,name)
98: REG STRING path;
99: STRING name;
100: {
101: /* leaves result on top of stack */
102: REG STRING scanp = path,
103: argp = locstak();
104:
105: WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD
106: IF scanp!=path THEN *argp++='/' FI
107: IF *scanp==COLON THEN scanp++ FI
108: path=(*scanp ? scanp : 0); scanp=name;
109: WHILE (*argp++ = *scanp++) DONE
110: return(path);
111: }
112:
113: LOCAL STRING xecmsg;
114: LOCAL STRING *xecenv;
115:
116: VOID execa(at)
117: STRING at[];
118: {
119: REG STRING path;
120: REG STRING *t = at;
121:
122: IF (flags&noexec)==0
123: THEN xecmsg=notfound; path=getpath(*t);
124: namscan(exname);
125: xecenv=setenv();
126: WHILE path=execs(path,t) DONE
127: failed(*t,xecmsg);
128: FI
129: }
130:
131: LOCAL STRING execs(ap,t)
132: STRING ap;
133: REG STRING t[];
134: {
135: REG STRING p, prefix;
136:
137: prefix=catpath(ap,t[0]);
138: trim(p=curstak());
139:
140: sigchk();
141: execve(p, &t[0] ,xecenv);
142: SWITCH errno IN
143:
144: case ENOEXEC:
145: flags=0;
146: comdiv=0; ioset=0;
147: clearup(); /* remove open files and for loop junk */
148: IF input THEN close(input) FI
149: close(output); output=2;
150: input=chkopen(p);
151:
152: /* band aid to get csh... 2/26/79 */
153: {
154: char c;
155: if (!isatty(input)) {
156: read(input, &c, 1);
157: if (c == '#')
158: gocsh(t, p, xecenv);
159: lseek(input, (long) 0, 0);
160: }
161: }
162:
163: /* set up new args */
164: setargs(t);
165: longjmp(subshell,1);
166:
167: case ENOMEM:
168: failed(p,toobig);
169:
170: case E2BIG:
171: failed(p,arglist);
172:
173: case ETXTBSY:
174: failed(p,txtbsy);
175:
176: default:
177: xecmsg=badexec;
178: case ENOENT:
179: return(prefix);
180: ENDSW
181: }
182:
183: gocsh(t, cp, xecenv)
184: register char **t, *cp, **xecenv;
185: {
186: char **newt[1000];
187: register char **p;
188: register int i;
189:
190: for (i = 0; t[i]; i++)
191: newt[i+1] = t[i];
192: newt[i+1] = 0;
193: newt[0] = "/bin/csh";
194: newt[1] = cp;
195: execve("/bin/csh", newt, xecenv);
196: }
197:
198: /* for processes to be waited for */
199: #define MAXP 20
200: LOCAL INT pwlist[MAXP];
201: LOCAL INT pwc;
202:
203: postclr()
204: {
205: REG INT *pw = pwlist;
206:
207: WHILE pw <= &pwlist[pwc]
208: DO *pw++ = 0 OD
209: pwc=0;
210: }
211:
212: VOID post(pcsid)
213: INT pcsid;
214: {
215: REG INT *pw = pwlist;
216:
217: IF pcsid
218: THEN WHILE *pw DO pw++ OD
219: IF pwc >= MAXP-1
220: THEN pw--;
221: ELSE pwc++;
222: FI
223: *pw = pcsid;
224: FI
225: }
226:
227: VOID await(i)
228: INT i;
229: {
230: INT rc=0, wx=0;
231: INT w;
232: INT ipwc = pwc;
233:
234: post(i);
235: WHILE pwc
236: DO REG INT p;
237: REG INT sig;
238: INT w_hi;
239:
240: BEGIN
241: REG INT *pw=pwlist;
242: IF setjmp(INTbuf) == 0
243: THEN trapjmp[INTR] = 1; p=wait(&w);
244: ELSE p = -1;
245: FI
246: trapjmp[INTR] = 0;
247: WHILE pw <= &pwlist[ipwc]
248: DO IF *pw==p
249: THEN *pw=0; pwc--;
250: ELSE pw++;
251: FI
252: OD
253: END
254:
255: IF p == -1 THEN continue FI
256:
257: w_hi = (w>>8)&LOBYTE;
258:
259: IF sig = w&0177
260: THEN IF sig == 0177 /* ptrace! return */
261: THEN prs("ptrace: ");
262: sig = w_hi;
263: FI
264: IF sysmsg[sig]
265: THEN IF i!=p ORF (flags&prompt)==0 THEN prp(); prn(p); blank() FI
266: prs(sysmsg[sig]);
267: IF w&0200 THEN prs(coredump) FI
268: FI
269: newline();
270: FI
271:
272: IF rc==0
273: THEN rc = (sig ? sig|SIGFLG : w_hi);
274: FI
275: wx |= w;
276: OD
277:
278: IF wx ANDF flags&errflg
279: THEN exitsh(rc);
280: FI
281: exitval=rc; exitset();
282: }
283:
284: BOOL nosubst;
285:
286: trim(at)
287: STRING at;
288: {
289: REG STRING p;
290: REG CHAR c;
291: REG CHAR q=0;
292:
293: IF p=at
294: THEN WHILE c = *p
295: DO *p++=c&STRIP; q |= c OD
296: FI
297: nosubst=q"E;
298: }
299:
300: STRING mactrim(s)
301: STRING s;
302: {
303: REG STRING t=macro(s);
304: trim(t);
305: return(t);
306: }
307:
308: STRING *scan(argn)
309: INT argn;
310: {
311: REG ARGPTR argp = Rcheat(gchain)&~ARGMK;
312: REG STRING *comargn, *comargm;
313:
314: comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS;
315:
316: WHILE argp
317: DO *--comargn = argp->argval;
318: IF argp = argp->argnxt
319: THEN trim(*comargn);
320: FI
321: IF argp==0 ORF Rcheat(argp)&ARGMK
322: THEN gsort(comargn,comargm);
323: comargm = comargn;
324: FI
325: /* Lcheat(argp) &= ~ARGMK; */
326: argp = Rcheat(argp)&~ARGMK;
327: OD
328: return(comargn);
329: }
330:
331: LOCAL VOID gsort(from,to)
332: STRING from[], to[];
333: {
334: INT k, m, n;
335: REG INT i, j;
336:
337: IF (n=to-from)<=1 THEN return FI
338:
339: FOR j=1; j<=n; j*=2 DONE
340:
341: FOR m=2*j-1; m/=2;
342: DO k=n-m;
343: FOR j=0; j<k; j++
344: DO FOR i=j; i>=0; i-=m
345: DO REG STRING *fromi; fromi = &from[i];
346: IF cf(fromi[m],fromi[0])>0
347: THEN break;
348: ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s;
349: FI
350: OD
351: OD
352: OD
353: }
354:
355: /* Argument list generation */
356:
357: INT getarg(ac)
358: COMPTR ac;
359: {
360: REG ARGPTR argp;
361: REG INT count=0;
362: REG COMPTR c;
363:
364: IF c=ac
365: THEN argp=c->comarg;
366: WHILE argp
367: DO count += split(macro(argp->argval));
368: argp=argp->argnxt;
369: OD
370: FI
371: return(count);
372: }
373:
374: LOCAL INT split(s)
375: REG STRING s;
376: {
377: REG STRING argp;
378: REG INT c;
379: INT count=0;
380:
381: LOOP sigchk(); argp=locstak()+BYTESPERWORD;
382: WHILE (c = *s++, !any(c,ifsnod.namval) && c)
383: DO *argp++ = c OD
384: IF argp==staktop+BYTESPERWORD
385: THEN IF c
386: THEN continue;
387: ELSE return(count);
388: FI
389: ELIF c==0
390: THEN s--;
391: FI
392: IF c=expand((argp=endstak(argp))->argval,0)
393: THEN count += c;
394: ELSE /* assign(&fngnod, argp->argval); */
395: makearg(argp); count++;
396: FI
397: Lcheat(gchain) |= ARGMK;
398: POOL
399: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.