home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume29 / pdksh / patch03c < prev    next >
Text File  |  1992-04-25  |  35KB  |  1,591 lines

  1. Newsgroups: comp.sources.misc
  2. From: sjg@zen.void.oz.au (Simon J. Gerraty)
  3. Subject:  v29i085:  pdksh - Public Domain Korn Shell, v4, Patch03c/5
  4. Message-ID: <1992Apr26.041550.22314@sparky.imd.sterling.com>
  5. X-Md4-Signature: 33c575c38912b013f9574b876cc8ed58
  6. Date: Sun, 26 Apr 1992 04:15:50 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: sjg@zen.void.oz.au (Simon J. Gerraty)
  10. Posting-number: Volume 29, Issue 85
  11. Archive-name: pdksh/patch03c
  12. Environment: UNIX
  13. Patch-To: pdksh: Volume 25, Issue 47-55
  14.  
  15. *** sh/jobs.c.old    Sat Apr 25 17:44:29 1992
  16. --- sh/jobs.c    Sat Apr 25 18:31:27 1992
  17. ***************
  18. *** 2,9 ****
  19.    * Process and job control
  20.    */
  21.   #ifndef lint
  22. ! static char *RCSid = "$Id: jobs.c,v 3.5 89/03/27 15:51:01 egisin Exp $";
  23. ! static char  sccs_id[] = "@(#)jobs.c     1.5  91/11/22  22:53:20  (sjg)";
  24.   #endif
  25.   
  26.   /*
  27. --- 2,8 ----
  28.    * Process and job control
  29.    */
  30.   #ifndef lint
  31. ! static char *RCSid = "$Id: jobs.c,v 1.3 1992/04/25 08:29:52 sjg Exp $";
  32.   #endif
  33.   
  34.   /*
  35. ***************
  36. *** 29,35 ****
  37.   #include <sys/times.h>
  38.   #include <sys/wait.h>
  39.   #include "sh.h"
  40. - #include "tree.h"
  41.   #ifdef JOBS
  42.   #ifdef _BSD
  43.   #include <sys/ioctl.h>
  44. --- 28,33 ----
  45. ***************
  46. *** 67,73 ****
  47.   #   define WEXITSTATUS(x)    ((x).w_retcode)
  48.   # endif
  49.   # ifndef HAVE_WAITPID
  50. ! #   define    waitpid(pid, sp, opts)    wait3(sp, opts, (Void*)NULL)
  51.   # endif
  52.   #else                    /* not _BSD */
  53.   # ifndef WIFCORED
  54. --- 65,71 ----
  55.   #   define WEXITSTATUS(x)    ((x).w_retcode)
  56.   # endif
  57.   # ifndef HAVE_WAITPID
  58. ! #   define    waitpid(pid, sp, opts)    wait3(sp, opts, (void*)NULL)
  59.   # endif
  60.   #else                    /* not _BSD */
  61.   # ifndef WIFCORED
  62. ***************
  63. *** 81,87 ****
  64.    *    int setpgid(pid_t pid, pid_t pgid); // Set process group id for job control
  65.    */
  66.   
  67. - static int sigchld_caught;    /* for recording child terminations */
  68.   
  69.   #ifdef JOBS
  70.   #ifdef _BSD            /* _BSD 4.* */
  71. --- 79,84 ----
  72. ***************
  73. *** 94,99 ****
  74. --- 91,97 ----
  75.   #endif
  76.   #endif
  77.   
  78.   #ifndef    SIGCHLD
  79.   #define    SIGCHLD    SIGCLD
  80.   #endif
  81. ***************
  82. *** 109,116 ****
  83.   struct Proc {
  84.       Proc   *next;        /* `procs' list link */
  85.       int    job;        /* job number: %n */
  86. !     short    Volatile state;    /* proc state */
  87. !     short    Volatile notify; /* proc state has changed */
  88.       Proc   *prev;        /* prev member of pipeline */
  89.       pid_t    proc;        /* process id */
  90.       pid_t    pgrp;        /* process group if flag[FMONITOR] */
  91. --- 107,114 ----
  92.   struct Proc {
  93.       Proc   *next;        /* `procs' list link */
  94.       int    job;        /* job number: %n */
  95. !     short    volatile state;    /* proc state */
  96. !     short    volatile notify; /* proc state has changed */
  97.       Proc   *prev;        /* prev member of pipeline */
  98.       pid_t    proc;        /* process id */
  99.       pid_t    pgrp;        /* process group if flag[FMONITOR] */
  100. ***************
  101. *** 131,137 ****
  102. --- 129,139 ----
  103.   
  104.   clock_t    j_utime, j_stime;    /* user and system time for last job a-waited */
  105.   #ifdef JOBS
  106. + # ifdef USE_SIGACT
  107. + sigset_t sm_default, sm_sigchld;    /* signal masks */
  108. + # else
  109.   static    int    sm_default, sm_sigchld;    /* signal masks */
  110. + # endif
  111.   static    int    our_pgrp;        /* shell's pgrp */
  112.   #endif
  113.   static    Proc   *j_lastj;        /* last proc created by exchild */
  114. ***************
  115. *** 139,169 ****
  116.   static    int    j_current = 0;        /* current job */
  117.   static    int    j_previous = 0;        /* previous job */
  118.   
  119. ! static    int    j_newjob ARGS((void));
  120. ! static    void    j_print ARGS((Proc *j));
  121. ! static    Proc   *j_search ARGS((int job));
  122. ! static    int    j_waitj ARGS((Proc *j, int intr));
  123. ! static    void    j_sigchld ARGS((int sig));
  124. !     
  125.   /* initialize job control */
  126.   void
  127.   j_init()
  128.   {
  129.   #ifdef JOBS
  130. ! #ifdef NTTYDISC
  131.       int ldisc = NTTYDISC;    /* BSD brain damage */
  132.   
  133.       if (ttyfd >= 0)
  134.           ioctl(ttyfd, TIOCSETD, &ldisc);
  135. ! #endif
  136.       our_pgrp = getpgid(0);
  137.       sigchld_caught = 0;
  138.       sm_default = 0;
  139.       sm_sigchld = sigmask(SIGCHLD);
  140.       _TRACE(5, ("j_init: sm_sigchld == 0x%x", sm_sigchld));
  141. ! #endif
  142. ! #if defined(_SYSV) && !defined(JOBS)
  143.       signal(SIGCHLD, SIG_DFL);    /* necessary ??? */
  144.   #endif
  145.   }
  146.   
  147. --- 141,183 ----
  148.   static    int    j_current = 0;        /* current job */
  149.   static    int    j_previous = 0;        /* previous job */
  150.   
  151. ! static int      j_waitj     ARGS((Proc *aj, int intr));
  152. ! static void     j_print     ARGS((Proc *j));
  153. ! static int      j_newjob    ARGS((void));
  154. ! static Proc *   j_search    ARGS((int job));
  155. ! static void    j_sigchld   ARGS((int sig));
  156. !   
  157.   /* initialize job control */
  158.   void
  159.   j_init()
  160.   {
  161.   #ifdef JOBS
  162. ! # if defined(NTTYDISC) && defined(TIOCSETD)
  163.       int ldisc = NTTYDISC;    /* BSD brain damage */
  164.   
  165.       if (ttyfd >= 0)
  166.           ioctl(ttyfd, TIOCSETD, &ldisc);
  167. ! # endif
  168.       our_pgrp = getpgid(0);
  169.       sigchld_caught = 0;
  170. + # ifdef USE_SIGACT
  171. +     sigemptyset(&sm_default);
  172. +     sigemptyset(&sm_sigchld);
  173. +     sigaddset(&sm_sigchld, SIGCHLD);
  174. + # else
  175.       sm_default = 0;
  176.       sm_sigchld = sigmask(SIGCHLD);
  177.       _TRACE(5, ("j_init: sm_sigchld == 0x%x", sm_sigchld));
  178. ! # endif
  179. ! #endif 
  180. ! #ifndef JOBS
  181. ! # ifdef USE_SIGACT
  182. !     sigaction(SIGCHLD, &Sigact_dfl, NULL);
  183. ! # else
  184. ! #   ifdef _SYSV
  185.       signal(SIGCHLD, SIG_DFL);    /* necessary ??? */
  186. + #   endif
  187. + # endif
  188.   #endif
  189.   }
  190.   
  191. ***************
  192. *** 200,207 ****
  193.   void
  194.   j_change()
  195.   {
  196.       static handler_t old_tstp, old_ttin, old_ttou;
  197.       if (flag[FMONITOR]) {
  198.           if (ttyfd < 0) {
  199.               flag[FMONITOR] = 0;
  200. --- 214,224 ----
  201.   void
  202.   j_change()
  203.   {
  204. + #ifdef USE_SIGACT
  205. +     static struct sigaction old_tstp, old_ttin, old_ttou;
  206. + #else
  207.       static handler_t old_tstp, old_ttin, old_ttou;
  208. ! #endif
  209.       if (flag[FMONITOR]) {
  210.           if (ttyfd < 0) {
  211.               flag[FMONITOR] = 0;
  212. ***************
  213. *** 208,213 ****
  214. --- 225,244 ----
  215.               shellf("job control requires tty\n");
  216.               return;
  217.           }
  218. + #ifdef USE_SIGACT
  219. +         Sigact.sa_handler = j_sigchld;
  220. +         sigemptyset(&Sigact.sa_mask);
  221. +         Sigact.sa_flags = SA_RESTART;
  222. +         sigaction(SIGCHLD, &Sigact, NULL);
  223. +         Sigact.sa_flags = 0;
  224. +         sigtraps[SIGCHLD].sig_dfl = 1; /* restore on fork */
  225. +         sigaction(SIGTSTP, &Sigact_ign, &old_tstp);
  226. +         sigtraps[SIGTSTP].sig_dfl = 1;
  227. +         sigaction(SIGTTIN, &Sigact_ign, &old_ttin);
  228. +         sigtraps[SIGTTIN].sig_dfl = 1;
  229. +         sigaction(SIGTTOU, &Sigact_ign, &old_ttou);
  230. +         sigtraps[SIGTTOU].sig_dfl = 1;
  231. + #else
  232.           (void) signal(SIGCHLD, j_sigchld);
  233.           sigtraps[SIGCHLD].sig_dfl = 1; /* restore on fork */
  234.           old_tstp = signal(SIGTSTP, SIG_IGN);
  235. ***************
  236. *** 216,224 ****
  237. --- 247,269 ----
  238.           sigtraps[SIGTTIN].sig_dfl = 1;
  239.           old_ttou = signal(SIGTTOU, SIG_IGN);
  240.           sigtraps[SIGTTOU].sig_dfl = 1;
  241. + #endif
  242. + #ifdef USE_SIGACT
  243. +         sigprocmask(SIG_SETMASK, &sm_default, NULL);
  244. + #else
  245.           sigsetmask(sm_default);
  246. + #endif
  247.           tcsetpgrp(ttyfd, our_pgrp);
  248.       } else {
  249. + #ifdef USE_SIGACT
  250. +         sigaction(SIGCHLD, &Sigact_dfl, NULL);
  251. +         sigaction(SIGTSTP, &old_tstp, NULL);
  252. +         sigtraps[SIGTSTP].sig_dfl = 0;
  253. +         sigaction(SIGTTIN, &old_ttin, NULL);
  254. +         sigtraps[SIGTTIN].sig_dfl = 0;
  255. +         sigaction(SIGTTOU, &old_ttou, NULL);
  256. +         sigtraps[SIGTTOU].sig_dfl = 0;
  257. + #else
  258.           (void) signal(SIGCHLD, SIG_DFL);
  259.           (void) signal(SIGTSTP, old_tstp);
  260.           sigtraps[SIGTSTP].sig_dfl = 0;
  261. ***************
  262. *** 226,231 ****
  263. --- 271,277 ----
  264.           sigtraps[SIGTTIN].sig_dfl = 0;
  265.           (void) signal(SIGTTOU, old_ttou);
  266.           sigtraps[SIGTTOU].sig_dfl = 0;
  267. + #endif
  268.       }
  269.   }
  270.   #endif
  271. ***************
  272. *** 269,274 ****
  273. --- 315,329 ----
  274.   
  275.       /* create child process */
  276.       forksleep = 0;
  277. + #ifdef JOBS
  278. +     /* don't allow SIGCHLD until we are ready */
  279. + #ifdef USE_SIGACT
  280. +     sigprocmask(SIG_SETMASK, &sm_sigchld, NULL);
  281. + # else
  282. +     sigsetmask(sm_sigchld);
  283. + # endif
  284. + #endif
  285.       while ((i = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
  286.           if (forksleep) {
  287.               sleep(forksleep);
  288. ***************
  289. *** 284,295 ****
  290.   
  291.   #ifdef JOBS
  292.       /* job control set up */
  293. !     if (flag[FMONITOR] && !(flags&XXCOM)) {
  294. !         j->pgrp = !(flags&XPIPEI) ? j->proc : j_lastj->pgrp;
  295. !         /* do in both parent and child to avoid fork race condition */
  296. !         if (!(flags&XBGND))
  297. !             tcsetpgrp(ttyfd, j->pgrp); /* could be trouble */
  298. !         setpgid(j->proc, j->pgrp);
  299.       }
  300.   #endif
  301.       j_lastj = j;
  302. --- 339,351 ----
  303.   
  304.   #ifdef JOBS
  305.       /* job control set up */
  306. !     if (flag[FMONITOR] && !(flags&XXCOM))
  307. !     {
  308. !       j->pgrp = !(flags&XPIPEI) ? j->proc : j_lastj->pgrp;
  309. !       /* do in both parent and child to avoid fork race condition */
  310. !       if (!(flags&XBGND))
  311. !         tcsetpgrp(ttyfd, j->pgrp); /* could be trouble */
  312. !       setpgid(j->proc, j->pgrp);
  313.       }
  314.   #endif
  315.       j_lastj = j;
  316. ***************
  317. *** 298,308 ****
  318.           e.oenv = NULL;
  319.           if (flag[FTALKING])
  320.               restoresigs();
  321. !         if ((flags&XBGND) && !flag[FMONITOR]) {
  322. !             signal(SIGINT, SIG_IGN);
  323. !             signal(SIGQUIT, SIG_IGN);
  324. !             if (flag[FTALKING])
  325. !                 signal(SIGTERM, SIG_DFL);
  326.               if (!(flags&XPIPEI)) {
  327.                   i = open("/dev/null", 0);
  328.                   (void) dup2(i, 0);
  329. --- 354,372 ----
  330.           e.oenv = NULL;
  331.           if (flag[FTALKING])
  332.               restoresigs();
  333. !         if ((flags&XBGND) && !flag[FMONITOR])
  334. !         {
  335. ! #ifdef USE_SIGACT
  336. !           sigaction(SIGINT, &Sigact_dfl, NULL);
  337. !           sigaction(SIGQUIT, &Sigact_dfl, NULL);
  338. !           if (flag[FTALKING])
  339. !             sigaction(SIGTERM, &Sigact_dfl, NULL);
  340. ! #else
  341. !           signal(SIGINT, SIG_IGN);
  342. !           signal(SIGQUIT, SIG_IGN);
  343. !           if (flag[FTALKING])
  344. !             signal(SIGTERM, SIG_DFL);
  345. ! #endif
  346.               if (!(flags&XPIPEI)) {
  347.                   i = open("/dev/null", 0);
  348.                   (void) dup2(i, 0);
  349. ***************
  350. *** 312,317 ****
  351. --- 376,389 ----
  352.           for (j = procs; j != NULL; j = j->next)
  353.               j->state = JFREE;
  354.           ttyfd = -1;
  355. + #ifdef JOBS
  356. +         /* is this needed in the child? */
  357. + # ifdef USE_SIGACT
  358. +         sigprocmask(SIG_SETMASK, &sm_default, NULL);
  359. + # else
  360. +         sigsetmask(sm_default);
  361. + # endif
  362. + #endif
  363.           flag[FMONITOR] = flag[FTALKING] = 0;
  364.           cleartraps();
  365.           execute(t, flags|XEXEC); /* no return */
  366. ***************
  367. *** 325,331 ****
  368.           j_current = j->job;
  369.           if (flag[FTALKING])
  370.               j_print(j);
  371. !     } else {        /* sync statement */
  372.           if (!(flags&XPIPE))
  373.               rv = j_waitj(j, 0);
  374.       }
  375. --- 397,412 ----
  376.           j_current = j->job;
  377.           if (flag[FTALKING])
  378.               j_print(j);
  379. !     }
  380. ! #ifdef JOBS
  381. ! # ifdef USE_SIGACT
  382. !     sigprocmask(SIG_SETMASK, &sm_default, NULL);
  383. ! # else
  384. !     sigsetmask(sm_default);
  385. ! # endif
  386. ! #endif
  387. !     if (!(flags&XBGND))
  388. !     {         /* sync statement */
  389.           if (!(flags&XPIPE))
  390.               rv = j_waitj(j, 0);
  391.       }
  392. ***************
  393. *** 353,360 ****
  394. --- 434,445 ----
  395.   #ifdef JOBS
  396.       if (flag[FMONITOR])
  397.       {
  398. + # ifdef USE_SIGACT
  399. +       sigprocmask(SIG_SETMASK, &sm_sigchld, NULL);
  400. + # else
  401.         _TRACE(5, ("j_waitj: sigsetmask(sm_sigchld==0x%x)", sm_sigchld));
  402.         sigsetmask(sm_sigchld);
  403. + # endif
  404.       }
  405.   #endif
  406.       /* wait for all members of pipeline */
  407. ***************
  408. *** 371,383 ****
  409.                  */
  410.                 if (!sigchld_caught)
  411.                 {
  412.                   _TRACE(4, ("j_waitj: sigpause(%d), sigchld_caught==%d", sm_default, sigchld_caught));
  413.                   sigpause(sm_default);
  414.                   _TRACE(4, ("j_waitj: sigpause() returned %d, sigchld_caught==%d", errno, sigchld_caught));
  415.                 }
  416.               }
  417.               else
  418. ! #endif
  419.                   j_sigchld(0);
  420.               /*
  421.                * Children to reap
  422. --- 456,472 ----
  423.                  */
  424.                 if (!sigchld_caught)
  425.                 {
  426. + # ifdef USE_SIGACT
  427. +                 sigsuspend(&sm_default);
  428. + # else
  429.                   _TRACE(4, ("j_waitj: sigpause(%d), sigchld_caught==%d", sm_default, sigchld_caught));
  430.                   sigpause(sm_default);
  431.                   _TRACE(4, ("j_waitj: sigpause() returned %d, sigchld_caught==%d", errno, sigchld_caught));
  432. + # endif /* USE_SIGACT */
  433.                 }
  434.               }
  435.               else
  436. ! #endif /* JOBS */
  437.                   j_sigchld(0);
  438.               /*
  439.                * Children to reap
  440. ***************
  441. *** 398,404 ****
  442.               if (!(j->flags&XPIPEO))
  443.                   rv = 0x80 + WTERMSIG(j->status);
  444.               if (WTERMSIG(j->status) == SIGINT ||
  445. !                 WTERMSIG(j->status) == SIGPIPE && (j->flags&XPIPEO))
  446.                   j->notify = 0;
  447.               if (WTERMSIG(j->status) == SIGINT ||
  448.                   WTERMSIG(j->status) == SIGQUIT)
  449. --- 487,494 ----
  450.               if (!(j->flags&XPIPEO))
  451.                   rv = 0x80 + WTERMSIG(j->status);
  452.               if (WTERMSIG(j->status) == SIGINT ||
  453. !                 (WTERMSIG(j->status) == SIGPIPE &&
  454. !                  (j->flags&XPIPEO)))
  455.                   j->notify = 0;
  456.               if (WTERMSIG(j->status) == SIGINT ||
  457.                   WTERMSIG(j->status) == SIGQUIT)
  458. ***************
  459. *** 441,450 ****
  460.   
  461.     Break:
  462.   #ifdef JOBS
  463. !     if (flag[FMONITOR]) {
  464. !         /* reset shell job control state */
  465. !         sigsetmask(sm_default);
  466. !         tcsetpgrp(ttyfd, our_pgrp);
  467.       }
  468.   #endif
  469.       if (ttysig)
  470. --- 531,545 ----
  471.   
  472.     Break:
  473.   #ifdef JOBS
  474. !     if (flag[FMONITOR])
  475. !     {
  476. !       /* reset shell job control state */
  477. ! # ifdef USE_SIGACT
  478. !       sigprocmask(SIG_SETMASK, &sm_default, NULL);
  479. ! # else
  480. !       sigsetmask(sm_default);
  481. ! # endif
  482. !       tcsetpgrp(ttyfd, our_pgrp);
  483.       }
  484.   #endif
  485.       if (ttysig)
  486. ***************
  487. *** 466,476 ****
  488.       int sig;
  489.   {
  490.       sigchld_caught++;    /* acknowledge it */
  491. - #if defined(_SYSV) && !defined(JOBS)
  492. -     /* non-zero sig means called as handler */
  493. -     /* 5.2 handlers must reinstate themselves */
  494. -     if (sig) signal(SIGCHLD, j_sigchld);
  495. - #endif
  496.   }
  497.   
  498.   /*
  499. --- 561,566 ----
  500. ***************
  501. *** 481,492 ****
  502.   j_reapchld()
  503.   {
  504.       struct tms t0, t1;
  505. ! #ifdef JOBS
  506.       int sm_old;
  507.   
  508.       sm_old = sigblock(0);    /* just get current mask */
  509. - #endif
  510.       _TRACE(5, ("j_reapchld: sm_old==0x%x, sigchld_caught==%d", sm_old, sigchld_caught));
  511.       (void) times(&t0);
  512.   
  513.       do {
  514. --- 571,588 ----
  515.   j_reapchld()
  516.   {
  517.       struct tms t0, t1;
  518. ! #if defined(JOBS)
  519. ! # ifdef USE_SIGACT
  520. !     sigset_t    sm_old;
  521. !     sigprocmask(SIG_SETMASK, NULL, &sm_old);
  522. ! # else
  523.       int sm_old;
  524.   
  525.       sm_old = sigblock(0);    /* just get current mask */
  526.       _TRACE(5, ("j_reapchld: sm_old==0x%x, sigchld_caught==%d", sm_old, sigchld_caught));
  527. + # endif
  528. + #endif
  529.       (void) times(&t0);
  530.   
  531.       do {
  532. ***************
  533. *** 499,504 ****
  534. --- 595,607 ----
  535.           else
  536.   #endif
  537.               pid = wait(&status);
  538. +         if (pid < 0 && errno == ECHILD)
  539. +         {
  540. +           /* no children - what are we doing here? */
  541. +           _TRACE(5, ("j_reapchld: no children"));
  542. +           sigchld_caught = 0;
  543. +           break;
  544. +         }
  545.           if (pid <= 0)    /* return if would block (0) ... */
  546.               break;    /* ... or no children or interrupted (-1) */
  547.           (void) times(&t1);
  548. ***************
  549. *** 534,552 ****
  550. --- 637,674 ----
  551.           j->stime = t1.tms_cstime - t0.tms_cstime;
  552.           t0 = t1;
  553.   #ifdef JOBS
  554. + # ifdef USE_SIGACT
  555. +         sigprocmask(SIG_BLOCK, &sm_sigchld, NULL);
  556. + # else
  557.           sigblock(sm_sigchld);
  558. + # endif
  559.   #endif
  560.           if (--sigchld_caught < 0) /* reduce the count */
  561.             sigchld_caught = 0;
  562.   #ifdef JOBS
  563. + # ifdef USE_SIGACT
  564. +         sigprocmask(SIG_SETMASK, &sm_old, NULL);
  565. + # else
  566.           _TRACE(5, ("j_reapchld: j->proc==%d, j->com=='%s', j->state==0x%hx, j->status==0x%x, j->notify==%hd", j->proc, j->com, j->state, j->status, j->notify));
  567.           sigsetmask(sm_old); /* restore old mask */
  568. + # endif
  569.   #endif
  570. +         
  571.   #ifdef JOBS
  572.       } while (flag[FMONITOR]);
  573.   #else
  574.       } while (0);        /* only once if wait()ing */
  575.   #endif
  576. + /*
  577. +  * this should be safe
  578. +  */
  579. + #if defined(_SYSV) && !defined(JOBS) && !defined(USE_SIGACT)
  580. +     signal(SIGCHLD, j_sigchld);
  581. + #if 0
  582. +     /* why was this here??? */
  583. +     signal(SIGCLD, SIG_DFL);
  584. + #endif
  585. + #endif
  586.   }
  587.   
  588.   j_reap()
  589. ***************
  590. *** 553,559 ****
  591.   {
  592.     if (sigchld_caught)
  593.       j_reapchld();
  594. ! #if defined(_SYSV) && !defined(JOBS)
  595.       signal(SIGCHLD, j_sigchld);
  596.       signal(SIGCLD, SIG_DFL);
  597.   #endif
  598. --- 675,684 ----
  599.   {
  600.     if (sigchld_caught)
  601.       j_reapchld();
  602. ! /*
  603. !  * now done in j_reapchld()
  604. !  */
  605. ! #if 0 && defined(_SYSV) && !defined(JOBS) && !defined(USE_SIGACT)
  606.       signal(SIGCHLD, j_sigchld);
  607.       signal(SIGCLD, SIG_DFL);
  608.   #endif
  609. *** sh/lex.c.old    Sat Apr 25 17:44:30 1992
  610. --- sh/lex.c    Sat Apr 25 18:36:52 1992
  611. ***************
  612. *** 3,10 ****
  613.    */
  614.   
  615.   #ifndef lint
  616. ! static char *RCSid = "$Id: lex.c,v 3.6 89/03/27 15:51:20 egisin Exp $";
  617. ! static char *sccs_id = "@(#)lex.c    1.4 91/11/22 22:53:17 (sjg)";
  618.   #endif
  619.   
  620.   #include "stdh.h"
  621. --- 3,9 ----
  622.    */
  623.   
  624.   #ifndef lint
  625. ! static char *RCSid = "$Id: lex.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  626.   #endif
  627.   
  628.   #include "stdh.h"
  629. ***************
  630. *** 13,21 ****
  631.   #include <unistd.h>
  632.   #include <assert.h>
  633.   #include "sh.h"
  634. - #include "lex.h"
  635. - #include "tree.h"
  636. - #include "table.h"
  637.   #include "expand.h"
  638.   
  639.       int    ttyfd = -1;        /* tty fd for edit and jobs */
  640. --- 12,17 ----
  641. ***************
  642. *** 29,36 ****
  643.   
  644.   static    int    expanding_alias;
  645.   static    int    alias;
  646. - static    int    getsc_ ARGS((void));
  647.   
  648.   /* optimized getsc_() */
  649.   #define    getsc()    ((*source->str != 0) ? *source->str++ : getsc_())
  650.   #define    ungetsc() (source->str--)
  651. --- 25,34 ----
  652.   
  653.   static    int    expanding_alias;
  654.   static    int    alias;
  655.   
  656. + static void     readhere    ARGS((struct ioword *iop));
  657. + static int      getsc_      ARGS((void));
  658.   /* optimized getsc_() */
  659.   #define    getsc()    ((*source->str != 0) ? *source->str++ : getsc_())
  660.   #define    ungetsc() (source->str--)
  661. ***************
  662. *** 87,93 ****
  663.   
  664.       /* collect non-special or quoted characters to form word */
  665.       for (*statep = state = istate;
  666. !          !((c = getsc()) == 0 || state == SBASE && ctype(c, C_LEX1)); ) {
  667.           Xcheck(ws, wp);
  668.           switch (state) {
  669.             case SBASE:
  670. --- 85,91 ----
  671.   
  672.       /* collect non-special or quoted characters to form word */
  673.       for (*statep = state = istate;
  674. !          !((c = getsc()) == 0 || (state == SBASE && ctype(c, C_LEX1))); ) {
  675.           Xcheck(ws, wp);
  676.           switch (state) {
  677.             case SBASE:
  678. ***************
  679. *** 464,470 ****
  680.   
  681.   void
  682.   yyerror(msg)
  683. !     Const char *msg;
  684.   {
  685.       yynerrs++;
  686.       while (source->type == SALIAS) /* pop aliases */
  687. --- 462,468 ----
  688.   
  689.   void
  690.   yyerror(msg)
  691. !     const char *msg;
  692.   {
  693.       yynerrs++;
  694.       while (source->type == SALIAS) /* pop aliases */
  695. ***************
  696. *** 501,507 ****
  697.       register Source *s = source;
  698.       register int c;
  699.       extern void    mprint();
  700.       while ((c = *s->str++) == 0) {
  701.           s->str = NULL;        /* return 0 for EOF by default */
  702.           switch (s->type) {
  703. --- 499,505 ----
  704.       register Source *s = source;
  705.       register int c;
  706.       extern void    mprint();
  707. !     
  708.       while ((c = *s->str++) == 0) {
  709.           s->str = NULL;        /* return 0 for EOF by default */
  710.           switch (s->type) {
  711. ***************
  712. *** 521,526 ****
  713. --- 519,533 ----
  714.               mprint();
  715.               pprompt(prompt);
  716.               flushshf(1);    flushshf(2);
  717. +             /*
  718. +              * This allows the arival of a SIGCHLD 
  719. +              * to not disturb us until we are ready. 
  720. +              * BSD and other systems that 
  721. +              * automatically rety a read after an 
  722. +              * interrupt don't need this but it 
  723. +              * doesn't do any harm either.
  724. +              */
  725. +               retry:
  726.   #ifdef EDIT
  727.   #ifdef EMACS
  728.               if (flag[FEMACS])
  729. ***************
  730. *** 534,539 ****
  731. --- 541,550 ----
  732.   #endif
  733.   #endif
  734.                   c = read(ttyfd, line, LINE);
  735. +             if (c < 0 && sigchld_caught)
  736. +             {
  737. +               goto retry;
  738. +             }
  739.               if (c < 0)    /* read error */
  740.                   c = 0;
  741.               line[c] = '\0';
  742. *** sh/lex.h.old    Sat Apr 25 17:41:36 1992
  743. --- sh/lex.h    Sat Apr 25 18:36:59 1992
  744. ***************
  745. *** 2,8 ****
  746.    * Source input, lexer and parser
  747.    */
  748.   
  749. ! /* Id: /u/egisin/sh/src/RCS/lex.h,v 3.3 89/01/28 15:29:42 egisin Exp $ */
  750.   
  751.   #define    IDENT    64
  752.   
  753. --- 2,8 ----
  754.    * Source input, lexer and parser
  755.    */
  756.   
  757. ! /* $Id: lex.h,v 1.2 1992/04/25 08:33:28 sjg Exp $ */
  758.   
  759.   #define    IDENT    64
  760.   
  761. ***************
  762. *** 99,105 ****
  763.   Extern    char    ident [IDENT+1];
  764.   
  765.   extern    int    yylex ARGS((int flags));
  766. ! extern    void    yyerror ARGS((Const char *msg));
  767.   
  768.   #define    HISTORY    100        /* size of saved history */
  769.   
  770. --- 99,105 ----
  771.   Extern    char    ident [IDENT+1];
  772.   
  773.   extern    int    yylex ARGS((int flags));
  774. ! extern    void    yyerror ARGS((const char *msg));
  775.   
  776.   #define    HISTORY    100        /* size of saved history */
  777.   
  778. *** sh/mail.c.old    Sat Apr 25 17:44:30 1992
  779. --- sh/mail.c    Sat Apr 25 18:37:02 1992
  780. ***************
  781. *** 3,9 ****
  782.    * John R. MacMillan
  783.    */
  784.   #ifndef lint
  785. ! static char *sccs_id = "@(#)mail.c    1.2 91/11/22 22:53:47 (sjg)";
  786.   #endif
  787.   
  788.   #include "stdh.h"
  789. --- 3,9 ----
  790.    * John R. MacMillan
  791.    */
  792.   #ifndef lint
  793. ! static char *RCSid = "$Id: mail.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  794.   #endif
  795.   
  796.   #include "stdh.h"
  797. ***************
  798. *** 12,24 ****
  799.   #include <setjmp.h>
  800.   #include <sys/stat.h>
  801.   #include "sh.h"
  802. - #include "table.h"
  803.   
  804. - Void    mcheck();    /* check for new mail */
  805. - Void    mbset();    /* set $MAIL */
  806. - Void    mpset();    /* set $MAILPATH */
  807. - Void    mprint();    /* print a list of mail messages */
  808.   #define MBMESSAGE    "you have mail in $_"
  809.   
  810.   typedef struct mbox {
  811. --- 12,18 ----
  812. ***************
  813. *** 43,53 ****
  814.   static mbox_t  mbox = { NULL, NULL, NULL, 0 };
  815.   static long    mlastchkd = 0;    /* when mail was last checked */
  816.   static struct mailmsg *mmsgs = NULL;    /* Messages to be printed */
  817. ! static Void    munset();        /* free mlist and mval */
  818.   static mbox_t  *mballoc();        /* allocate a new mbox */
  819. ! static Void    maddmsg();
  820.   
  821. ! Void
  822.   mcheck()
  823.   {
  824.       register mbox_t    *mbp;
  825. --- 37,52 ----
  826.   static mbox_t  mbox = { NULL, NULL, NULL, 0 };
  827.   static long    mlastchkd = 0;    /* when mail was last checked */
  828.   static struct mailmsg *mmsgs = NULL;    /* Messages to be printed */
  829. ! #if 0
  830. ! static void    munset();        /* free mlist and mval */
  831.   static mbox_t  *mballoc();        /* allocate a new mbox */
  832. ! static void    maddmsg();
  833. ! #endif
  834. ! static void     munset      ARGS((mbox_t *mlist));
  835. ! static mbox_t * mballoc     ARGS((char *p, char *m));
  836. ! static void     maddmsg     ARGS((mbox_t *mbp));
  837.   
  838. ! void
  839.   mcheck()
  840.   {
  841.       register mbox_t    *mbp;
  842. ***************
  843. *** 93,99 ****
  844.       }
  845.   }
  846.   
  847. ! Void
  848.   mbset(p)
  849.       register char    *p;
  850.   {
  851. --- 92,98 ----
  852.       }
  853.   }
  854.   
  855. ! void
  856.   mbset(p)
  857.       register char    *p;
  858.   {
  859. ***************
  860. *** 100,106 ****
  861.       struct stat    stbuf;
  862.   
  863.       if (mbox.mb_msg)
  864. !         afree((Void *)mbox.mb_msg, APERM);
  865.       mbox.mb_path = p;
  866.       mbox.mb_msg = NULL;
  867.       if (stat(p,&stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFREG)
  868. --- 99,105 ----
  869.       struct stat    stbuf;
  870.   
  871.       if (mbox.mb_msg)
  872. !         afree((void *)mbox.mb_msg, APERM);
  873.       mbox.mb_path = p;
  874.       mbox.mb_msg = NULL;
  875.       if (stat(p,&stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFREG)
  876. ***************
  877. *** 109,115 ****
  878.           mbox.mb_size = 0;
  879.   }
  880.   
  881. ! Void
  882.   mpset(mptoparse)
  883.       register char    *mptoparse;
  884.   {
  885. --- 108,114 ----
  886.           mbox.mb_size = 0;
  887.   }
  888.   
  889. ! void
  890.   mpset(mptoparse)
  891.       register char    *mptoparse;
  892.   {
  893. ***************
  894. *** 133,139 ****
  895.       }
  896.   }
  897.   
  898. ! static Void
  899.   munset(mlist)
  900.   register mbox_t    *mlist;
  901.   {
  902. --- 132,138 ----
  903.       }
  904.   }
  905.   
  906. ! static void
  907.   munset(mlist)
  908.   register mbox_t    *mlist;
  909.   {
  910. ***************
  911. *** 143,150 ****
  912.           mbp = mlist;
  913.           mlist = mbp->mb_next;
  914.           if (!mlist)
  915. !             afree((Void *)mbp->mb_path, APERM);
  916. !         afree((Void *)mbp, APERM);
  917.       }
  918.   }
  919.   
  920. --- 142,149 ----
  921.           mbp = mlist;
  922.           mlist = mbp->mb_next;
  923.           if (!mlist)
  924. !             afree((void *)mbp->mb_path, APERM);
  925. !         afree((void *)mbp, APERM);
  926.       }
  927.   }
  928.   
  929. ***************
  930. *** 169,175 ****
  931.       return(mbp);
  932.   }
  933.   
  934. ! Void
  935.   mprint()
  936.   {
  937.       struct mailmsg *mm;
  938. --- 168,174 ----
  939.       return(mbp);
  940.   }
  941.   
  942. ! void
  943.   mprint()
  944.   {
  945.       struct mailmsg *mm;
  946. ***************
  947. *** 177,189 ****
  948.       while ((mm = mmsgs) != NULL) {
  949.           shellf( "%s\n", mm->msg );
  950.           fflush(shlout);
  951. !         afree((Void *)mm->msg, APERM);
  952.           mmsgs = mm->next;
  953. !         afree((Void *)mm, APERM);
  954.       }
  955.   }
  956.   
  957. ! static Void
  958.   maddmsg( mbp )
  959.   mbox_t    *mbp;
  960.   {
  961. --- 176,188 ----
  962.       while ((mm = mmsgs) != NULL) {
  963.           shellf( "%s\n", mm->msg );
  964.           fflush(shlout);
  965. !         afree((void *)mm->msg, APERM);
  966.           mmsgs = mm->next;
  967. !         afree((void *)mm, APERM);
  968.       }
  969.   }
  970.   
  971. ! static void
  972.   maddmsg( mbp )
  973.   mbox_t    *mbp;
  974.   {
  975. *** sh/main.c.old    Sat Apr 25 17:44:31 1992
  976. --- sh/main.c    Sat Apr 25 18:31:56 1992
  977. ***************
  978. *** 3,10 ****
  979.    */
  980.   
  981.   #ifndef lint
  982. ! static char *RCSid = "$Id: main.c,v 3.3 89/03/27 15:51:39 egisin Exp $";
  983. ! static char *sccs_id = "@(#)main.c    1.6 91/11/25 13:33:06 (sjg)";
  984.   #endif
  985.   
  986.   #define    Extern                /* define Externs in sh.h */
  987. --- 3,9 ----
  988.    */
  989.   
  990.   #ifndef lint
  991. ! static char *RCSid = "$Id: main.c,v 1.3 1992/04/25 08:29:52 sjg Exp $";
  992.   #endif
  993.   
  994.   #define    Extern                /* define Externs in sh.h */
  995. ***************
  996. *** 17,27 ****
  997.   #include <setjmp.h>
  998.   #include <time.h>
  999.   #include "sh.h"
  1000. - #include "lex.h"
  1001. - #include "tree.h"
  1002. - #include "table.h"
  1003.   
  1004. ! #ifndef HAVE_REMOVE
  1005.   #define remove(x)    unlink(x)
  1006.   #endif
  1007.   
  1008. --- 16,23 ----
  1009.   #include <setjmp.h>
  1010.   #include <time.h>
  1011.   #include "sh.h"
  1012.   
  1013. ! #if !defined(HAVE_REMOVE) && !defined(remove)
  1014.   #define remove(x)    unlink(x)
  1015.   #endif
  1016.   
  1017. ***************
  1018. *** 39,45 ****
  1019.   
  1020.   static    char    initifs [] = "IFS= \t\n"; /* must be R/W */
  1021.   
  1022. ! static    Const    char   initsubs [] = 
  1023.   #ifdef sun                /* sun's don't have a real /bin */
  1024.     "${SHELL:=/bin/sh} ${PATH:=/usr/bin:/usr/ucb:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${MAILCHECK:=600}";
  1025.   #else
  1026. --- 35,41 ----
  1027.   
  1028.   static    char    initifs [] = "IFS= \t\n"; /* must be R/W */
  1029.   
  1030. ! static    const    char   initsubs [] = 
  1031.   #ifdef sun                /* sun's don't have a real /bin */
  1032.     "${SHELL:=/bin/sh} ${PATH:=/usr/bin:/usr/ucb:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${MAILCHECK:=600}";
  1033.   #else
  1034. ***************
  1035. *** 46,52 ****
  1036.     "${SHELL:=/bin/sh} ${PATH:=/bin:/usr/bin:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${MAILCHECK:=600}";
  1037.   #endif
  1038.   
  1039. ! static    Const    char *initcoms [] = {
  1040.       "cd", ".", NULL,        /* set up $PWD */
  1041.       "typeset", "-x", "SHELL", "PATH", "HOME", NULL,
  1042.       "typeset", "-r", "PWD", "OLDPWD", NULL,
  1043. --- 42,48 ----
  1044.     "${SHELL:=/bin/sh} ${PATH:=/bin:/usr/bin:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${MAILCHECK:=600}";
  1045.   #endif
  1046.   
  1047. ! static    const    char *initcoms [] = {
  1048.       "cd", ".", NULL,        /* set up $PWD */
  1049.       "typeset", "-x", "SHELL", "PATH", "HOME", NULL,
  1050.       "typeset", "-r", "PWD", "OLDPWD", NULL,
  1051. ***************
  1052. *** 78,85 ****
  1053. --- 74,83 ----
  1054.       Trace_level = 0;
  1055.       break;
  1056.     }
  1057. + #if defined(_SYSV) && !defined(USE_SIGACT)
  1058.     if (sig > 0)
  1059.       (void) signal(sig, set_TraceLev);
  1060. + #endif
  1061.     return;
  1062.   }
  1063.   #endif
  1064. ***************
  1065. *** 92,97 ****
  1066. --- 90,96 ----
  1067.       register int i;
  1068.       register char *arg;
  1069.       int cflag = 0, qflag = 0, fflag = 0;
  1070. +     int argi;
  1071.       char *name;
  1072.       register Source *s;
  1073.       register struct block *l = &globals;
  1074. ***************
  1075. *** 99,104 ****
  1076. --- 98,116 ----
  1077.       extern char ksh_version [];
  1078.       extern time_t time();
  1079.   
  1080. + #ifdef USE_SIGACT
  1081. +     sigemptyset(&Sigact.sa_mask);
  1082. +     sigemptyset(&Sigact_dfl.sa_mask);
  1083. +     sigemptyset(&Sigact_ign.sa_mask);
  1084. +     sigemptyset(&Sigact_trap.sa_mask);
  1085. +     Sigact.sa_flags = 0;
  1086. +     Sigact_dfl.sa_flags = 0;
  1087. +     Sigact_ign.sa_flags = 0;
  1088. +     Sigact_trap.sa_flags = 0;
  1089. +     Sigact_dfl.sa_handler = SIG_DFL;
  1090. +     Sigact_ign.sa_handler = SIG_IGN;
  1091. +     Sigact_trap.sa_handler = trapsig;
  1092. + #endif
  1093.       ainit(&aperm);        /* initialize permanent Area */
  1094.   
  1095.   #ifndef F_SETFD
  1096. ***************
  1097. *** 133,140 ****
  1098. --- 145,158 ----
  1099.       typeset(ksh_version, 0, 0); /* RDONLY */
  1100.   
  1101.   #ifdef USE_TRACE
  1102. + #ifdef USE_SIGACT
  1103. +     Sigact.sa_handler = set_TraceLev;
  1104. +     sigaction(SIGUSR1, &Sigact, NULL);
  1105. +     sigaction(SIGUSR2, &Sigact, NULL);
  1106. + #else
  1107.       (void) signal(SIGUSR1, set_TraceLev);
  1108.       (void) signal(SIGUSR2, set_TraceLev);
  1109. + #endif
  1110.       _TRACE(0, ("Traces enabled.")); /* allow _TRACE to setup */
  1111.   #endif
  1112.   
  1113. ***************
  1114. *** 167,184 ****
  1115.       s = pushs(SFILE);
  1116.       s->u.file = stdin;
  1117.       cflag = 0;
  1118. !     name = *argv++;
  1119.   
  1120.       /* what a bloody mess */
  1121. !     if (--argc >= 1) {
  1122. !         if (argv[0][0] == '-' && argv[0][1] != '\0') {
  1123. !             for (arg = argv[0]+1; *arg; arg++)
  1124.                   switch (*arg) {
  1125.                     case 'c':
  1126.                       cflag = 1;
  1127. !                     if (--argc > 0) {
  1128.                           s->type = SSTRING;
  1129. !                         s->str = *++argv;
  1130.                       }
  1131.                       break;
  1132.       
  1133. --- 185,202 ----
  1134.       s = pushs(SFILE);
  1135.       s->u.file = stdin;
  1136.       cflag = 0;
  1137. !     name = *argv;
  1138.   
  1139.       /* what a bloody mess */
  1140. !     if ((argi = 1) < argc) {
  1141. !         if (argv[argi][0] == '-' && argv[argi][1] != '\0') {
  1142. !             for (arg = argv[argi++]+1; *arg; arg++) {
  1143.                   switch (*arg) {
  1144.                     case 'c':
  1145.                       cflag = 1;
  1146. !                     if (argi < argc) {
  1147.                           s->type = SSTRING;
  1148. !                         s->str = argv[argi++];
  1149.                       }
  1150.                       break;
  1151.       
  1152. ***************
  1153. *** 190,205 ****
  1154.                       if (*arg>='a' && *arg<='z')
  1155.                           flag[FLAG(*arg)]++;
  1156.                   }
  1157. !         } else {
  1158. !             argv--;
  1159. !             argc++;
  1160.           }
  1161. !         if (s->type == SFILE && --argc > 0 && !flag[FSTDIN]) {
  1162. !             if ((s->u.file = fopen(*++argv, "r")) == NULL)
  1163. !                 errorf("%s: cannot open\n", *argv);
  1164.               fflag = 1;
  1165. -             s->file = name = *argv;
  1166. -             argc--;
  1167.               fileno(s->u.file) = savefd(fileno(s->u.file));
  1168.               setvbuf(s->u.file, (char *)NULL, _IOFBF, BUFSIZ);
  1169.           }
  1170. --- 208,220 ----
  1171.                       if (*arg>='a' && *arg<='z')
  1172.                           flag[FLAG(*arg)]++;
  1173.                   }
  1174. !             }
  1175.           }
  1176. !         if (s->type == SFILE && argi < argc && !flag[FSTDIN]) {
  1177. !             s->file = name = argv[argi++];
  1178. !             if ((s->u.file = fopen(name, "r")) == NULL)
  1179. !                 errorf("%s: cannot open\n", name);
  1180.               fflag = 1;
  1181.               fileno(s->u.file) = savefd(fileno(s->u.file));
  1182.               setvbuf(s->u.file, (char *)NULL, _IOFBF, BUFSIZ);
  1183.           }
  1184. ***************
  1185. *** 216,225 ****
  1186.       if (s->type == STTY) {
  1187.           ttyfd = fcntl(0, F_DUPFD, FDBASE);
  1188.   #ifdef F_SETFD
  1189. !         (void) fcntl(ttyfd, F_SETFD, FD_CLEXEC);
  1190.   #else
  1191.           (void) fd_clexec(ttyfd);
  1192.   #endif
  1193.   #ifdef EMACS
  1194.           x_init_emacs();
  1195.   #endif
  1196. --- 231,243 ----
  1197.       if (s->type == STTY) {
  1198.           ttyfd = fcntl(0, F_DUPFD, FDBASE);
  1199.   #ifdef F_SETFD
  1200. !         (void) fcntl(ttyfd, F_SETFD, 1);
  1201.   #else
  1202.           (void) fd_clexec(ttyfd);
  1203.   #endif
  1204. + #if defined(EMACS) || defined(VI)
  1205. +         init_editmode();
  1206. + #endif
  1207.   #ifdef EMACS
  1208.           x_init_emacs();
  1209.   #endif
  1210. ***************
  1211. *** 231,238 ****
  1212.       if (!qflag)
  1213.           ignoresig(SIGQUIT);
  1214.   
  1215. !     l->argv = argv;
  1216. !     l->argc = argc;
  1217.       l->argv[0] = name;
  1218.       resetopts();
  1219.   
  1220. --- 249,256 ----
  1221.       if (!qflag)
  1222.           ignoresig(SIGQUIT);
  1223.   
  1224. !     l->argv = &argv[argi];
  1225. !     l->argc = argc - argi;
  1226.       l->argv[0] = name;
  1227.       resetopts();
  1228.   
  1229. ***************
  1230. *** 247,257 ****
  1231.       if (*arg != '\0')
  1232.           (void) include(arg);
  1233.   
  1234. !     if (flag[FTALKING]) {
  1235. !         signal(SIGTERM, trapsig);
  1236. !         ignoresig(SIGINT);
  1237.       } else
  1238. !         flag[FHASHALL] = 1;
  1239.   
  1240.   #ifdef JOBS            /* todo: could go before includes? */
  1241.       if (s->type == STTY) {
  1242. --- 265,280 ----
  1243.       if (*arg != '\0')
  1244.           (void) include(arg);
  1245.   
  1246. !     if (flag[FTALKING])
  1247. !     {
  1248. ! #ifdef USE_SIGACT
  1249. !       sigaction(SIGTERM, &Sigact_trap, NULL);
  1250. ! #else
  1251. !       signal(SIGTERM, trapsig);
  1252. ! #endif
  1253. !       ignoresig(SIGINT);
  1254.       } else
  1255. !       flag[FHASHALL] = 1;
  1256.   
  1257.   #ifdef JOBS            /* todo: could go before includes? */
  1258.       if (s->type == STTY) {
  1259. ***************
  1260. *** 259,267 ****
  1261.           j_change();
  1262.       }
  1263.   #endif
  1264.       argc = shell(s);
  1265.       leave(argc);
  1266.   }
  1267.   
  1268.   int
  1269. --- 282,294 ----
  1270.           j_change();
  1271.       }
  1272.   #endif
  1273. !     if (flag[FTALKING])
  1274. !     {
  1275. !       hist_init(s);
  1276. !     }
  1277.       argc = shell(s);
  1278.       leave(argc);
  1279. +     return 0;
  1280.   }
  1281.   
  1282.   int
  1283. ***************
  1284. *** 308,316 ****
  1285.       Source *s;        /* input source */
  1286.   {
  1287.       struct op *t;
  1288. !     Volatile int attempts = 13;
  1289. !     Volatile int wastty;
  1290. !     Volatile int reading = 0;
  1291.       extern void mcheck();
  1292.   
  1293.       newenv(E_PARSE);
  1294. --- 335,343 ----
  1295.       Source *s;        /* input source */
  1296.   {
  1297.       struct op *t;
  1298. !     volatile int attempts = 13;
  1299. !     volatile int wastty;
  1300. !     volatile int reading = 0;
  1301.       extern void mcheck();
  1302.   
  1303.       newenv(E_PARSE);
  1304. ***************
  1305. *** 329,335 ****
  1306.           if (trap)
  1307.               runtraps();
  1308.           if (flag[FTALKING])
  1309. !             signal(SIGINT, trapsig);
  1310.   
  1311.           if (s->next == NULL)
  1312.               s->echo = flag[FVERBOSE];
  1313. --- 356,368 ----
  1314.           if (trap)
  1315.               runtraps();
  1316.           if (flag[FTALKING])
  1317. !         {
  1318. ! #ifdef USE_SIGACT
  1319. !           sigaction(SIGINT, &Sigact_trap, NULL);
  1320. ! #else
  1321. !           signal(SIGINT, trapsig);
  1322. ! #endif
  1323. !         }
  1324.   
  1325.           if (s->next == NULL)
  1326.               s->echo = flag[FVERBOSE];
  1327. ***************
  1328. *** 360,366 ****
  1329.   
  1330.           reclaim();
  1331.       }
  1332. !   Error:
  1333.       quitenv();
  1334.       return exstat;
  1335.   }
  1336. --- 393,399 ----
  1337.   
  1338.           reclaim();
  1339.       }
  1340. !     /* Error: */
  1341.       quitenv();
  1342.       return exstat;
  1343.   }
  1344. ***************
  1345. *** 372,377 ****
  1346. --- 405,414 ----
  1347.       if (e.type == E_TCOM && e.oenv != NULL)    /* exec'd command */
  1348.           unwind();
  1349.       runtrap(&sigtraps[0]);
  1350. +     if (flag[FTALKING])
  1351. +     {
  1352. +       hist_finish();
  1353. +     }
  1354.       j_exit();
  1355.       exit(rv);
  1356.       /* NOTREACHED */
  1357. ***************
  1358. *** 431,436 ****
  1359. --- 468,474 ----
  1360.               restfd(fd, e.savefd[fd]);
  1361.       reclaim();
  1362.       e = *ep;
  1363. +     afree(ep, ATEMP);
  1364.   }
  1365.   
  1366.   /* remove temp files and free ATEMP Area */
  1367. ***************
  1368. *** 448,454 ****
  1369.   void
  1370.   aerror(ap, msg)
  1371.       Area *ap;
  1372. !     Const char *msg;
  1373.   {
  1374.       errorf("alloc internal error: %s\n", msg);
  1375.   }
  1376. --- 486,492 ----
  1377.   void
  1378.   aerror(ap, msg)
  1379.       Area *ap;
  1380. !     const char *msg;
  1381.   {
  1382.       errorf("alloc internal error: %s\n", msg);
  1383.   }
  1384. *** sh/misc.c.old    Sat Apr 25 17:44:31 1992
  1385. --- sh/misc.c    Sat Apr 25 18:37:07 1992
  1386. ***************
  1387. *** 3,10 ****
  1388.    */
  1389.   
  1390.   #ifndef lint
  1391. ! static char *RCSid = "$Id: misc.c,v 3.2 89/03/27 15:51:44 egisin Exp $";
  1392. ! static char *sccs_id = "@(#)misc.c    1.2 91/11/22 22:53:50 (sjg)";
  1393.   #endif
  1394.   
  1395.   #include "stdh.h"
  1396. --- 3,9 ----
  1397.    */
  1398.   
  1399.   #ifndef lint
  1400. ! static char *RCSid = "$Id: misc.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  1401.   #endif
  1402.   
  1403.   #include "stdh.h"
  1404. ***************
  1405. *** 21,32 ****
  1406.   
  1407.   char ctypes [UCHAR_MAX+1];    /* type bits for unsigned char */
  1408.   
  1409.   /*
  1410.    * Fast character classes
  1411.    */
  1412.   void
  1413.   setctypes(s, t)
  1414. !     register Const char *s;
  1415.       register int t;
  1416.   {
  1417.       register int i;
  1418. --- 20,33 ----
  1419.   
  1420.   char ctypes [UCHAR_MAX+1];    /* type bits for unsigned char */
  1421.   
  1422. + static char *   cclass      ARGS((char *p, int sub));
  1423.   /*
  1424.    * Fast character classes
  1425.    */
  1426.   void
  1427.   setctypes(s, t)
  1428. !     register /* const */ char *s;
  1429.       register int t;
  1430.   {
  1431.       register int i;
  1432. ***************
  1433. *** 119,125 ****
  1434.    */
  1435.   int
  1436.   option(n)
  1437. !     Const char *n;
  1438.   {
  1439.       register struct option *op;
  1440.   
  1441. --- 120,126 ----
  1442.    */
  1443.   int
  1444.   option(n)
  1445. !     const char *n;
  1446.   {
  1447.       register struct option *op;
  1448.   
  1449. ***************
  1450. *** 277,283 ****
  1451.               p++;
  1452.           } else
  1453.               d = c;
  1454. !         if (c == sub || c <= sub && sub <= d)
  1455.               found = 1;
  1456.       } while (*++p != ']');
  1457.   
  1458. --- 278,284 ----
  1459.               p++;
  1460.           } else
  1461.               d = c;
  1462. !         if (c == sub || (c <= sub && sub <= d))
  1463.               found = 1;
  1464.       } while (*++p != ']');
  1465.   
  1466. ***************
  1467. *** 292,298 ****
  1468.   
  1469.   void
  1470.   qsortp(base, n, f)
  1471. !     Void **base;        /* base address */
  1472.       size_t n;        /* elements */
  1473.       int (*f)();        /* compare function */
  1474.   {
  1475. --- 293,299 ----
  1476.   
  1477.   void
  1478.   qsortp(base, n, f)
  1479. !     void **base;        /* base address */
  1480.       size_t n;        /* elements */
  1481.       int (*f)();        /* compare function */
  1482.   {
  1483. ***************
  1484. *** 300,317 ****
  1485.   }
  1486.   
  1487.   #define    swap2(a, b)    {\
  1488. !     register Void *t; t = *(a); *(a) = *(b); *(b) = t;\
  1489.   }
  1490.   #define    swap3(a, b, c)    {\
  1491. !     register Void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\
  1492.   }
  1493.   
  1494.   qsort1(base, lim, f)
  1495. !     Void **base, **lim;
  1496.       int (*f)();
  1497.   {
  1498. !     register Void **i, **j;
  1499. !     register Void **lptr, **hptr;
  1500.       size_t n;
  1501.       int c;
  1502.   
  1503. --- 301,318 ----
  1504.   }
  1505.   
  1506.   #define    swap2(a, b)    {\
  1507. !     register void *t; t = *(a); *(a) = *(b); *(b) = t;\
  1508.   }
  1509.   #define    swap3(a, b, c)    {\
  1510. !     register void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\
  1511.   }
  1512.   
  1513.   qsort1(base, lim, f)
  1514. !     void **base, **lim;
  1515.       int (*f)();
  1516.   {
  1517. !     register void **i, **j;
  1518. !     register void **lptr, **hptr;
  1519.       size_t n;
  1520.       int c;
  1521.   
  1522. ***************
  1523. *** 378,389 ****
  1524.   
  1525.   int
  1526.   xstrcmp(p1, p2)
  1527. !     Void *p1, *p2;
  1528.   {
  1529.       return (strcmp((char *)p1, (char *)p2));
  1530.   }
  1531.   
  1532. ! Void
  1533.   cleanpath(pwd, dir, clean)
  1534.       char *pwd, *dir, *clean;
  1535.   {
  1536. --- 379,390 ----
  1537.   
  1538.   int
  1539.   xstrcmp(p1, p2)
  1540. !     void *p1, *p2;
  1541.   {
  1542.       return (strcmp((char *)p1, (char *)p2));
  1543.   }
  1544.   
  1545. ! void
  1546.   cleanpath(pwd, dir, clean)
  1547.       char *pwd, *dir, *clean;
  1548.   {
  1549. ***************
  1550. *** 396,402 ****
  1551.           s = pwd;
  1552.           while (*d++ = *s++)
  1553.               ;
  1554. !         *(d - 1) = '/';
  1555.       }
  1556.   
  1557.       s = dir;
  1558. --- 397,406 ----
  1559.           s = pwd;
  1560.           while (*d++ = *s++)
  1561.               ;
  1562. !         if (d >= clean + 2 && *(d - 2) == '/')
  1563. !             d--;
  1564. !         else
  1565. !             *(d - 1) = '/';
  1566.       }
  1567.   
  1568.       s = dir;
  1569. *** /dev/null    Sat Apr 25 07:00:06 1992
  1570. --- sh/patchlevel.h    Sat Apr 25 18:24:54 1992
  1571. ***************
  1572. *** 0 ****
  1573. --- 1,6 ----
  1574. + /*
  1575. +  * PD KSH
  1576. +  * $Id: patchlevel.h,v 4.3 1992/04/25 08:24:42 sjg Exp $
  1577. +  */
  1578. + #define VERSION        4
  1579. + #define PATCHLEVEL    3
  1580.  
  1581. exit 0 # Just in case...
  1582.