home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume1 / bourne / part3 < prev    next >
Internet Message Format  |  1986-11-30  |  46KB

  1. Date: Fri, 7 Jun 85 14:00:51 edt
  2. From: Arnold Robbins <gatech!arnold>
  3. Subject: Bourne shell history + tilde + job control + more (Part 3 of 9)
  4. Newsgroups: mod.sources
  5.  
  6. This is part 3 of 9.  It contains the second set of code diffs for the BSD
  7. Bourne shell.
  8.  
  9. Arnold Robbins
  10. arnold@gatech.{UUCP, CSNET}
  11. ------------------- tear here --------------------
  12. :::::::: name.c :::::::
  13. *** ../orig.u/name.c    Wed May 15 17:13:45 1985
  14. --- name.c    Tue Jun  4 14:43:24 1985
  15. ***************
  16. *** 16,21
  17.   PROC BOOL    chkid();
  18.   
  19.   
  20.   NAMNOD    ps2nod    = {    NIL,        NIL,        ps2name},
  21.       fngnod    = {    NIL,        NIL,        fngname},
  22.       pathnod = {    NIL,        NIL,        pathname},
  23.  
  24. --- 16,25 -----
  25.   PROC BOOL    chkid();
  26.   
  27.   
  28. + #if pyr
  29. + NAMNOD    ps2nod    = {    NIL,        &univnod,    ps2name},
  30. +     univnod = {    NIL,        NIL,        univname},
  31. + #else
  32.   NAMNOD    ps2nod    = {    NIL,        NIL,        ps2name},
  33.   #endif
  34.       fngnod    = {    NIL,        NIL,        fngname},
  35. ***************
  36. *** 17,22
  37.   
  38.   
  39.   NAMNOD    ps2nod    = {    NIL,        NIL,        ps2name},
  40.       fngnod    = {    NIL,        NIL,        fngname},
  41.       pathnod = {    NIL,        NIL,        pathname},
  42.       ifsnod    = {    NIL,        NIL,        ifsname},
  43.  
  44. --- 21,27 -----
  45.       univnod = {    NIL,        NIL,        univname},
  46.   #else
  47.   NAMNOD    ps2nod    = {    NIL,        NIL,        ps2name},
  48. + #endif
  49.       fngnod    = {    NIL,        NIL,        fngname},
  50.       pathnod = {    NIL,        NIL,        pathname},
  51.       ifsnod    = {    NIL,        NIL,        ifsname},
  52. ***************
  53. *** 21,28
  54.       pathnod = {    NIL,        NIL,        pathname},
  55.       ifsnod    = {    NIL,        NIL,        ifsname},
  56.       ps1nod    = {    &pathnod,    &ps2nod,    ps1name},
  57. !     homenod = {    &fngnod,    &ifsnod,    homename},
  58. !     mailnod = {    &homenod,    &ps1nod,    mailname};
  59.   
  60.   NAMPTR        namep = &mailnod;
  61.   
  62.  
  63. --- 26,34 -----
  64.       pathnod = {    NIL,        NIL,        pathname},
  65.       ifsnod    = {    NIL,        NIL,        ifsname},
  66.       ps1nod    = {    &pathnod,    &ps2nod,    ps1name},
  67. !     homenod = {    &histfnod,    &ifsnod,    homename},
  68. !     mailnod = {    &homenod,    &ps1nod,    mailname},
  69. !     histfnod = {    &fngnod,    NIL,        histfilename};
  70.   
  71.   NAMPTR        namep = &mailnod;
  72.   
  73. ***************
  74. *** 38,43
  75.       REG SYSPTR    syscan;
  76.   
  77.       syscan=syswds; first = *w;
  78.   
  79.       WHILE s=syscan->sysnam
  80.       DO  IF first == *s
  81.  
  82. --- 44,50 -----
  83.       REG SYSPTR    syscan;
  84.   
  85.       syscan=syswds; first = *w;
  86. +     IF *w == 0 THEN return (0) FI
  87.   
  88.       WHILE s=syscan->sysnam
  89.       DO  IF first == *s
  90. ***************
  91. *** 129,135
  92.       THEN    f->fsiz=1;
  93.       FI
  94.   
  95. !     LOOP    c=nextc(0);
  96.           IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c)
  97.           THEN    zerostak();
  98.               assign(n,absstak(rel)); setstak(rel);
  99.  
  100. --- 136,145 -----
  101.       THEN    f->fsiz=1;
  102.       FI
  103.   
  104. !     /*    strip any leading IFS characters    */
  105. !     WHILE    (any((c=nextc(0)), ifsnod.namval)) ANDF !(eolchar(c)) DONE
  106. !     LOOP
  107.           IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c)
  108.           THEN    zerostak();
  109.               assign(n,absstak(rel)); setstak(rel);
  110. ***************
  111. *** 139,144
  112.               FI
  113.               IF eolchar(c)
  114.               THEN    break;
  115.               FI
  116.           ELSE    pushstak(c);
  117.           FI
  118.  
  119. --- 149,157 -----
  120.               FI
  121.               IF eolchar(c)
  122.               THEN    break;
  123. +             ELSE    /* strip imbedded IFS characters */
  124. +                 WHILE (any((c=nextc(0)), ifsnod.namval)) ANDF
  125. +                     !(eolchar(c)) DONE
  126.               FI
  127.           ELSE    pushstak(c);
  128.               c = nextc(0);
  129. ***************
  130. *** 141,146
  131.               THEN    break;
  132.               FI
  133.           ELSE    pushstak(c);
  134.           FI
  135.       POOL
  136.       WHILE n
  137.  
  138. --- 154,166 -----
  139.                       !(eolchar(c)) DONE
  140.               FI
  141.           ELSE    pushstak(c);
  142. +             c = nextc(0);
  143. +             IF eolchar(c)
  144. +             THEN
  145. +                 STKPTR top = staktop;
  146. +                 WHILE any (*(--top), ifsnod.namval) DONE
  147. +                 staktop = top + 1;
  148. +             FI
  149.           FI
  150.       POOL
  151.       WHILE n
  152. :::::::: name.h :::::::
  153. No differences encountered
  154. :::::::: print.c :::::::
  155. *** ../orig.u/print.c    Wed May 15 17:13:45 1985
  156. --- print.c    Mon Jun  3 11:05:42 1985
  157. ***************
  158. *** 15,20
  159.   
  160.   CHAR        numbuf[6];
  161.   
  162.   
  163.   /* printing and io conversion */
  164.   
  165.  
  166. --- 15,27 -----
  167.   
  168.   CHAR        numbuf[6];
  169.   
  170. + #ifndef TAB
  171. + /* emulate buffered i/o in later versions of the shell (sigh) */
  172. + prc_buff(c)
  173. + char c;
  174. + {
  175. +     prc(c);
  176. + }
  177.   
  178.   prs_buff (s)
  179.   char *s;
  180. ***************
  181. *** 16,21
  182.   CHAR        numbuf[6];
  183.   
  184.   
  185.   /* printing and io conversion */
  186.   
  187.   newline()
  188.  
  189. --- 23,45 -----
  190.       prc(c);
  191.   }
  192.   
  193. + prs_buff (s)
  194. + char *s;
  195. + {
  196. +     prs (s);
  197. + }
  198. + prn_buff (n)
  199. + int n;
  200. + {
  201. +     prn (n);
  202. + }
  203. + flushb ()
  204. + {
  205. + }
  206. + #endif
  207.   /* printing and io conversion */
  208.   
  209.   newline()
  210. ***************
  211. *** 99,101
  212.       FI
  213.   }
  214.   
  215.  
  216. --- 123,229 -----
  217.       FI
  218.   }
  219.   
  220. + void
  221. + pr_prompt (str)
  222. + register char *str;
  223. + {
  224. +     for (; *str; str++)
  225. +     {
  226. +         if (*str != '%')
  227. +             prc_buff (*str);
  228. + #ifdef notdef
  229. +         /* BSD does not have pwd built in, sorry */
  230. +         else if (*(str+1) == 'd')
  231. +         {
  232. +             /* current directory */
  233. +             str++;
  234. +             prs_buff (retcwd());
  235. +         }
  236. + #endif
  237. +         else if (*(str+1) == 'e')
  238. +         {
  239. +             /* event count */
  240. +             str++;
  241. +             if ((flags & nohistflg) == 0)
  242. +                 prn_buff (event_count);
  243. +         }
  244. +         else if (*(str+1) == 'h')
  245. +         {
  246. +             /* hostname */
  247. +             static char *cp = 0;
  248. +             static int didhost = FALSE;
  249. +             static int didgt = FALSE;
  250. +             static char buf[257];
  251. +             if (! didhost)
  252. +             {
  253. +                 gethostname (buf, sizeof buf);
  254. +                 didhost = TRUE;
  255. +                 cp = buf;
  256. +             }
  257. + #ifdef GATECH
  258. +             /*
  259. +              * this is to get rid of the dumb gt- convention.
  260. +              * a gt w/out the - is also removed.
  261. +              */
  262. +             if (! didgt)
  263. +             {
  264. +                 didgt = TRUE;
  265. +                 if (cp[0] == 'g' && cp[1] == 't' && cp[2])
  266. +                 {
  267. +                     cp += 2;
  268. +                     if (cp[0] == '-' && cp[1])
  269. +                         cp++;
  270. +                 }
  271. +             }
  272. + #endif
  273. +             prs_buff (cp);
  274. +             str++;
  275. +         }
  276. +         else if (*(str+1) == 'l')
  277. +         {
  278. +             /* login name */
  279. +             static char *cp = 0;
  280. +             static int didname = FALSE;
  281. +             str++;
  282. +             if (! didname)
  283. +             {
  284. +                 cp = username ();
  285. +                 didname = TRUE;
  286. +             }
  287. +             if (cp)
  288. +                 prs_buff (cp);
  289. +         }
  290. +         else if (*(str+1) == 't')
  291. +         {
  292. +             /* current time, HH:MM */
  293. +             long l;
  294. +             char *cp, *ctime ();
  295. +             str++;
  296. +             time (& l);
  297. +             cp = ctime (& l);
  298. +             cp[16] = '\0';
  299. +             cp += 11;
  300. +             prs_buff (cp);
  301. +         }
  302. + #if pyr
  303. +         else if (*(str+1) == 'u')
  304. +         {
  305. +             /* current univeserse */
  306. +             str++;
  307. +             prs_buff (univ_name[cur_univ-1]);
  308. +         }
  309. + #endif
  310. +         else if (*(str+1) == '\0')    /* % was last char in string */
  311. +         {
  312. +             prc_buff (*str);
  313. +             continue;
  314. +         }
  315. +         else
  316. +             prc_buff (*(++str));
  317. +     }
  318. +     flushb();
  319. + }
  320. :::::::: service.c :::::::
  321. *** ../orig.u/service.c    Wed May 15 17:13:46 1985
  322. --- service.c    Tue Jun  4 15:06:44 1985
  323. ***************
  324. *** 12,17
  325.    */
  326.   
  327.   #include    "defs.h"
  328.   
  329.   
  330.   PROC VOID    gsort();
  331.  
  332. --- 12,20 -----
  333.    */
  334.   
  335.   #include    "defs.h"
  336. + #if JOBS
  337. + #include    <sys/wait.h>
  338. + #endif
  339.   
  340.   
  341.   PROC VOID    gsort();
  342. ***************
  343. *** 43,50
  344.           ion=mactrim(iop->ioname);
  345.           IF *ion ANDF (flags&noexec)==0
  346.           THEN    IF iof&IODOC
  347. !             THEN    subst(chkopen(ion),(fd=tmpfil()));
  348. !                 close(fd); fd=chkopen(tmpout); unlink(tmpout);
  349.               ELIF iof&IOMOV
  350.               THEN    IF eq(minus,ion)
  351.                   THEN    fd = -1;
  352.  
  353. --- 46,57 -----
  354.           ion=mactrim(iop->ioname);
  355.           IF *ion ANDF (flags&noexec)==0
  356.           THEN    IF iof&IODOC
  357. !             THEN    TEMPBLK    tb;
  358. !                 subst(chkopen(ion),(fd=tmpfil(&tb)));
  359. !                 poptemp();    /* pushed in tmpfil --
  360. !                            bug fix for problems with
  361. !                            in-line scripts */
  362. !                 fd=chkopen(tmpout); unlink(tmpout);
  363.               ELIF iof&IOMOV
  364.               THEN    IF eq(minus,ion)
  365.                   THEN    fd = -1;
  366. ***************
  367. *** 53,58
  368.                   THEN    failed(ion,badfile);
  369.                   ELSE    fd=dup(fd);
  370.                   FI
  371.               ELIF (iof&IOPUT)==0
  372.               THEN    fd=chkopen(ion);
  373.               ELIF flags&rshflg
  374.  
  375. --- 60,69 -----
  376.                   THEN    failed(ion,badfile);
  377.                   ELSE    fd=dup(fd);
  378.                   FI
  379. +             ELIF iof&IORDW
  380. +             THEN    IF (fd=open(ion, 2)) < 0
  381. +                 THEN    failed(ion, badopen);
  382. +                 FI
  383.               ELIF (iof&IOPUT)==0
  384.               THEN    fd=chkopen(ion);
  385.               ELIF flags&rshflg
  386. ***************
  387. *** 69,74
  388.       FI
  389.   }
  390.   
  391.   STRING    getpath(s)
  392.       STRING        s;
  393.   {
  394.  
  395. --- 80,96 -----
  396.       FI
  397.   }
  398.   
  399. + STRING    simple (s)
  400. +     REG STRING s;
  401. + {
  402. +     STRING save = s;
  403. +     FOR ; *s; s++
  404. +     DO    IF *s == '/' THEN save = s; FI
  405. +     OD
  406. +     return (*save == '/' ? ++save : save);
  407. + }
  408.   STRING    getpath(s)
  409.       STRING        s;
  410.   {
  411. ***************
  412. *** 73,79
  413.       STRING        s;
  414.   {
  415.       REG STRING    path;
  416. !     IF any('/',s)
  417.       THEN    IF flags&rshflg
  418.           THEN    failed(s, restricted);
  419.           ELSE    return(nullstr);
  420.  
  421. --- 95,101 -----
  422.       STRING        s;
  423.   {
  424.       REG STRING    path;
  425. !     IF any('/',s) ORF any(('/'|QUOTE), s)
  426.       THEN    IF flags&rshflg
  427.           THEN    failed(s, restricted);
  428.           ELSE    return(nullstr);
  429. ***************
  430. *** 101,106
  431.       /* leaves result on top of stack */
  432.       REG STRING    scanp = path,
  433.               argp = locstak();
  434.   
  435.       WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD
  436.       IF scanp!=path THEN *argp++='/' FI
  437.  
  438. --- 123,129 -----
  439.       /* leaves result on top of stack */
  440.       REG STRING    scanp = path,
  441.               argp = locstak();
  442. +     STRING    save = argp, cp;
  443.   
  444.       WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD
  445.       *argp = '\0';
  446. ***************
  447. *** 103,108
  448.               argp = locstak();
  449.   
  450.       WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD
  451.       IF scanp!=path THEN *argp++='/' FI
  452.       IF *scanp==COLON THEN scanp++ FI
  453.       path=(*scanp ? scanp : 0); scanp=name;
  454.  
  455. --- 126,137 -----
  456.       STRING    save = argp, cp;
  457.   
  458.       WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD
  459. +     *argp = '\0';
  460. +     /* try a tilde expansion */
  461. +     IF *save == SQUIGGLE ANDF (cp = homedir(save+1)) != nullstr
  462. +     THEN    movstr(cp, save);
  463. +         argp = save + length (save) - 1;
  464. +     FI
  465.       IF scanp!=path THEN *argp++='/' FI
  466.       IF *scanp==COLON THEN scanp++ FI
  467.       path=(*scanp ? scanp : 0); scanp=name;
  468. ***************
  469. *** 149,165
  470.           close(output); output=2;
  471.           input=chkopen(p);
  472.   
  473. -         /* band aid to get csh... 2/26/79 */
  474. -         {
  475. -             char c;
  476. -             if (!isatty(input)) {
  477. -                 read(input, &c, 1);
  478. -                 if (c == '#')
  479. -                     gocsh(t, p, xecenv);
  480. -                 lseek(input, (long) 0, 0);
  481. -             }
  482. -         }
  483.           /* set up new args */
  484.           setargs(t);
  485.           longjmp(subshell,1);
  486.  
  487. --- 178,183 -----
  488.           close(output); output=2;
  489.           input=chkopen(p);
  490.   
  491.           /* set up new args */
  492.           setargs(t);
  493.           longjmp(subshell,1);
  494. ***************
  495. *** 180,200
  496.       ENDSW
  497.   }
  498.   
  499. - gocsh(t, cp, xecenv)
  500. -     register char **t, *cp, **xecenv;
  501. - {
  502. -     char **newt[1000];
  503. -     register char **p;
  504. -     register int i;
  505. -     for (i = 0; t[i]; i++)
  506. -         newt[i+1] = t[i];
  507. -     newt[i+1] = 0;
  508. -     newt[0] = "/bin/csh";
  509. -     newt[1] = cp;
  510. -     execve("/bin/csh", newt, xecenv);
  511. - }
  512.   /* for processes to be waited for */
  513.   #define MAXP 20
  514.   LOCAL INT    pwlist[MAXP];
  515.  
  516. --- 198,203 -----
  517.       ENDSW
  518.   }
  519.   
  520.   /* for processes to be waited for */
  521.   #define MAXP 20
  522.   LOCAL INT    pwlist[MAXP];
  523. ***************
  524. *** 200,205
  525.   LOCAL INT    pwlist[MAXP];
  526.   LOCAL INT    pwc;
  527.   
  528.   postclr()
  529.   {
  530.       REG INT        *pw = pwlist;
  531.  
  532. --- 203,247 -----
  533.   LOCAL INT    pwlist[MAXP];
  534.   LOCAL INT    pwc;
  535.   
  536. + #if JOBS
  537. + LOCAL INT    *wf_pwlist;
  538. + LOCAL INT    wf_pwc;
  539. + VOID set_wfence()
  540. + {
  541. +     wf_pwlist = &pwlist[pwc];
  542. +     wf_pwc = 0;
  543. + }
  544. + BOOL unpost (pcsid)
  545. +     INT pcsid;
  546. + {
  547. +     REG INT *pw = pwlist;
  548. +     IF pcsid
  549. +     THEN    WHILE pw <= &pwlist[pwc]
  550. +         DO    IF pcsid == *pw
  551. +             THEN
  552. +                 IF pw >= wf_pwlist
  553. +                 THEN    wf_pwc--;    /* DAG -- bug fix */
  554. +                 ELSE    wf_pwlist--;
  555. +                 FI
  556. +                 WHILE pw <= &pwlist[pwc]
  557. +                 DO    *pw = pw[1];
  558. +                     pw++;
  559. +                 OD
  560. +                 pw[pwc] = 0;
  561. +                 pwc--;
  562. +                 return TRUE;
  563. +             FI
  564. +             pw++;
  565. +         OD
  566. +         return FALSE;
  567. +     ELSE    return TRUE;
  568. +     FI
  569. + }
  570. + #endif
  571.   postclr()
  572.   {
  573.       REG INT        *pw = pwlist;
  574. ***************
  575. *** 205,211
  576.       REG INT        *pw = pwlist;
  577.   
  578.       WHILE pw <= &pwlist[pwc]
  579. !     DO *pw++ = 0 OD
  580.       pwc=0;
  581.   }
  582.   
  583.  
  584. --- 247,258 -----
  585.       REG INT        *pw = pwlist;
  586.   
  587.       WHILE pw <= &pwlist[pwc]
  588. !     DO
  589. ! #if JOBS
  590. !         j_child_clear(*pw);
  591. ! #endif
  592. !         *pw++ = 0;
  593. !     OD
  594.       pwc=0;
  595.   }
  596.   
  597. ***************
  598. *** 215,221
  599.       REG INT        *pw = pwlist;
  600.   
  601.       IF pcsid
  602. !     THEN    WHILE *pw DO pw++ OD
  603.           IF pwc >= MAXP-1
  604.           THEN    pw--;
  605.           ELSE    pwc++;
  606.  
  607. --- 262,274 -----
  608.       REG INT        *pw = pwlist;
  609.   
  610.       IF pcsid
  611. !     THEN    WHILE *pw
  612. !         DO
  613. ! #if JOBS
  614. !             IF pcsid == *pw THEN return FI
  615. ! #endif
  616. !             pw++;
  617. !         OD
  618.           IF pwc >= MAXP-1
  619.           THEN    pw--;
  620.           ELSE    pwc++;
  621. ***************
  622. *** 219,224
  623.           IF pwc >= MAXP-1
  624.           THEN    pw--;
  625.           ELSE    pwc++;
  626.           FI
  627.           *pw = pcsid;
  628.       FI
  629.  
  630. --- 272,280 -----
  631.           IF pwc >= MAXP-1
  632.           THEN    pw--;
  633.           ELSE    pwc++;
  634. + #if JOBS
  635. +             wf_pwc++;
  636. + #endif
  637.           FI
  638.           *pw = pcsid;
  639.       FI
  640. ***************
  641. *** 224,231
  642.       FI
  643.   }
  644.   
  645. ! VOID    await(i)
  646. !     INT        i;
  647.   {
  648.       INT        rc=0, wx=0;
  649.       INT        w;
  650.  
  651. --- 280,287 -----
  652.       FI
  653.   }
  654.   
  655. ! VOID    await(i, bckg)
  656. !     INT        i, bckg;
  657.   {
  658.   #if JOBS
  659.   #include <sys/time.h>
  660. ***************
  661. *** 227,232
  662.   VOID    await(i)
  663.       INT        i;
  664.   {
  665.       INT        rc=0, wx=0;
  666.       INT        w;
  667.       INT        ipwc = pwc;
  668.  
  669. --- 283,293 -----
  670.   VOID    await(i, bckg)
  671.       INT        i, bckg;
  672.   {
  673. + #if JOBS
  674. + #include <sys/time.h>
  675. + #include <sys/resource.h>
  676. +     struct rusage    ru;
  677. + #endif
  678.       INT        rc=0, wx=0;
  679.       INT        w;
  680.       INT        ipwc = pwc;
  681. ***************
  682. *** 230,235
  683.       INT        rc=0, wx=0;
  684.       INT        w;
  685.       INT        ipwc = pwc;
  686.   
  687.       post(i);
  688.       WHILE pwc
  689.  
  690. --- 291,298 -----
  691.       INT        rc=0, wx=0;
  692.       INT        w;
  693.       INT        ipwc = pwc;
  694. + #if JOBS
  695. +     BOOL        update_only = i == -2;
  696.   
  697.       IF update_only THEN i = -1 FI
  698.       IF (flags&jobflg) == 0 ORF i != -1
  699. ***************
  700. *** 231,236
  701.       INT        w;
  702.       INT        ipwc = pwc;
  703.   
  704.       post(i);
  705.       WHILE pwc
  706.       DO    REG INT        p;
  707.  
  708. --- 294,303 -----
  709.   #if JOBS
  710.       BOOL        update_only = i == -2;
  711.   
  712. +     IF update_only THEN i = -1 FI
  713. +     IF (flags&jobflg) == 0 ORF i != -1
  714. +     THEN
  715. + #endif
  716.       post(i);
  717.   #if JOBS
  718.       FI
  719. ***************
  720. *** 232,237
  721.       INT        ipwc = pwc;
  722.   
  723.       post(i);
  724.       WHILE pwc
  725.       DO    REG INT        p;
  726.           REG INT        sig;
  727.  
  728. --- 299,308 -----
  729.       THEN
  730.   #endif
  731.       post(i);
  732. + #if JOBS
  733. +     FI
  734. + #endif
  735.       WHILE pwc
  736.   #if JOBS
  737.       ORF (flags&jobflg)
  738. ***************
  739. *** 233,238
  740.   
  741.       post(i);
  742.       WHILE pwc
  743.       DO    REG INT        p;
  744.           REG INT        sig;
  745.           INT        w_hi;
  746.  
  747. --- 304,312 -----
  748.   #endif
  749.   
  750.       WHILE pwc
  751. + #if JOBS
  752. +     ORF (flags&jobflg)
  753. + #endif
  754.       DO    REG INT        p;
  755.           REG INT        sig;
  756.           INT        w_hi;
  757. ***************
  758. *** 236,241
  759.       DO    REG INT        p;
  760.           REG INT        sig;
  761.           INT        w_hi;
  762.   
  763.           BEGIN
  764.              REG INT    *pw=pwlist;
  765.  
  766. --- 310,316 -----
  767.       DO    REG INT        p;
  768.           REG INT        sig;
  769.           INT        w_hi;
  770. +         INT    found = 0;
  771.   
  772.           BEGIN
  773.   #ifndef JOBS
  774. ***************
  775. *** 238,243
  776.           INT        w_hi;
  777.   
  778.           BEGIN
  779.              REG INT    *pw=pwlist;
  780.               IF setjmp(INTbuf) == 0
  781.               THEN    trapjmp[INTR] = 1; p=wait(&w);
  782.  
  783. --- 313,319 -----
  784.           INT    found = 0;
  785.   
  786.           BEGIN
  787. + #ifndef JOBS
  788.              REG INT    *pw=pwlist;
  789.   #else
  790.              IF (i == 0) ANDF (flags & jobflg) ANDF wf_pwc == 0
  791. ***************
  792. *** 239,249
  793.   
  794.           BEGIN
  795.              REG INT    *pw=pwlist;
  796. !             IF setjmp(INTbuf) == 0
  797. !             THEN    trapjmp[INTR] = 1; p=wait(&w);
  798. !             ELSE    p = -1;
  799. !             FI
  800. !             trapjmp[INTR] = 0;
  801.              WHILE pw <= &pwlist[ipwc]
  802.              DO IF *pw==p
  803.                 THEN *pw=0; pwc--;
  804.  
  805. --- 315,346 -----
  806.           BEGIN
  807.   #ifndef JOBS
  808.              REG INT    *pw=pwlist;
  809. ! #else
  810. !            IF (i == 0) ANDF (flags & jobflg) ANDF wf_pwc == 0
  811. !            THEN    break;
  812. !            FI
  813. !            IF (pwc == 0 ANDF (flags&jobflg)) ORF update_only
  814. !            THEN    IF (p = wait3(&w, WUNTRACED|WNOHANG, &ru)) == 0
  815. !             THEN    unpost(i);
  816. !                 break;
  817. !             FI
  818. !             IF pwc == 0 ANDF p == -1 THEN break FI
  819. !            ELSE
  820. ! #endif
  821. !             p = wait3(&w, WUNTRACED, &ru);
  822. ! #if JOBS
  823. !            FI
  824. ! #endif
  825. !            IF wasintr THEN
  826. !             wasintr = 0;
  827. !             IF bckg THEN
  828. !                 break;
  829. !             FI
  830. !            FI
  831. ! #if JOBS
  832. !            IF unpost(p) THEN found++ FI
  833. ! #else
  834.              WHILE pw <= &pwlist[ipwc]
  835.              DO IF *pw==p
  836.                 THEN *pw=0; pwc--;
  837. ***************
  838. *** 247,252
  839.              WHILE pw <= &pwlist[ipwc]
  840.              DO IF *pw==p
  841.                 THEN *pw=0; pwc--;
  842.                 ELSE pw++;
  843.                 FI
  844.              OD
  845.  
  846. --- 344,350 -----
  847.              WHILE pw <= &pwlist[ipwc]
  848.              DO IF *pw==p
  849.                 THEN *pw=0; pwc--;
  850. +             found++;
  851.                 ELSE pw++;
  852.                 FI
  853.              OD
  854. ***************
  855. *** 250,255
  856.                 ELSE pw++;
  857.                 FI
  858.              OD
  859.           END
  860.   
  861.           IF p == -1 THEN continue FI
  862.  
  863. --- 348,354 -----
  864.                 ELSE pw++;
  865.                 FI
  866.              OD
  867. + #endif
  868.           END
  869.   
  870.           IF p == -1 THEN
  871. ***************
  872. *** 252,258
  873.              OD
  874.           END
  875.   
  876. !         IF p == -1 THEN continue FI
  877.   
  878.           w_hi = (w>>8)&LOBYTE;
  879.   
  880.  
  881. --- 351,370 -----
  882.   #endif
  883.           END
  884.   
  885. !         IF p == -1 THEN
  886. !             IF bckg THEN
  887. ! #if JOBS
  888. !                 j_child_clear(i);
  889. !                 unpost(i);
  890. ! #else
  891. !                 REG INT *pw=pwlist;
  892. !                 WHILE pw <= &pwlist[ipwc] ANDF i != *pw
  893. !                 DO    pw++; OD
  894. !                 IF i == *pw THEN *pw = 0; pwc-- FI
  895. ! #endif
  896. !             FI
  897. !             continue;
  898. !         FI
  899.   
  900.           w_hi = (w>>8)&LOBYTE;
  901.   
  902. ***************
  903. *** 258,265
  904.   
  905.           IF sig = w&0177
  906.           THEN    IF sig == 0177    /* ptrace! return */
  907. !             THEN    prs("ptrace: ");
  908. !                 sig = w_hi;
  909.               FI
  910.               IF sysmsg[sig]
  911.               THEN    IF i!=p ORF (flags&prompt)==0 THEN prp(); prn(p); blank() FI
  912.  
  913. --- 370,384 -----
  914.   
  915.           IF sig = w&0177
  916.           THEN    IF sig == 0177    /* ptrace! return */
  917. !             THEN    sig = w_hi;
  918. ! #if JOBS
  919. !                 IF (flags&jobflg) ANDF
  920. !                 (sig==STOP ORF sig==TSTP ORF sig==TTOU ORF sig==TTIN)
  921. !                 THEN    j_child_stop(p, sig);
  922. !                     goto j_bypass;
  923. !                 FI
  924. ! #endif
  925. !                 prs("ptrace: ");
  926.               FI
  927.               IF sysmsg[sig]
  928.               THEN    IF i!=p ORF (flags&prompt)==0 THEN prp(); prn(p); blank() FI
  929. ***************
  930. *** 269,275
  931.               newline();
  932.           FI
  933.   
  934. !         IF rc==0
  935.           THEN    rc = (sig ? sig|SIGFLG : w_hi);
  936.           FI
  937.           wx |= w;
  938.  
  939. --- 388,425 -----
  940.               newline();
  941.           FI
  942.   
  943. ! #if JOBS
  944. !         IF flags&infoflg
  945. !         THEN
  946. !             register int    k;
  947. !             long        l;
  948. !             prc('[');
  949. !             l = ru.ru_utime.tv_sec * 1000000L + ru.ru_utime.tv_usec
  950. !               + ru.ru_stime.tv_sec * 1000000L + ru.ru_stime.tv_usec;
  951. !             prn((int)(l / 1000000));    /* integral seconds */
  952. !             k = (int)(l % 1000000L) / 1000;    /* thousandths */
  953. !             prc('.');
  954. !             if (k < 100)
  955. !                 prc('0');
  956. !             if (k < 10)
  957. !                 prc('0');
  958. !             prn(k);
  959. !             blank();
  960. !             prn((int)ru.ru_inblock);
  961. !             blank();
  962. !             prn((int)ru.ru_oublock);
  963. !             blank();
  964. !             prn((int)ru.ru_minflt);
  965. !             blank();
  966. !             prn((int)ru.ru_majflt);
  967. !             prc(']');
  968. !             newline();
  969. !         FI
  970. !         j_child_die(p);
  971. !     j_bypass:
  972. ! #endif
  973. !         IF rc == 0 ANDF found != 0
  974.           THEN    rc = (sig ? sig|SIGFLG : w_hi);
  975.           FI
  976.           wx |= w;
  977. ***************
  978. *** 273,278
  979.           THEN    rc = (sig ? sig|SIGFLG : w_hi);
  980.           FI
  981.           wx |= w;
  982.       OD
  983.   
  984.       IF wx ANDF flags&errflg
  985.  
  986. --- 423,429 -----
  987.           THEN    rc = (sig ? sig|SIGFLG : w_hi);
  988.           FI
  989.           wx |= w;
  990. +         IF p == i THEN break FI
  991.       OD
  992.   
  993.       IF wx ANDF flags&errflg
  994. ***************
  995. *** 278,283
  996.       IF wx ANDF flags&errflg
  997.       THEN    exitsh(rc);
  998.       FI
  999.       exitval=rc; exitset();
  1000.   }
  1001.   
  1002.  
  1003. --- 429,435 -----
  1004.       IF wx ANDF flags&errflg
  1005.       THEN    exitsh(rc);
  1006.       FI
  1007. +     flags |= eflag;
  1008.       exitval=rc; exitset();
  1009.   }
  1010.   
  1011. :::::::: setbrk.c :::::::
  1012. No differences encountered
  1013. :::::::: stak.c :::::::
  1014. No differences encountered
  1015. :::::::: stak.h :::::::
  1016. No differences encountered
  1017. :::::::: string.c :::::::
  1018. No differences encountered
  1019. :::::::: sym.h :::::::
  1020. *** ../orig.u/sym.h    Wed May 15 17:13:46 1985
  1021. --- sym.h    Mon Jun  3 12:51:24 1985
  1022. ***************
  1023. *** 46,48
  1024.   #define DOLLAR    '$'
  1025.   #define ESCAPE    '\\'
  1026.   #define BRACE    '{'
  1027.  
  1028. --- 46,51 -----
  1029.   #define DOLLAR    '$'
  1030.   #define ESCAPE    '\\'
  1031.   #define BRACE    '{'
  1032. + #if JOBS
  1033. + #define PERCENT    '%'
  1034. + #endif
  1035. :::::::: timeout.h :::::::
  1036. No differences encountered
  1037. :::::::: word.c :::::::
  1038. *** ../orig.u/word.c    Wed May 15 17:13:46 1985
  1039. --- word.c    Thu Jun  6 14:38:18 1985
  1040. ***************
  1041. *** 23,28
  1042.       REG CHAR    c, d;
  1043.       REG CHAR    *argp=locstak()+BYTESPERWORD;
  1044.       INT        alpha=1;
  1045.   
  1046.       wdnum=0; wdset=0;
  1047.   
  1048.  
  1049. --- 23,29 -----
  1050.       REG CHAR    c, d;
  1051.       REG CHAR    *argp=locstak()+BYTESPERWORD;
  1052.       INT        alpha=1;
  1053. +     STRING        save;
  1054.   
  1055.       wdnum=0; wdset=0;
  1056.   
  1057. ***************
  1058. *** 26,32
  1059.   
  1060.       wdnum=0; wdset=0;
  1061.   
  1062. !     WHILE (c=nextc(0), space(c)) DONE
  1063.   
  1064.       IF c=='#'
  1065.       THEN    WHILE (c=readc()) ANDF c!=NL DONE
  1066.  
  1067. --- 27,43 -----
  1068.   
  1069.       wdnum=0; wdset=0;
  1070.   
  1071. !     catcheof = TRUE;
  1072. !     WHILE TRUE
  1073. !     DO
  1074. !         WHILE (c=nextc(0), space(c)) DONE
  1075. !         IF c=='#'
  1076. !         THEN    WHILE (c=nextc(0)) !=NL ANDF c != EOF DONE
  1077. !             peekc = c;
  1078. !         ELSE    break;    /* out of comment - white space loop */
  1079. !         FI
  1080. !     OD
  1081. !     save = argp;
  1082.   
  1083.       IF !eofmeta(c)
  1084.       THEN    REP    IF c==LITERAL
  1085. ***************
  1086. *** 28,37
  1087.   
  1088.       WHILE (c=nextc(0), space(c)) DONE
  1089.   
  1090. -     IF c=='#'
  1091. -     THEN    WHILE (c=readc()) ANDF c!=NL DONE
  1092. -     FI
  1093.       IF !eofmeta(c)
  1094.       THEN    REP    IF c==LITERAL
  1095.               THEN    *argp++=(DQUOTE);
  1096.  
  1097. --- 39,44 -----
  1098.       OD
  1099.       save = argp;
  1100.   
  1101.       IF !eofmeta(c)
  1102.       THEN    REP    IF c==LITERAL
  1103.               THEN    *argp++=(DQUOTE);
  1104. ***************
  1105. *** 46,51
  1106.                   THEN    d=c;
  1107.                       WHILE (*argp++=(c=nextc(d))) ANDF c!=d
  1108.                       DO chkpr(c) OD
  1109.                   FI
  1110.               FI
  1111.           PER (c=nextc(0), !eofmeta(c)) DONE
  1112.  
  1113. --- 53,73 -----
  1114.                   THEN    d=c;
  1115.                       WHILE (*argp++=(c=nextc(d))) ANDF c!=d
  1116.                       DO chkpr(c) OD
  1117. +                 ELIF c == SQUIGGLE
  1118. +                 THEN    /* try ~login name */
  1119. +                     STRING name, home;
  1120. +                     name = argp;
  1121. +                     WHILE (c = nextc(0)) != '/' ANDF
  1122. +                         !eofmeta(c)
  1123. +                     DO
  1124. +                         *name++ = c;
  1125. +                     OD
  1126. +                     peekc = c;
  1127. +                     *name = '\0';
  1128. +                     home = homedir(argp);
  1129. +                     IF *home THEN movstr(home, --argp) FI
  1130. +                     argp += length(argp) - 1;
  1131.                   FI
  1132.               FI
  1133.           PER (c=nextc(0), !eofmeta(c)) DONE
  1134. ***************
  1135. *** 64,69
  1136.       ELIF dipchar(c)
  1137.       THEN    IF (d=nextc(0))==c
  1138.           THEN    wdval = c|SYMREP;
  1139.           ELSE    peekc = d|MARK; wdval = c;
  1140.           FI
  1141.       ELSE    IF (wdval=c)==EOF
  1142.  
  1143. --- 86,97 -----
  1144.       ELIF dipchar(c)
  1145.       THEN    IF (d=nextc(0))==c
  1146.           THEN    wdval = c|SYMREP;
  1147. +             IF c == '<'
  1148. +             THEN    IF (d=nextc(0))=='-'
  1149. +                 THEN stripflg++;
  1150. +                 ELSE peekc = d|MARK;
  1151. +                 FI
  1152. +             FI
  1153.           ELSE    peekc = d|MARK; wdval = c;
  1154.           FI
  1155.       ELSE    IF (wdval=c)==EOF
  1156. ***************
  1157. *** 70,76
  1158.           THEN    wdval=EOFSYM;
  1159.           FI
  1160.           IF iopend ANDF eolchar(c)
  1161. !         THEN    copy(iopend); iopend=0;
  1162.           FI
  1163.       FI
  1164.       reserv=FALSE;
  1165.  
  1166. --- 98,109 -----
  1167.           THEN    wdval=EOFSYM;
  1168.           FI
  1169.           IF iopend ANDF eolchar(c)
  1170. !         THEN    INT histon = (flags&nohistflg) == 0;
  1171. !             flags |= nohistflg;    /* no history for here docs */
  1172. !             copy(iopend);
  1173. !             IF histon THEN flags &= ~nohistflg FI    /* restore */
  1174. !             iopend=0;
  1175.           FI
  1176.       FI
  1177.       catcheof = FALSE;
  1178. ***************
  1179. *** 73,78
  1180.           THEN    copy(iopend); iopend=0;
  1181.           FI
  1182.       FI
  1183.       reserv=FALSE;
  1184.       return(wdval);
  1185.   }
  1186.  
  1187. --- 106,112 -----
  1188.               iopend=0;
  1189.           FI
  1190.       FI
  1191. +     catcheof = FALSE;
  1192.       reserv=FALSE;
  1193.       return(wdval);
  1194.   }
  1195. ***************
  1196. *** 94,99
  1197.   
  1198.   readc()
  1199.   {
  1200.       REG CHAR    c;
  1201.       REG INT        len;
  1202.       REG FILE    f;
  1203.  
  1204. --- 128,134 -----
  1205.   
  1206.   readc()
  1207.   {
  1208. +     LOCAL INT    eofcount = 0;    /* to break endless catcheof loop */
  1209.       REG CHAR    c;
  1210.       REG INT        len;
  1211.       REG FILE    f;
  1212. ***************
  1213. *** 116,123
  1214.       ELIF f->feof ORF f->fdes<0
  1215.       THEN    c=EOF; f->feof++;
  1216.       ELIF (len=readb())<=0
  1217. !     THEN    close(f->fdes); f->fdes = -1; c=EOF; f->feof++;
  1218. !     ELSE    f->fend = (f->fnxt = f->fbuf)+len;
  1219.           goto retry;
  1220.       FI
  1221.       return(c);
  1222.  
  1223. --- 151,185 -----
  1224.       ELIF f->feof ORF f->fdes<0
  1225.       THEN    c=EOF; f->feof++;
  1226.       ELIF (len=readb())<=0
  1227. !     THEN
  1228. !         IF catcheof
  1229. ! #if JOBS
  1230. !         ANDF (flags&(ttyflg|prompt|dotflg)) == (ttyflg|prompt)
  1231. !         ANDF ( (flags&noeotflg) ORF j_finish(FALSE) )
  1232. ! #else
  1233. !         ANDF (flags&(ttyflg|prompt|noeotflg|dotflg)) == (ttyflg|prompt|noeotflg)
  1234. ! #endif
  1235. !         ANDF ++eofcount < 10    /* in case terminal is disconnected */
  1236. !         THEN
  1237. ! #if JOBS
  1238. !         IF (flags&(ttyflg|prompt|noeotflg)) == (ttyflg|prompt|noeotflg)
  1239. !         THEN
  1240. ! #endif
  1241. !             prs("use \"exit\"\n");
  1242. ! #if JOBS
  1243. !         /* else "there are stopped jobs" was printed */
  1244. !         FI
  1245. ! #endif
  1246. !         c = NL;
  1247. !         ELSE
  1248. !         close(f->fdes); f->fdes = -1; c=EOF; f->feof++;
  1249. ! #if JOBS
  1250. !         j_finish(TRUE);
  1251. ! #endif
  1252. !         FI
  1253. !     ELSE    f->fend = f->fnxt+len;
  1254. !         /* was f->fend = (f->fnxt = f->fbuf) + len */
  1255. !         eofcount = 0;
  1256.           goto retry;
  1257.       FI
  1258.       return(c);
  1259. ***************
  1260. *** 123,129
  1261.       return(c);
  1262.   }
  1263.   
  1264. ! LOCAL    readb()
  1265.   {
  1266.       REG FILE    f=standin;
  1267.       REG INT        len;
  1268.  
  1269. --- 185,191 -----
  1270.       return(c);
  1271.   }
  1272.   
  1273. ! LOCAL    readblock()    /* ADR --- changed the name */
  1274.   {
  1275.       REG FILE    f=standin;
  1276.       REG INT        len;
  1277. ***************
  1278. *** 128,135
  1279.       REG FILE    f=standin;
  1280.       REG INT        len;
  1281.   
  1282. !     IF setjmp(INTbuf) == 0 THEN trapjmp[INTR] = 1; FI
  1283. !     REP    IF trapnote&SIGSET THEN newline(); sigchk() FI
  1284.       PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
  1285.       trapjmp[INTR] = 0;
  1286.       return(len);
  1287.  
  1288. --- 190,201 -----
  1289.       REG FILE    f=standin;
  1290.       REG INT        len;
  1291.   
  1292. !     REP
  1293. !         IF trapnote&SIGSET
  1294. !         THEN    newline(); sigchk();
  1295. !         ELIF (trapnote&TRAPSET) ANDF (rwait>0)
  1296. !         THEN    newline(); chktrap(); clearup();
  1297. !         FI
  1298.       PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
  1299.       return(len);
  1300.   }
  1301. ***************
  1302. *** 131,136
  1303.       IF setjmp(INTbuf) == 0 THEN trapjmp[INTR] = 1; FI
  1304.       REP    IF trapnote&SIGSET THEN newline(); sigchk() FI
  1305.       PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
  1306. -     trapjmp[INTR] = 0;
  1307.       return(len);
  1308.   }
  1309.  
  1310. --- 197,202 -----
  1311.           THEN    newline(); chktrap(); clearup();
  1312.           FI
  1313.       PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
  1314.       return(len);
  1315.   }
  1316.   
  1317. ***************
  1318. *** 133,136
  1319.       PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
  1320.       trapjmp[INTR] = 0;
  1321.       return(len);
  1322.   }
  1323.  
  1324. --- 198,398 -----
  1325.           FI
  1326.       PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
  1327.       return(len);
  1328. + }
  1329. + /* readb --- read a block from the outside world, and history process it */
  1330. + /*
  1331. +  * In BSD systems, using the literal next capability of the tty driver, it
  1332. +  * is actually possible to put a newline in the middle of the input line,
  1333. +  * and then hit return, so that the shell sees two lines of input.
  1334. +  *
  1335. +  * As a design decision, if there is a \n in the middle of what we've read
  1336. +  * from a terminal, treat the commands as two separately typed commands. I.e.
  1337. +  *
  1338. +  *    echo hi ^J echo there
  1339. +  *
  1340. +  * is the same as
  1341. +  *
  1342. +  *    echo hi
  1343. +  *    echo there
  1344. +  *
  1345. +  * The major reason for doing it this way is that the history mechanism knows
  1346. +  * that a \n is the end of a line.
  1347. +  *
  1348. +  * Finally, on USG systems, we just leave this code alone, since it won't
  1349. +  * get executed anyway.
  1350. +  */
  1351. + /*
  1352. +  * In word.c, the readc() function keeps a pointer to what standin pointed to
  1353. +  * when readc first gets called.  Therefore, where standin points to can not 
  1354. +  * not change across calls to readb().  To get around this, we change the
  1355. +  * contents of the structure pointed to by standin, saving and restoring
  1356. +  * it as necessary.
  1357. +  */
  1358. + #define LARGEBUF    (HISTSIZE / 2)    /* size of expanded history */
  1359. + static
  1360. + readb()
  1361. + {
  1362. +     int ilen, i, j;
  1363. +     char ibuf[BUFSIZ];    /* input into scratch area, pass to history */
  1364. +     static char expansion[LARGEBUF];
  1365. +     static int moreinbuf = FALSE;
  1366. +     static int saved_ilen = 0;
  1367. +     static int start_here = 0;
  1368. +     static struct fileblk *f = 0;
  1369. +     auto int gotoutofbuf = 0;
  1370. +     if (expanded)    /* just did a history substitution */
  1371. +         expanded = 0;
  1372. +     if ((flags & nohistflg) || (flags & prompt) == 0 || ! isatty (input)
  1373. +             || standin->fstak != 0)
  1374. +     {
  1375. +         ilen = readblock ();
  1376. +         if (ilen > 0)
  1377. +             standin->fnxt = standin->fbuf;
  1378. +         return (ilen);
  1379. +         /* not doing history expansion at all */
  1380. +     }
  1381. +     if (f == 0)
  1382. +         f = standin;
  1383. +     ilen = 0;
  1384. +     /*
  1385. +      * First, if there was more stuff in the last buffer, go and get it.
  1386. +      * If not get some more from the outside world.
  1387. +      *
  1388. +      * Then, make sure we've read up to a newline.
  1389. +      * This is basically in case someone has done something bizarre
  1390. +      * like 'stty raw', and input is coming in one character at a time.
  1391. +      *
  1392. +      * We use a heuristic.  If amount read is just 1, keep reading till
  1393. +      * we get a newline.  Else, read in a complete line from the terminal.
  1394. +      * Once we're in raw mode, can't reset it until a newline is typed.
  1395. +      *
  1396. +      * If not reading one character at a time, then do the stuff for
  1397. +      * embedded newlines.
  1398. +      */
  1399. +     if (moreinbuf)
  1400. +     {
  1401. +         for (i = 0, j = start_here; f->fbuf[j] != NL && j < saved_ilen; i++, j++)
  1402. +             ibuf[i] = f->fbuf[j];
  1403. + #ifdef notdef
  1404. +         if (f->fbuf[j] != NL)
  1405. +         {
  1406. +             prs ("internal i/o error C in readb\n");
  1407. +             return (0);
  1408. +         }
  1409. + #endif
  1410. +         if (f->fbuf[j] == NL)
  1411. +             ibuf[i++] = NL;
  1412. +         ibuf[i] = '\0';
  1413. +         ilen = i;
  1414. +         /* embedded newline */
  1415. +         moreinbuf = (++j < saved_ilen - 1);
  1416. +         if (moreinbuf)
  1417. +             start_here = j;    /* where to start next time */
  1418. +         gotoutofbuf = 1;
  1419. +     }
  1420. +     else    /* wasn't an embedded \n last time */
  1421. +     {
  1422. +         ilen = readblock ();
  1423. +     
  1424. +         if (ilen <= 0)    /* EOF or error */
  1425. +             return (ilen);
  1426. +         if (ilen == 1)    /* either in raw mode, or an empty line */
  1427. +         {
  1428. +             i = 0;
  1429. +             ibuf[i++] = f->fbuf[0];
  1430. +             if (f->fbuf[0] == NL)
  1431. +             {
  1432. +                 ibuf[i] = '\0';
  1433. +                 goto dohist;
  1434. +             }
  1435. +             while ((ilen = readblock()) > 0)
  1436. +             {
  1437. +                 if (ilen != 1)
  1438. +                 {
  1439. +                     prs ("internal i/o error A in readb\n");
  1440. +                     return (0);
  1441. +                 }
  1442. +                 ibuf[i++] = f->fbuf[0];
  1443. +                 if (f->fbuf[0] == NL)
  1444. +                 {
  1445. +                     ibuf[i] = '\0';
  1446. +                     break;    /* while */
  1447. +                 }
  1448. +             }
  1449. +             ilen = i;
  1450. +             gotoutofbuf = TRUE;
  1451. +             /* force code below to use collected string */
  1452. +         }
  1453. +         else
  1454. +         {
  1455. +             /* reading bunches of characters at once */
  1456. +             for (i = 0; f->fbuf[i] != NL && i < ilen; i++)
  1457. +                 ibuf[i] = f->fbuf[i];
  1458. + #ifdef notdef
  1459. +             if (f->fbuf[i] != NL)
  1460. +             {
  1461. +                 prs ("internal i/o error B in readb\n");
  1462. +                 return (0);
  1463. +             }
  1464. + #endif
  1465. +             ibuf[i++] = NL;
  1466. +             ibuf[i] = '\0';
  1467. +             /* ilen was set by readblock() */
  1468. +             /* embedded newline */
  1469. +             moreinbuf = (i < ilen - 1);
  1470. +             if (moreinbuf)
  1471. +             {
  1472. +                 saved_ilen = ilen;
  1473. +                 start_here = i;
  1474. +                 /* where to start next time */
  1475. +                 gotoutofbuf = 1;
  1476. +             }
  1477. +         }
  1478. +     }
  1479. + dohist:
  1480. +     /* quick heuristic */
  1481. +     if (! gotoutofbuf && ilen == 1 && f->fbuf[0] == NL)
  1482. +     {
  1483. +         f->fnxt = f->fbuf;
  1484. +         return (ilen);
  1485. +     }
  1486. +     if (histsub (ibuf, expansion, sizeof expansion))
  1487. +     {
  1488. +         int olen = length (expansion) - 1;
  1489. +         if (! expanded && ! gotoutofbuf)
  1490. +         {
  1491. +             standin->fnxt = standin->fbuf;
  1492. +             return (ilen);
  1493. +         }
  1494. +         /* else
  1495. +             expanded == TRUE or from buffer */
  1496. +         standin->fnxt = expansion;
  1497. +         return (olen);
  1498. +     }
  1499. +     else
  1500. +     {
  1501. +         /* hist expansion failed, return an empty line */
  1502. +         standin->fnxt = standin->fbuf;
  1503. +         standin->fbuf[0] = NL;
  1504. +         return (1);
  1505. +     }
  1506.   }
  1507. :::::::: xec.c :::::::
  1508. *** ../orig.u/xec.c    Wed May 15 17:13:46 1985
  1509. --- xec.c    Tue Jun  4 17:58:16 1985
  1510. ***************
  1511. *** 12,17
  1512.    */
  1513.   
  1514.   #include    "defs.h"
  1515.   #include    "sym.h"
  1516.   
  1517.   LOCAL INT    parent;
  1518.  
  1519. --- 12,18 -----
  1520.    */
  1521.   
  1522.   #include    "defs.h"
  1523. + #include    <errno.h>
  1524.   #include    "sym.h"
  1525.   
  1526.   LOCAL INT    parent;
  1527. ***************
  1528. *** 23,29
  1529.   /* ========    command execution    ========*/
  1530.   
  1531.   
  1532. ! execute(argt, execflg, pf1, pf2)
  1533.       TREPTR        argt;
  1534.       INT        *pf1, *pf2;
  1535.   {
  1536.  
  1537. --- 24,30 -----
  1538.   /* ========    command execution    ========*/
  1539.   
  1540.   
  1541. ! execute(argt, execflg, errorflg, pf1, pf2)
  1542.       TREPTR        argt;
  1543.       INT        *pf1, *pf2;
  1544.   {
  1545. ***************
  1546. *** 30,35
  1547.       /* `stakbot' is preserved by this routine */
  1548.       REG TREPTR    t;
  1549.       STKPTR        sav=savstak();
  1550.   
  1551.       sigchk();
  1552.   
  1553.  
  1554. --- 31,46 -----
  1555.       /* `stakbot' is preserved by this routine */
  1556.       REG TREPTR    t;
  1557.       STKPTR        sav=savstak();
  1558. + #if pyr
  1559. +     auto INT    change_univ = FALSE;
  1560. +     auto INT    new_univ = 0;
  1561. +     /*
  1562. +      * universes run from 1 to NUMUNIV: We start out at 0
  1563. +      * and increment new_univ in the swtich for internal
  1564. +      * commands, below. new_univ nust *not* be assigned to, directly
  1565. +      * or via side effects, any place else
  1566. +      */
  1567. + #endif
  1568.   
  1569.       sigchk();
  1570.   
  1571. ***************
  1572. *** 33,38
  1573.   
  1574.       sigchk();
  1575.   
  1576.       IF (t=argt) ANDF execbrk==0
  1577.       THEN    REG INT        treeflgs;
  1578.           INT        oldexit, type;
  1579.  
  1580. --- 44,50 -----
  1581.   
  1582.       sigchk();
  1583.   
  1584. +     IF ! errorflg THEN flags &= ~errflg FI
  1585.       IF (t=argt) ANDF execbrk==0
  1586.       THEN    REG INT        treeflgs;
  1587.           INT        oldexit, type;
  1588. ***************
  1589. *** 54,60
  1590.               com=scan(argn);
  1591.               a1=com[1]; gchain=schain;
  1592.   
  1593. !             IF argn==0 ORF (internal=syslook(com[0],commands))
  1594.               THEN    setlist(t->comset, 0);
  1595.               FI
  1596.   
  1597.  
  1598. --- 66,72 -----
  1599.               com=scan(argn);
  1600.               a1=com[1]; gchain=schain;
  1601.   
  1602. !             IF (internal=syslook(com[0],commands)) ORF argn==0
  1603.               THEN    setlist(t->comset, 0);
  1604.               FI
  1605.   
  1606. ***************
  1607. *** 75,81
  1608.       
  1609.                           IF (f=pathopen(getpath(a1), a1)) < 0
  1610.                           THEN failed(a1,notfound);
  1611. !                         ELSE execexp(0,f);
  1612.                           FI
  1613.                       FI
  1614.                       break;
  1615.  
  1616. --- 87,99 -----
  1617.       
  1618.                           IF (f=pathopen(getpath(a1), a1)) < 0
  1619.                           THEN failed(a1,notfound);
  1620. !                         ELSE
  1621. !                             INT savedot = flags&dotflg;
  1622. !                             flags |= dotflg;
  1623. !                             execexp(0,f);
  1624. !                             flags &= ~dotflg;
  1625. !                             flags |= savedot;
  1626.                           FI
  1627.                       FI
  1628.                       break;
  1629. ***************
  1630. *** 88,93
  1631.                       break;
  1632.       
  1633.                   case SYSEXIT:
  1634.                       exitsh(a1?stoi(a1):oldexit);
  1635.       
  1636.                   case SYSNULL:
  1637.  
  1638. --- 106,116 -----
  1639.                       break;
  1640.       
  1641.                   case SYSEXIT:
  1642. + #if JOBS
  1643. +                     IF j_finish(FALSE) THEN break; FI
  1644. + #endif
  1645. +                     histsave (histfnod.namval);
  1646. +                     flags |= forked;    /* force exit */
  1647.                       exitsh(a1?stoi(a1):oldexit);
  1648.       
  1649.                   case SYSNULL:
  1650. ***************
  1651. *** 95,101
  1652.                       break;
  1653.       
  1654.                   case SYSCONT:
  1655. !                     execbrk = -loopcnt; break;
  1656.       
  1657.                   case SYSBREAK:
  1658.                       IF (execbrk=loopcnt) ANDF a1
  1659.  
  1660. --- 118,127 -----
  1661.                       break;
  1662.       
  1663.                   case SYSCONT:
  1664. !                     IF (execbrk = -loopcnt) ANDF a1
  1665. !                     THEN    breakcnt = stoi (a1); 
  1666. !                     FI
  1667. !                     break;
  1668.       
  1669.                   case SYSBREAK:
  1670.                       IF (execbrk=loopcnt) ANDF a1
  1671. ***************
  1672. *** 139,144
  1673.                       IF a1==0 THEN break FI
  1674.       
  1675.                   case SYSLOGIN:
  1676.                       flags |= forked;
  1677.                       oldsigs(); execa(com); done();
  1678.       
  1679.  
  1680. --- 165,171 -----
  1681.                       IF a1==0 THEN break FI
  1682.       
  1683.                   case SYSLOGIN:
  1684. +                     histsave (histfnod.namval);
  1685.                       flags |= forked;
  1686.                       oldsigs(); execa(com); done();
  1687.       
  1688. ***************
  1689. *** 151,160
  1690.                       break;
  1691.       
  1692.                   case SYSSHFT:
  1693. !                     IF dolc<1
  1694. !                     THEN    error(badshift);
  1695. !                     ELSE    dolv++; dolc--;
  1696. !                     FI
  1697.                       assnum(&dolladr, dolc);
  1698.                       break;
  1699.       
  1700.  
  1701. --- 178,193 -----
  1702.                       break;
  1703.       
  1704.                   case SYSSHFT:
  1705. !                     BEGIN
  1706. !                         INT places;
  1707. !                         places = a1 ? stoi(a1) : 1;
  1708. !                         FOR ; places--;
  1709. !                         DO    IF dolc<1
  1710. !                             THEN    error(badshift);
  1711. !                             ELSE    dolv++; dolc--;
  1712. !                             FI
  1713. !                         OD
  1714. !                     END
  1715.                       assnum(&dolladr, dolc);
  1716.                       break;
  1717.       
  1718. ***************
  1719. *** 159,164
  1720.                       break;
  1721.       
  1722.                   case SYSWAIT:
  1723.                       await(-1);
  1724.                       break;
  1725.       
  1726.  
  1727. --- 192,198 -----
  1728.                       break;
  1729.       
  1730.                   case SYSWAIT:
  1731. +                     /*
  1732.                       await(-1);
  1733.                       */
  1734.                       await(a1?stoi(a1):-1,1);
  1735. ***************
  1736. *** 160,165
  1737.       
  1738.                   case SYSWAIT:
  1739.                       await(-1);
  1740.                       break;
  1741.       
  1742.                   case SYSREAD:
  1743.  
  1744. --- 194,201 -----
  1745.                   case SYSWAIT:
  1746.                       /*
  1747.                       await(-1);
  1748. +                     */
  1749. +                     await(a1?stoi(a1):-1,1);
  1750.                       break;
  1751.       
  1752.                   case SYSREAD:
  1753. ***************
  1754. *** 163,168
  1755.                       break;
  1756.       
  1757.                   case SYSREAD:
  1758.                       exitval=readvar(&com[1]);
  1759.                       break;
  1760.   
  1761.  
  1762. --- 199,205 -----
  1763.                       break;
  1764.       
  1765.                   case SYSREAD:
  1766. +                     rwait=1;
  1767.                       exitval=readvar(&com[1]);
  1768.                       break;
  1769.   
  1770. ***************
  1771. *** 222,227
  1772.                                           }
  1773.                                           break;
  1774.       
  1775.                   default:
  1776.                       internal=builtin(argn,com);
  1777.       
  1778.  
  1779. --- 259,327 -----
  1780.                                           }
  1781.                                           break;
  1782.       
  1783. + #if JOBS
  1784. +                 case SYSJOBS:
  1785. +                     j_print();
  1786. +                     break;
  1787. +                 case SYSFG:
  1788. +                     j_resume(a1, FALSE);
  1789. +                     break;
  1790. +                 case SYSBG:
  1791. +                     j_resume(a1, TRUE);
  1792. +                     break;
  1793. +                 case SYSSUSPEND:
  1794. +                     exitval = 1;
  1795. +                     IF getppid() == 1
  1796. +                     THEN    prs (nosusp);
  1797. +                     ELSE    exitval = 0;
  1798. +                         kill (getpid(), STOP);
  1799. +                     FI
  1800. +                     break;
  1801. + #endif
  1802. + #if pyr
  1803. +                 /*
  1804. +                  * UCB is Universe 2
  1805. +                  * ATT is Universe 1
  1806. +                  * new_univ == 0
  1807. +                  */
  1808. +                 case SYSUCB:
  1809. +                     new_univ++;
  1810. +                     /* fall thru */
  1811. +                 case SYSATT:
  1812. +                     new_univ++;
  1813. +                     IF argn > 1
  1814. +                     THEN
  1815. +                         change_univ = TRUE;
  1816. +                         com++;
  1817. +                         goto doit;
  1818. +                     ELSE
  1819. +                         setuniverse (cur_univ = new_univ);
  1820. +                         univnod.namflg &= ~N_RDONLY;
  1821. +                         assign (& univnod, univ_name[cur_univ - 1]);
  1822. +                         attrib ((& univnod), N_RDONLY);
  1823. +                         break;
  1824. +                     FI
  1825. +                 case SYSUNIVERSE:
  1826. +                     IF eq(com[1], dashl)
  1827. +                     THEN    prs_buff (univ_longname[cur_univ - 1]);
  1828. +                     ELSE    prs_buff (univ_name[cur_univ - 1]);
  1829. +                     FI
  1830. +                     prc_buff (NL);
  1831. +                     break;
  1832. + #endif
  1833. +                 case SYSHISTORY:
  1834. +                     exitval = history (argn, com);
  1835. +                     break;
  1836.                   default:
  1837.                       internal=builtin(argn,com);
  1838.       
  1839. ***************
  1840. *** 233,239
  1841.                       break;
  1842.                   FI
  1843.               ELIF t->treio==0
  1844. !             THEN    break;
  1845.               FI
  1846.               END
  1847.       
  1848.  
  1849. --- 333,340 -----
  1850.                       break;
  1851.                   FI
  1852.               ELIF t->treio==0
  1853. !             THEN    chktrap();
  1854. !                 break;
  1855.               FI
  1856.               END
  1857.       
  1858. ***************
  1859. *** 238,243
  1860.               END
  1861.       
  1862.           case TFORK:
  1863.               IF execflg ANDF (treeflgs&(FAMP|FPOU))==0
  1864.               THEN    parent=0;
  1865.               ELSE    WHILE (parent=fork()) == -1
  1866.  
  1867. --- 339,347 -----
  1868.               END
  1869.       
  1870.           case TFORK:
  1871. + #if pyr
  1872. +         doit:
  1873. + #endif
  1874.               IF execflg ANDF (treeflgs&(FAMP|FPOU))==0
  1875.               THEN    parent=0;
  1876.               ELSE    WHILE (parent=fork()) == -1
  1877. ***************
  1878. *** 242,247
  1879.               THEN    parent=0;
  1880.               ELSE    WHILE (parent=fork()) == -1
  1881.                   DO sigchk(); alarm(10); pause() OD
  1882.               FI
  1883.   
  1884.               IF parent
  1885.  
  1886. --- 346,354 -----
  1887.               THEN    parent=0;
  1888.               ELSE    WHILE (parent=fork()) == -1
  1889.                   DO sigchk(); alarm(10); pause() OD
  1890. + #if JOBS
  1891. +                 IF parent == 0 THEN j_top_level = FALSE; FI
  1892. + #endif
  1893.               FI
  1894.   
  1895.               IF parent
  1896. ***************
  1897. *** 248,253
  1898.               THEN    /* This is the parent branch of fork;    */
  1899.                   /* it may or may not wait for the child. */
  1900.                   IF treeflgs&FPRS ANDF flags&ttyflg
  1901.                   THEN    prn(parent); newline();
  1902.                   FI
  1903.                   IF treeflgs&FPCL THEN closepipe(pf1) FI
  1904.  
  1905. --- 355,363 -----
  1906.               THEN    /* This is the parent branch of fork;    */
  1907.                   /* it may or may not wait for the child. */
  1908.                   IF treeflgs&FPRS ANDF flags&ttyflg
  1909. + #if JOBS
  1910. +                 ANDF (flags&jobflg) == 0
  1911. + #endif
  1912.                   THEN    prn(parent); newline();
  1913.                   FI
  1914.                   IF treeflgs&FPCL THEN closepipe(pf1) FI
  1915. ***************
  1916. *** 251,256
  1917.                   THEN    prn(parent); newline();
  1918.                   FI
  1919.                   IF treeflgs&FPCL THEN closepipe(pf1) FI
  1920.                   IF (treeflgs&(FAMP|FPOU))==0
  1921.                   THEN    await(parent);
  1922.                   ELIF (treeflgs&FAMP)==0
  1923.  
  1924. --- 361,369 -----
  1925.                   THEN    prn(parent); newline();
  1926.                   FI
  1927.                   IF treeflgs&FPCL THEN closepipe(pf1) FI
  1928. + #if JOBS
  1929. +                 j_child_post(parent, treeflgs&FAMP, treeflgs&FPIN, t);
  1930. + #endif
  1931.                   IF (treeflgs&(FAMP|FPOU))==0
  1932.                   THEN    await(parent, 0);
  1933.   #if JOBS
  1934. ***************
  1935. *** 252,258
  1936.                   FI
  1937.                   IF treeflgs&FPCL THEN closepipe(pf1) FI
  1938.                   IF (treeflgs&(FAMP|FPOU))==0
  1939. !                 THEN    await(parent);
  1940.                   ELIF (treeflgs&FAMP)==0
  1941.                   THEN    post(parent);
  1942.                   ELSE    assnum(&pcsadr, parent);
  1943.  
  1944. --- 365,374 -----
  1945.                   j_child_post(parent, treeflgs&FAMP, treeflgs&FPIN, t);
  1946.   #endif
  1947.                   IF (treeflgs&(FAMP|FPOU))==0
  1948. !                 THEN    await(parent, 0);
  1949. ! #if JOBS
  1950. !                     j_reset_pg();
  1951. ! #endif
  1952.                   ELIF (treeflgs&FAMP)==0
  1953.                   THEN    post(parent);
  1954.                   ELSE    assnum(&pcsadr, parent);
  1955. ***************
  1956. *** 263,268
  1957.   
  1958.   
  1959.               ELSE    /* this is the forked branch (child) of execute */
  1960.                   flags |= forked; iotemp=0;
  1961.                   postclr();
  1962.                   settmp();
  1963.  
  1964. --- 379,393 -----
  1965.   
  1966.   
  1967.               ELSE    /* this is the forked branch (child) of execute */
  1968. + #if pyr
  1969. +                 IF change_univ
  1970. +                 THEN    setuniverse (new_univ);
  1971. +                     univnod.namflg &= ~N_RDONLY;
  1972. +                     assign (&univnod, univ_name[cur_univ - 1]);
  1973. +                     attrib ((&univnod), N_RDONLY);
  1974. +                 FI
  1975. + #endif
  1976.                   flags |= forked; iotemp=0;
  1977.                   postclr();
  1978.                   settmp();
  1979. ***************
  1980. *** 268,274
  1981.                   settmp();
  1982.   
  1983.                   /* Turn off INTR and QUIT if `FINT'  */
  1984. !                 /* Reset ramaining signals to parent */
  1985.                   /* except for those `lost' by trap   */
  1986.                   oldsigs();
  1987.                   IF treeflgs&FINT
  1988.  
  1989. --- 393,399 -----
  1990.                   settmp();
  1991.   
  1992.                   /* Turn off INTR and QUIT if `FINT'  */
  1993. !                 /* Reset remaining signals to parent */
  1994.                   /* except for those `lost' by trap   */
  1995.                   oldsigs();
  1996.                   IF treeflgs&FINT
  1997. ***************
  1998. *** 272,277
  1999.                   /* except for those `lost' by trap   */
  2000.                   oldsigs();
  2001.                   IF treeflgs&FINT
  2002.                   THEN    signal(INTR,1); signal(QUIT,1);
  2003.                   FI
  2004.   
  2005.  
  2006. --- 397,405 -----
  2007.                   /* except for those `lost' by trap   */
  2008.                   oldsigs();
  2009.                   IF treeflgs&FINT
  2010. + #if JOBS
  2011. +                 ANDF (flags&jobflg) == 0
  2012. + #endif
  2013.                   THEN    signal(INTR,1); signal(QUIT,1);
  2014.                   FI
  2015.   
  2016. ***************
  2017. *** 287,292
  2018.   
  2019.                   /* default std input for & */
  2020.                   IF treeflgs&FINT ANDF ioset==0
  2021.                   THEN    rename(chkopen(devnull),0);
  2022.                   FI
  2023.   
  2024.  
  2025. --- 415,423 -----
  2026.   
  2027.                   /* default std input for & */
  2028.                   IF treeflgs&FINT ANDF ioset==0
  2029. + #if JOBS
  2030. +                 ANDF (flags&jobflg) == 0
  2031. + #endif
  2032.                   THEN    rename(chkopen(devnull),0);
  2033.                   FI
  2034.   
  2035. ***************
  2036. *** 293,299
  2037.                   /* io redirection */
  2038.                   initio(t->treio);
  2039.                   IF type!=TCOM
  2040. !                 THEN    execute(t->forktre,1);
  2041.                   ELIF com[0]!=ENDARGS
  2042.                   THEN    setlist(t->comset,N_EXPORT);
  2043.                       execa(com);
  2044.  
  2045. --- 424,430 -----
  2046.                   /* io redirection */
  2047.                   initio(t->treio);
  2048.                   IF type!=TCOM
  2049. !                 THEN    execute(t->forktre,1, errorflg);
  2050.                   ELIF com[0]!=ENDARGS
  2051.                   THEN
  2052.                       eflag = 0;
  2053. ***************
  2054. *** 295,301
  2055.                   IF type!=TCOM
  2056.                   THEN    execute(t->forktre,1);
  2057.                   ELIF com[0]!=ENDARGS
  2058. !                 THEN    setlist(t->comset,N_EXPORT);
  2059.                       execa(com);
  2060.                   FI
  2061.                   done();
  2062.  
  2063. --- 426,438 -----
  2064.                   IF type!=TCOM
  2065.                   THEN    execute(t->forktre,1, errorflg);
  2066.                   ELIF com[0]!=ENDARGS
  2067. !                 THEN
  2068. !                     eflag = 0;
  2069. !                     /* eflag must be set to zero so commands
  2070. !                        implemented as shell scripts do not
  2071. !                        exit if set -e and some command in
  2072. !                        the script returns non zero */
  2073. !                     setlist(t->comset,N_EXPORT);
  2074.                       execa(com);
  2075.                   FI
  2076.                   done();
  2077. ***************
  2078. *** 303,309
  2079.   
  2080.           case TPAR:
  2081.               rename(dup(2),output);
  2082. !             execute(t->partre,execflg);
  2083.               done();
  2084.   
  2085.           case TFIL:
  2086.  
  2087. --- 440,446 -----
  2088.   
  2089.           case TPAR:
  2090.               rename(dup(2),output);
  2091. !             execute(t->partre,execflg, errorflg);
  2092.               done();
  2093.   
  2094.           case TFIL:
  2095. ***************
  2096. *** 309,316
  2097.           case TFIL:
  2098.               BEGIN
  2099.                  INT pv[2]; chkpipe(pv);
  2100. !                IF execute(t->lstlef, 0, pf1, pv)==0
  2101. !                THEN    execute(t->lstrit, execflg, pv, pf2);
  2102.                  ELSE    closepipe(pv);
  2103.                  FI
  2104.               END
  2105.  
  2106. --- 446,453 -----
  2107.           case TFIL:
  2108.               BEGIN
  2109.                  INT pv[2]; chkpipe(pv);
  2110. !                IF execute(t->lstlef, 0, errorflg, pf1, pv)==0
  2111. !                THEN    execute(t->lstrit, execflg, errorflg, pv, pf2);
  2112.                  ELSE    closepipe(pv);
  2113.                  FI
  2114.               END
  2115. ***************
  2116. *** 317,324
  2117.               break;
  2118.   
  2119.           case TLST:
  2120. !             execute(t->lstlef,0);
  2121. !             execute(t->lstrit,execflg);
  2122.               break;
  2123.   
  2124.           case TAND:
  2125.  
  2126. --- 454,461 -----
  2127.               break;
  2128.   
  2129.           case TLST:
  2130. !             execute(t->lstlef,0, errorflg);
  2131. !             execute(t->lstrit,execflg, errorflg);
  2132.               break;
  2133.   
  2134.           case TAND:
  2135. ***************
  2136. *** 322,329
  2137.               break;
  2138.   
  2139.           case TAND:
  2140. !             IF execute(t->lstlef,0)==0
  2141. !             THEN    execute(t->lstrit,execflg);
  2142.               FI
  2143.               break;
  2144.   
  2145.  
  2146. --- 459,466 -----
  2147.               break;
  2148.   
  2149.           case TAND:
  2150. !             IF execute(t->lstlef,0, 0)==0
  2151. !             THEN    execute(t->lstrit,execflg, errorflg);
  2152.               FI
  2153.               break;
  2154.   
  2155. ***************
  2156. *** 328,335
  2157.               break;
  2158.   
  2159.           case TORF:
  2160. !             IF execute(t->lstlef,0)!=0
  2161. !             THEN    execute(t->lstrit,execflg);
  2162.               FI
  2163.               break;
  2164.   
  2165.  
  2166. --- 465,472 -----
  2167.               break;
  2168.   
  2169.           case TORF:
  2170. !             IF execute(t->lstlef,0, 0)!=0
  2171. !             THEN    execute(t->lstrit,execflg, errorflg);
  2172.               FI
  2173.               break;
  2174.   
  2175. ***************
  2176. *** 350,357
  2177.                  loopcnt++;
  2178.                  WHILE *args!=ENDARGS ANDF execbrk==0
  2179.                  DO    assign(n,*args++);
  2180. !                 execute(t->fortre,0);
  2181. !                 IF execbrk<0 THEN execbrk=0 FI
  2182.                  OD
  2183.                  IF breakcnt THEN breakcnt-- FI
  2184.                  execbrk=breakcnt; loopcnt--;
  2185.  
  2186. --- 487,499 -----
  2187.                  loopcnt++;
  2188.                  WHILE *args!=ENDARGS ANDF execbrk==0
  2189.                  DO    assign(n,*args++);
  2190. !                 execute(t->fortre,0, errorflg);
  2191. !                 IF execbrk
  2192. !                 THEN    IF breakcnt > 1 ORF execbrk > 0
  2193. !                     THEN break;
  2194. !                     ELSE execbrk = breakcnt = 0;
  2195. !                     FI
  2196. !                 FI
  2197.                  OD
  2198.                  IF breakcnt THEN breakcnt-- FI
  2199.                  execbrk = (execbrk < 0 ? -breakcnt : breakcnt);
  2200. ***************
  2201. *** 354,360
  2202.                   IF execbrk<0 THEN execbrk=0 FI
  2203.                  OD
  2204.                  IF breakcnt THEN breakcnt-- FI
  2205. !                execbrk=breakcnt; loopcnt--;
  2206.                  argfor=freeargs(argsav);
  2207.               END
  2208.               break;
  2209.  
  2210. --- 496,503 -----
  2211.                   FI
  2212.                  OD
  2213.                  IF breakcnt THEN breakcnt-- FI
  2214. !                execbrk = (execbrk < 0 ? -breakcnt : breakcnt);
  2215. !                loopcnt--;
  2216.                  argfor=freeargs(argsav);
  2217.               END
  2218.               break;
  2219. ***************
  2220. *** 365,373
  2221.                  INT        i=0;
  2222.   
  2223.                  loopcnt++;
  2224. !                WHILE execbrk==0 ANDF (execute(t->whtre,0)==0)==(type==TWH)
  2225. !                DO i=execute(t->dotre,0);
  2226. !                   IF execbrk<0 THEN execbrk=0 FI
  2227.                  OD
  2228.                  IF breakcnt THEN breakcnt-- FI
  2229.                  execbrk=breakcnt; loopcnt--; exitval=i;
  2230.  
  2231. --- 508,521 -----
  2232.                  INT        i=0;
  2233.   
  2234.                  loopcnt++;
  2235. !                WHILE execbrk<=0 ANDF (execute(t->whtre,0,0)==0)==(type==TWH)
  2236. !                DO i=execute(t->dotre,0, errorflg);
  2237. !                   IF execbrk
  2238. !                   THEN    IF breakcnt > 1 ORF execbrk > 0
  2239. !                     THEN break;
  2240. !                     ELSE execbrk = breakcnt = 0;
  2241. !                     FI
  2242. !                   FI
  2243.                  OD
  2244.                  IF breakcnt THEN breakcnt-- FI
  2245.                  execbrk=(execbrk < 0 ? -breakcnt : breakcnt);
  2246. ***************
  2247. *** 370,376
  2248.                     IF execbrk<0 THEN execbrk=0 FI
  2249.                  OD
  2250.                  IF breakcnt THEN breakcnt-- FI
  2251. !                execbrk=breakcnt; loopcnt--; exitval=i;
  2252.               END
  2253.               break;
  2254.   
  2255.  
  2256. --- 518,525 -----
  2257.                     FI
  2258.                  OD
  2259.                  IF breakcnt THEN breakcnt-- FI
  2260. !                execbrk=(execbrk < 0 ? -breakcnt : breakcnt);
  2261. !                loopcnt--; exitval=i;
  2262.               END
  2263.               break;
  2264.   
  2265. ***************
  2266. *** 375,383
  2267.               break;
  2268.   
  2269.           case TIF:
  2270. !             IF execute(t->iftre,0)==0
  2271. !             THEN    execute(t->thtre,execflg);
  2272. !             ELSE    execute(t->eltre,execflg);
  2273.               FI
  2274.               break;
  2275.   
  2276.  
  2277. --- 524,534 -----
  2278.               break;
  2279.   
  2280.           case TIF:
  2281. !             IF execute(t->iftre,0,0)==0
  2282. !             THEN    execute(t->thtre,execflg, errorflg);
  2283. !             ELIF    t->eltre
  2284. !             THEN    execute(t->eltre,execflg, errorflg);
  2285. !             ELSE    exitval = 0; /* force zero exit for if-then-fi */
  2286.               FI
  2287.               break;
  2288.   
  2289. ***************
  2290. *** 390,396
  2291.                   WHILE rex
  2292.                   DO    REG STRING    s;
  2293.                       IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
  2294. !                     THEN    execute(t->regcom,0);
  2295.                           t=0; break;
  2296.                       ELSE    rex=rex->argnxt;
  2297.                       FI
  2298.  
  2299. --- 541,547 -----
  2300.                   WHILE rex
  2301.                   DO    REG STRING    s;
  2302.                       IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
  2303. !                     THEN    execute(t->regcom,0,errorflg);
  2304.                           t=0; break;
  2305.                       ELSE    rex=rex->argnxt;
  2306.                       FI
  2307. ***************
  2308. *** 405,410
  2309.   
  2310.       sigchk();
  2311.       tdystak(sav);
  2312.       return(exitval);
  2313.   }
  2314.   
  2315.  
  2316. --- 556,562 -----
  2317.   
  2318.       sigchk();
  2319.       tdystak(sav);
  2320. +     flags |= eflag;
  2321.       return(exitval);
  2322.   }
  2323.   
  2324. ***************
  2325. *** 420,425
  2326.       ELIF f>=0
  2327.       THEN    initf(f);
  2328.       FI
  2329. !     execute(cmd(NL, NLFLG|MTFLG),0);
  2330.       pop();
  2331.   }
  2332.  
  2333. --- 572,577 -----
  2334.       ELIF f>=0
  2335.       THEN    initf(f);
  2336.       FI
  2337. !     execute(cmd(NL, NLFLG|MTFLG),0, flags&errflg);
  2338.       pop();
  2339.   }
  2340.  
  2341.