# 2.11BSD#431 - /usr/src/bin/sh/service.c

##### Functions

    await             X
    catpath           X
    execa             X
    execs             X
    getarg            X
    getpath           X
    gocsh             X
    gsort             X
    initio            X
    mactrim           X
    pathopen          X
    post              X
    postclr           X
    scan              X
    split             X
    trim              X

##### Macros

    ARGMK             X
    E2BIG             X
    ENOENT            X
    ENOEXEC           X
    ENOMEM            X
    ETXTBSY           X
    MAXP              X

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

#### Defined functions

await defined in line 228; used 4 times

- in /usr/src/bin/sh/defs.h line 100
- in /usr/src/bin/sh/macro.c line 202
- in /usr/src/bin/sh/xec.c line 162, 255

catpath defined in line 98; used 3 times

- in line 93, 138
- in /usr/src/bin/sh/defs.h line 94

execa defined in line 117; used 2 times

- in /usr/src/bin/sh/xec.c line 143, 299

execs defined in line 132; used 2 times

- in line 127
- in /usr/src/bin/sh/defs.h line 99

getarg defined in line 360; used 2 times

- in /usr/src/bin/sh/xec.c line 53, 347

getpath defined in line 73; used 3 times

- in line 124
- in /usr/src/bin/sh/defs.h line 95
- in /usr/src/bin/sh/xec.c line 76

gocsh defined in line 184; used 1 times

- in line 159

gsort defined in line 334; used 2 times

- in line 17, 325

initio defined in line 36; used 3 times

- in line 69
- in /usr/src/bin/sh/xec.c line 138, 294

mactrim defined in line 303; used 5 times

- in line 44
- in /usr/src/bin/sh/defs.h line 97
- in /usr/src/bin/sh/io.c line 121
- in /usr/src/bin/sh/name.c line 57
- in /usr/src/bin/sh/xec.c line 386

pathopen defined in line 88; used 2 times

- in /usr/src/bin/sh/main.c line 80
- in /usr/src/bin/sh/xec.c line 76

post defined in line 213; used 3 times

- in line 235
- in /usr/src/bin/sh/defs.h line 101
- in /usr/src/bin/sh/xec.c line 257

postclr defined in line 204; used 1 times

- in /usr/src/bin/sh/xec.c line 267

scan defined in line 311; used 3 times

- in /usr/src/bin/sh/defs.h line 96
- in /usr/src/bin/sh/xec.c line 54, 347

split defined in line 377; used 1 times

- in line 370

trim defined in line 289; used 6 times

- in line 139, 307, 322
- in /usr/src/bin/sh/macro.c line 185
- in /usr/src/bin/sh/xec.c line 347, 392

#### Defined variables

sccsid defined in line 2; never used

#### Defined macros

ARGMK defined in line 19; used 4 times

- in line 314, 324-329(2), 400

E2BIG defined in line 28; never used
ENOENT defined in line 29; never used
ENOEXEC defined in line 27; never used
ENOMEM defined in line 26; never used
ETXTBSY defined in line 30; never used
MAXP defined in line 200; used 2 times

- in line 201, 220

Last modified: 1994-12-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1669 |