BSD 4_1c_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 9 Feb 1983 07:29:32 +0000 (23:29 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 9 Feb 1983 07:29:32 +0000 (23:29 -0800)
Work on file usr/src/bin/sh/Makefile
Work on file usr/src/bin/sh/macro.c
Work on file usr/src/bin/sh/xec.c

Synthesized-from: CSRG/cd1/4.1c.2

usr/src/bin/sh/Makefile [new file with mode: 0644]
usr/src/bin/sh/macro.c [new file with mode: 0644]
usr/src/bin/sh/xec.c [new file with mode: 0644]

diff --git a/usr/src/bin/sh/Makefile b/usr/src/bin/sh/Makefile
new file mode 100644 (file)
index 0000000..cfabc4a
--- /dev/null
@@ -0,0 +1,33 @@
+#      Makefile        4.4     83/02/09
+#
+CFLAGS = -O -w
+
+all:   sh
+
+cp:    sh
+       cp sh /bin/sh
+       rm sh *.o
+
+cmp:   sh
+       cmp sh /bin/sh
+       rm sh *.o
+
+sh:    setbrk.o
+sh:    builtin.o blok.o stak.o
+sh:    cmd.o fault.o main.o
+sh:    word.o string.o name.o args.o
+sh:    xec.o service.o error.o io.o
+sh:    print.o macro.o expand.o
+sh:    ctype.o msg.o
+blok.o:                brkincr.h
+fault.o:       brkincr.h
+main.o:                brkincr.h
+stak.o:                brkincr.h
+
+sh:
+       cc -o sh -n *.o
+
+install:
+       install -s sh $(DESTDIR)/bin
+clean:
+       rm -f sh *.o
diff --git a/usr/src/bin/sh/macro.c b/usr/src/bin/sh/macro.c
new file mode 100644 (file)
index 0000000..905ae24
--- /dev/null
@@ -0,0 +1,235 @@
+/*     macro.c 4.2     83/02/09        */
+
+#
+/*
+ * UNIX shell
+ *
+ * S. R. Bourne
+ * Bell Telephone Laboratories
+ *
+ */
+
+#include       "defs.h"
+#include       "sym.h"
+
+LOCAL CHAR     quote;  /* used locally */
+LOCAL CHAR     quoted; /* used locally */
+
+
+
+LOCAL STRING   copyto(endch)
+       REG CHAR        endch;
+{
+       REG CHAR        c;
+
+       WHILE (c=getch(endch))!=endch ANDF c
+       DO pushstak(c|quote) OD
+       zerostak();
+       IF c!=endch THEN error(badsub) FI
+}
+
+LOCAL  skipto(endch)
+       REG CHAR        endch;
+{
+       /* skip chars up to } */
+       REG CHAR        c;
+       WHILE (c=readc()) ANDF c!=endch
+       DO      SWITCH c IN
+
+               case SQUOTE:    skipto(SQUOTE); break;
+
+               case DQUOTE:    skipto(DQUOTE); break;
+
+               case DOLLAR:    IF readc()==BRACE
+                               THEN    skipto('}');
+                               FI
+               ENDSW
+       OD
+       IF c!=endch THEN error(badsub) FI
+}
+
+LOCAL  getch(endch)
+       CHAR            endch;
+{
+       REG CHAR        d;
+
+retry:
+       d=readc();
+       IF !subchar(d)
+       THEN    return(d);
+       FI
+       IF d==DOLLAR
+       THEN    REG INT c;
+               IF (c=readc(), dolchar(c))
+               THEN    NAMPTR          n=NIL;
+                       INT             dolg=0;
+                       BOOL            bra;
+                       REG STRING      argp, v;
+                       CHAR            idb[2];
+                       STRING          id=idb;
+
+                       IF bra=(c==BRACE) THEN c=readc() FI
+                       IF letter(c)
+                       THEN    argp=relstak();
+                               WHILE alphanum(c) DO pushstak(c); c=readc() OD
+                               zerostak();
+                               n=lookup(absstak(argp)); setstak(argp);
+                               v = n->namval; id = n->namid;
+                               peekc = c|MARK;;
+                       ELIF digchar(c)
+                       THEN    *id=c; idb[1]=0;
+                               IF astchar(c)
+                               THEN    dolg=1; c='1';
+                               FI
+                               c -= '0';
+                               v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (dolg=0));
+                       ELIF c=='$'
+                       THEN    v=pidadr;
+                       ELIF c=='!'
+                       THEN    v=pcsadr;
+                       ELIF c=='#'
+                       THEN    v=dolladr;
+                       ELIF c=='?'
+                       THEN    v=exitadr;
+                       ELIF c=='-'
+                       THEN    v=flagadr;
+                       ELIF bra THEN error(badsub);
+                       ELSE    goto retry;
+                       FI
+                       c = readc();
+                       IF !defchar(c) ANDF bra
+                       THEN    error(badsub);
+                       FI
+                       argp=0;
+                       IF bra
+                       THEN    IF c!='}'
+                               THEN    argp=relstak();
+                                       IF (v==0)NEQ(setchar(c))
+                                       THEN    copyto('}');
+                                       ELSE    skipto('}');
+                                       FI
+                                       argp=absstak(argp);
+                               FI
+                       ELSE    peekc = c|MARK; c = 0;
+                       FI
+                       IF v
+                       THEN    IF c!='+'
+                               THEN    LOOP WHILE c = *v++
+                                            DO pushstak(c|quote); OD
+                                            IF dolg==0 ORF (++dolg>dolc)
+                                            THEN break;
+                                            ELSE v=dolv[dolg]; pushstak(SP|(*id=='*' ? quote : 0));
+                                            FI
+                                       POOL
+                               FI
+                       ELIF argp
+                       THEN    IF c=='?'
+                               THEN    failed(id,*argp?argp:badparam);
+                               ELIF c=='='
+                               THEN    IF n
+                                       THEN    assign(n,argp);
+                                       ELSE    error(badsub);
+                                       FI
+                               FI
+                       ELIF flags&setflg
+                       THEN    failed(id,badparam);
+                       FI
+                       goto retry;
+               ELSE    peekc=c|MARK;
+               FI
+       ELIF d==endch
+       THEN    return(d);
+       ELIF d==SQUOTE
+       THEN    comsubst(); goto retry;
+       ELIF d==DQUOTE
+       THEN    quoted++; quote^=QUOTE; goto retry;
+       FI
+       return(d);
+}
+
+STRING macro(as)
+       STRING          as;
+{
+       /* Strip "" and do $ substitution
+        * Leaves result on top of stack
+        */
+       REG BOOL        savqu =quoted;
+       REG CHAR        savq = quote;
+       FILEHDR         fb;
+
+       push(&fb); estabf(as);
+       usestak();
+       quote=0; quoted=0;
+       copyto(0);
+       pop();
+       IF quoted ANDF (stakbot==staktop) THEN pushstak(QUOTE) FI
+       quote=savq; quoted=savqu;
+       return(fixstak());
+}
+
+LOCAL  comsubst()
+{
+       /* command substn */
+       FILEBLK         cb;
+       REG CHAR        d;
+       REG STKPTR      savptr = fixstak();
+
+       usestak();
+       WHILE (d=readc())!=SQUOTE ANDF d
+       DO pushstak(d) OD
+
+       BEGIN
+          REG STRING   argc;
+          trim(argc=fixstak());
+          push(&cb); estabf(argc);
+       END
+       BEGIN
+          REG TREPTR   t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG));
+          INT          pv[2];
+
+          /* this is done like this so that the pipe
+           * is open only when needed
+           */
+          chkpipe(pv);
+          initf(pv[INPIPE]);
+          execute(t, 0, 0, pv);
+          close(pv[OTPIPE]);
+       END
+       tdystak(savptr); staktop=movstr(savptr,stakbot);
+       WHILE d=readc() DO locstak(); pushstak(d|quote) OD
+       await(0);
+       WHILE stakbot!=staktop
+       DO      IF (*--staktop&STRIP)!=NL
+               THEN    ++staktop; break;
+               FI
+       OD
+       pop();
+}
+
+#define CPYSIZ 512
+
+subst(in,ot)
+       INT             in, ot;
+{
+       REG CHAR        c;
+       FILEBLK         fb;
+       REG INT         count=CPYSIZ;
+
+       push(&fb); initf(in);
+       /* DQUOTE used to stop it from quoting */
+       WHILE c=(getch(DQUOTE)&STRIP)
+       DO pushstak(c);
+          IF --count == 0
+          THEN flush(ot); count=CPYSIZ;
+          FI
+       OD
+       flush(ot);
+       pop();
+}
+
+LOCAL  flush(ot)
+{
+       write(ot,stakbot,staktop-stakbot);
+       IF flags&execpr THEN write(output,stakbot,staktop-stakbot) FI
+       staktop=stakbot;
+}
diff --git a/usr/src/bin/sh/xec.c b/usr/src/bin/sh/xec.c
new file mode 100644 (file)
index 0000000..c092a13
--- /dev/null
@@ -0,0 +1,423 @@
+/*     xec.c   4.2     83/02/09        */
+
+#
+/*
+ * UNIX shell
+ *
+ * S. R. Bourne
+ * Bell Telephone Laboratories
+ *
+ */
+
+#include       "defs.h"
+#include       "sym.h"
+
+LOCAL INT      parent;
+
+SYSTAB         commands;
+
+
+
+/* ========    command execution       ========*/
+
+
+execute(argt, execflg, pf1, pf2)
+       TREPTR          argt;
+       INT             *pf1, *pf2;
+{
+       /* `stakbot' is preserved by this routine */
+       REG TREPTR      t;
+       STKPTR          sav=savstak();
+
+       sigchk();
+
+       IF (t=argt) ANDF execbrk==0
+       THEN    REG INT         treeflgs;
+               INT             oldexit, type;
+               REG STRING      *com;
+
+               treeflgs = t->tretyp; type = treeflgs&COMMSK;
+               oldexit=exitval; exitval=0;
+
+               SWITCH type IN
+
+               case TCOM:
+                       BEGIN
+                       STRING          a1;
+                       INT             argn, internal;
+                       ARGPTR          schain=gchain;
+                       IOPTR           io=t->treio;
+                       gchain=0;
+                       argn = getarg(t);
+                       com=scan(argn);
+                       a1=com[1]; gchain=schain;
+
+                       IF argn==0 ORF (internal=syslook(com[0],commands))
+                       THEN    setlist(t->comset, 0);
+                       FI
+
+                       IF argn ANDF (flags&noexec)==0
+                       THEN    /* print command if execpr */
+                               IF flags&execpr
+                               THEN    argn=0; prs(execpmsg);
+                                       WHILE com[argn]!=ENDARGS
+                                       DO prs(com[argn++]); blank() OD
+                                       newline();
+                               FI
+
+                               SWITCH internal IN
+
+                               case SYSDOT:
+                                       IF a1
+                                       THEN    REG INT         f;
+       
+                                               IF (f=pathopen(getpath(a1), a1)) < 0
+                                               THEN failed(a1,notfound);
+                                               ELSE execexp(0,f);
+                                               FI
+                                       FI
+                                       break;
+       
+                               case SYSTIMES:
+                                       {
+                                       L_INT   t[4]; times(t);
+                                       prt(t[2]); blank(); prt(t[3]); newline();
+                                       }
+                                       break;
+       
+                               case SYSEXIT:
+                                       exitsh(a1?stoi(a1):oldexit);
+       
+                               case SYSNULL:
+                                       io=0;
+                                       break;
+       
+                               case SYSCONT:
+                                       execbrk = -loopcnt; break;
+       
+                               case SYSBREAK:
+                                       IF (execbrk=loopcnt) ANDF a1
+                                       THEN breakcnt=stoi(a1);
+                                       FI
+                                       break;
+       
+                               case SYSTRAP:
+                                       IF a1
+                                       THEN    BOOL    clear;
+                                               IF (clear=digit(*a1))==0
+                                               THEN    ++com;
+                                               FI
+                                               WHILE *++com
+                                               DO INT  i;
+                                                  IF (i=stoi(*com))>=MAXTRAP ORF i<MINTRAP
+                                                  THEN failed(*com,badtrap);
+                                                  ELIF clear
+                                                  THEN clrsig(i);
+                                                  ELSE replace(&trapcom[i],a1);
+                                                       IF *a1
+                                                       THEN    getsig(i);
+                                                       ELSE    ignsig(i);
+                                                       FI
+                                                  FI
+                                               OD
+                                       ELSE    /* print out current traps */
+                                               INT             i;
+       
+                                               FOR i=0; i<MAXTRAP; i++
+                                               DO IF trapcom[i]
+                                                  THEN prn(i); prs(colon); prs(trapcom[i]); newline();
+                                                  FI
+                                               OD
+                                       FI
+                                       break;
+       
+                               case SYSEXEC:
+                                       com++;
+                                       initio(io); ioset=0; io=0;
+                                       IF a1==0 THEN break FI
+       
+                               case SYSLOGIN:
+                                       flags |= forked;
+                                       oldsigs(); execa(com); done();
+       
+                               case SYSCD:
+                                       IF flags&rshflg
+                                       THEN    failed(com[0],restricted);
+                                       ELIF (a1==0 ANDF (a1=homenod.namval)==0) ORF chdir(a1)<0
+                                       THEN    failed(a1,baddir);
+                                       FI
+                                       break;
+       
+                               case SYSSHFT:
+                                       IF dolc<1
+                                       THEN    error(badshift);
+                                       ELSE    dolv++; dolc--;
+                                       FI
+                                       assnum(&dolladr, dolc);
+                                       break;
+       
+                               case SYSWAIT:
+                                       await(-1);
+                                       break;
+       
+                               case SYSREAD:
+                                       exitval=readvar(&com[1]);
+                                       break;
+
+/*
+                               case SYSTST:
+                                       exitval=testcmd(com);
+                                       break;
+*/
+
+                               case SYSSET:
+                                       IF a1
+                                       THEN    INT     argc;
+                                               argc = options(argn,com);
+                                               IF argc>1
+                                               THEN    setargs(com+argn-argc);
+                                               FI
+                                       ELIF t->comset==0
+                                       THEN    /*scan name chain and print*/
+                                               namscan(printnam);
+                                       FI
+                                       break;
+       
+                               case SYSRDONLY:
+                                       exitval=N_RDONLY;
+                               case SYSXPORT:
+                                       IF exitval==0 THEN exitval=N_EXPORT; FI
+       
+                                       IF a1
+                                       THEN    WHILE *++com
+                                               DO attrib(lookup(*com), exitval) OD
+                                       ELSE    namscan(printflg);
+                                       FI
+                                       exitval=0;
+                                       break;
+       
+                               case SYSEVAL:
+                                       IF a1
+                                       THEN    execexp(a1,&com[2]);
+                                       FI
+                                       break;
+
+                                case SYSUMASK:
+                                        if (a1) {
+                                                int c, i
+                                                i = 0;
+                                                while ((c = *a1++) >= '0' &&
+                                                        c <= '7')
+                                                        i = (i << 3) + c - '0';
+                                                umask(i);
+                                        } else {
+                                                int i, j;
+                                                umask(i = umask(0));
+                                                prc('0');
+                                                for (j = 6; j >= 0; j -= 3)
+                                                        prc(((i>>j)&07) + '0');
+                                                newline();
+                                        }
+                                        break;
+       
+                               default:
+                                       internal=builtin(argn,com);
+       
+                               ENDSW
+
+                               IF internal
+                               THEN    IF io THEN error(illegal) FI
+                                       chktrap();
+                                       break;
+                               FI
+                       ELIF t->treio==0
+                       THEN    break;
+                       FI
+                       END
+       
+               case TFORK:
+                       IF execflg ANDF (treeflgs&(FAMP|FPOU))==0
+                       THEN    parent=0;
+                       ELSE    WHILE (parent=fork()) == -1
+                               DO sigchk(); alarm(10); pause() OD
+                       FI
+
+                       IF parent
+                       THEN    /* This is the parent branch of fork;    */
+                               /* it may or may not wait for the child. */
+                               IF treeflgs&FPRS ANDF flags&ttyflg
+                               THEN    prn(parent); newline();
+                               FI
+                               IF treeflgs&FPCL THEN closepipe(pf1) FI
+                               IF (treeflgs&(FAMP|FPOU))==0
+                               THEN    await(parent);
+                               ELIF (treeflgs&FAMP)==0
+                               THEN    post(parent);
+                               ELSE    assnum(&pcsadr, parent);
+                               FI
+
+                               chktrap();
+                               break;
+
+
+                       ELSE    /* this is the forked branch (child) of execute */
+                               flags |= forked; iotemp=0;
+                               postclr();
+                               settmp();
+
+                               /* Turn off INTR and QUIT if `FINT'  */
+                               /* Reset ramaining signals to parent */
+                               /* except for those `lost' by trap   */
+                               oldsigs();
+                               IF treeflgs&FINT
+                               THEN    signal(INTR,1); signal(QUIT,1);
+                               FI
+
+                               /* pipe in or out */
+                               IF treeflgs&FPIN
+                               THEN    rename(pf1[INPIPE],0);
+                                       close(pf1[OTPIPE]);
+                               FI
+                               IF treeflgs&FPOU
+                               THEN    rename(pf2[OTPIPE],1);
+                                       close(pf2[INPIPE]);
+                               FI
+
+                               /* default std input for & */
+                               IF treeflgs&FINT ANDF ioset==0
+                               THEN    rename(chkopen(devnull),0);
+                               FI
+
+                               /* io redirection */
+                               initio(t->treio);
+                               IF type!=TCOM
+                               THEN    execute(t->forktre,1);
+                               ELIF com[0]!=ENDARGS
+                               THEN    setlist(t->comset,N_EXPORT);
+                                       execa(com);
+                               FI
+                               done();
+                       FI
+
+               case TPAR:
+                       rename(dup(2),output);
+                       execute(t->partre,execflg);
+                       done();
+
+               case TFIL:
+                       BEGIN
+                          INT pv[2]; chkpipe(pv);
+                          IF execute(t->lstlef, 0, pf1, pv)==0
+                          THEN execute(t->lstrit, execflg, pv, pf2);
+                          ELSE closepipe(pv);
+                          FI
+                       END
+                       break;
+
+               case TLST:
+                       execute(t->lstlef,0);
+                       execute(t->lstrit,execflg);
+                       break;
+
+               case TAND:
+                       IF execute(t->lstlef,0)==0
+                       THEN    execute(t->lstrit,execflg);
+                       FI
+                       break;
+
+               case TORF:
+                       IF execute(t->lstlef,0)!=0
+                       THEN    execute(t->lstrit,execflg);
+                       FI
+                       break;
+
+               case TFOR:
+                       BEGIN
+                          NAMPTR       n = lookup(t->fornam);
+                          STRING       *args;
+                          DOLPTR       argsav=0;
+
+                          IF t->forlst==0
+                          THEN    args=dolv+1;
+                                  argsav=useargs();
+                          ELSE    ARGPTR       schain=gchain;
+                                  gchain=0;
+                                  trim((args=scan(getarg(t->forlst)))[0]);
+                                  gchain=schain;
+                          FI
+                          loopcnt++;
+                          WHILE *args!=ENDARGS ANDF execbrk==0
+                          DO   assign(n,*args++);
+                               execute(t->fortre,0);
+                               IF execbrk<0 THEN execbrk=0 FI
+                          OD
+                          IF breakcnt THEN breakcnt-- FI
+                          execbrk=breakcnt; loopcnt--;
+                          argfor=freeargs(argsav);
+                       END
+                       break;
+
+               case TWH:
+               case TUN:
+                       BEGIN
+                          INT          i=0;
+
+                          loopcnt++;
+                          WHILE execbrk==0 ANDF (execute(t->whtre,0)==0)==(type==TWH)
+                          DO i=execute(t->dotre,0);
+                             IF execbrk<0 THEN execbrk=0 FI
+                          OD
+                          IF breakcnt THEN breakcnt-- FI
+                          execbrk=breakcnt; loopcnt--; exitval=i;
+                       END
+                       break;
+
+               case TIF:
+                       IF execute(t->iftre,0)==0
+                       THEN    execute(t->thtre,execflg);
+                       ELSE    execute(t->eltre,execflg);
+                       FI
+                       break;
+
+               case TSW:
+                       BEGIN
+                          REG STRING   r = mactrim(t->swarg);
+                          t=t->swlst;
+                          WHILE t
+                          DO   ARGPTR          rex=t->regptr;
+                               WHILE rex
+                               DO      REG STRING      s;
+                                       IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
+                                       THEN    execute(t->regcom,0);
+                                               t=0; break;
+                                       ELSE    rex=rex->argnxt;
+                                       FI
+                               OD
+                               IF t THEN t=t->regnxt FI
+                          OD
+                       END
+                       break;
+               ENDSW
+               exitset();
+       FI
+
+       sigchk();
+       tdystak(sav);
+       return(exitval);
+}
+
+
+execexp(s,f)
+       STRING          s;
+       UFD             f;
+{
+       FILEBLK         fb;
+       push(&fb);
+       IF s
+       THEN    estabf(s); fb.feval=f;
+       ELIF f>=0
+       THEN    initf(f);
+       FI
+       execute(cmd(NL, NLFLG|MTFLG),0);
+       pop();
+}