home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume29 / zsh2.2 / part09 < prev    next >
Text File  |  1992-05-13  |  50KB  |  2,318 lines

  1. Newsgroups: comp.sources.misc
  2. From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  3. Subject:  v29i105:  zsh2.2 - The Z shell, Part09/17
  4. Message-ID: <1992May13.160404.9847@sparky.imd.sterling.com>
  5. X-Md4-Signature: d245b6fdbcbd95f7f7f27301a0db0e57
  6. Date: Wed, 13 May 1992 16:04:04 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  10. Posting-number: Volume 29, Issue 105
  11. Archive-name: zsh2.2/part09
  12. Environment: BSD
  13. Supersedes: zsh2.1: Volume 24, Issue 1-19
  14.  
  15. #!/bin/sh
  16. # this is aa.09 (part 9 of zsh2.2)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file zsh2.2/src/hist.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 9; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping zsh2.2/src/hist.c'
  34. else
  35. echo 'x - continuing file zsh2.2/src/hist.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.2/src/hist.c' &&
  37. X        if (hlastw == hptr)
  38. X            zerr("hungetc attempted at buffer start",NULL,0);
  39. X        else {
  40. X            hptr--;
  41. X            if (*hptr == '!' && unset(NOBANGHIST)) hptr--;
  42. X        }
  43. X    }
  44. X    hungetch(c);
  45. X}
  46. X
  47. Xvoid hungetch(c) /**/
  48. Xint c;
  49. X{
  50. X    if (lexstop)
  51. X        return;
  52. X    if (inbufct == inbufsz)
  53. X        {
  54. X        hungets(" ");
  55. X        *inbufptr = c;
  56. X        }
  57. X    else
  58. X        {
  59. X        *--inbufptr = c;
  60. X        inbufct++;
  61. X        }
  62. X}
  63. X
  64. X/* begin reading a string */
  65. X
  66. Xvoid strinbeg() /**/
  67. X{
  68. X    strin = 1;
  69. X    hbegin();
  70. X    lexinit();
  71. X}
  72. X
  73. X/* done reading a string */
  74. X
  75. Xvoid strinend() /**/
  76. X{
  77. X    strin = 0;
  78. X    isfirstch = 1;
  79. X    histdone = 0;
  80. X    hend();
  81. X}
  82. X
  83. X/* stuff a whole file into the input queue and print it */
  84. X
  85. Xint stuff(fn) /**/
  86. Xchar *fn;
  87. X{
  88. XFILE *in;
  89. Xchar *buf;
  90. Xint len;
  91. X
  92. X    if (!(in = fopen(fn,"r")))
  93. X        {
  94. X        zerr("can't open %s",fn,0);
  95. X        return 1;
  96. X        }
  97. X    fseek(in,0,2);
  98. X    len = ftell(in);
  99. X    fseek(in,0,0);
  100. X    buf = alloc(len+1);
  101. X    if (!(fread(buf,len,1,in)))
  102. X        {
  103. X        zerr("read error on %s",fn,0);
  104. X        fclose(in);
  105. X        free(buf);
  106. X        return 1;
  107. X        }
  108. X    fclose(in);
  109. X    buf[len] = '\0';
  110. X    fwrite(buf,len,1,stdout);
  111. X    hungets(buf);
  112. X    return 0;
  113. X}
  114. X
  115. X/* flush input queue */
  116. X
  117. Xvoid hflush() /**/
  118. X{
  119. X    inbufptr += inbufct;
  120. X    inbufct = 0;
  121. X}
  122. X
  123. X/* initialize the history mechanism */
  124. X
  125. Xvoid hbegin() /**/
  126. X{
  127. X    isfirstln = isfirstch = 1;
  128. X    histremmed = errflag = histdone = spaceflag = 0;
  129. X    stophist = isset(NOBANGHIST) || unset(SHINSTDIN);
  130. X    lithist = isset(HISTLIT);
  131. X    hline = hptr = hp_alloc(&hp_lex,hlinesz = 16);
  132. X    curhistent = gethistent(curhist);
  133. X    if (!curhistent->ftim) curhistent->ftim = time(NULL);
  134. X    if (interact && isset(SHINSTDIN) && !strin) {
  135. X        inittty();
  136. X        defev = curhist++;
  137. X        if (curhist-histsiz >= 0) gethistent(curhist-histsiz)->lex = NULL;
  138. X        if (curhist-lithistsiz >= 0) gethistent(curhist-lithistsiz)->lit = NULL;
  139. X        curhistent = gethistent(curhist);
  140. X        hp_purge(hp_lex,curhist-histsiz);
  141. X        hp_purge(hp_lit,curhist-lithistsiz);
  142. X        curhistent->lex = hline;
  143. X        *(curhistent->lit = hp_alloc(&hp_lit,1)) = '\0';
  144. X    } else
  145. X        histremmed = 1;
  146. X}
  147. X
  148. Xvoid inittty() /**/
  149. X{
  150. X    attachtty(mypgrp);
  151. X}
  152. X
  153. X/* say we're done using the history mechanism */
  154. X
  155. Xint hend() /**/
  156. X{
  157. Xint flag,save = 1;
  158. XHistent he;
  159. X
  160. X    if (!hline)
  161. X        return 1;
  162. X    if (!interact || strin || unset(SHINSTDIN)) {
  163. X        hp_free(hp_lex,hline,hlinesz);
  164. X        return 1;
  165. X    }
  166. X    flag = histdone;
  167. X    histdone = 0;
  168. X    if (hptr < hline+2)
  169. X        save = 0;
  170. X    else {
  171. X        char *s,*t;
  172. X
  173. X        s = curhistent->lit;
  174. X        if (*s && *(t = s+strlen(s)-1) == HISTSPACE) *t = '\0';
  175. X        hptr[-1] = '\0';
  176. X        if (hptr[-2] == '\n')
  177. X            if (hline[1]) {
  178. X                if (hptr[-3] == HISTSPACE) hptr[-3] = '\0';
  179. X            } else save = 0;
  180. X        he = gethistent(curhist-1);
  181. X        if (!strcmp(hline,"\n") ||
  182. X                (isset(HISTIGNOREDUPS) && he->lex && !strcmp(he->lex,hline)) ||
  183. X                (isset(HISTIGNORESPACE) && spaceflag))
  184. X            save = 0;
  185. X    }
  186. X    if (flag & (HISTFLAG_DONE|HISTFLAG_RECALL)) {
  187. X        char *ptr,*p;
  188. X        p = ptr = ztrdup(hline);
  189. X        for (;*p;p++) if (*p == HISTSPACE) *p = ' ';
  190. X        if ((flag & (HISTFLAG_DONE|HISTFLAG_RECALL)) == HISTFLAG_DONE) {
  191. X            fprintf(stderr,"%s\n",ptr);
  192. X            fflush(stderr);
  193. X        }
  194. X        if (flag & HISTFLAG_RECALL) {
  195. X            permalloc();
  196. X            pushnode(bufstack,ptr);
  197. X            lastalloc();
  198. X            save = 0;
  199. X        } else free(ptr);
  200. X    }
  201. X    curhistent->stim = time(NULL);
  202. X    curhistent->ftim = 0L;
  203. X    if (!save) remhist();
  204. X    if (hline && !curhistent->lex) hp_free(hp_lex,hline,hlinesz);
  205. X    hline = NULL;
  206. X    return !(flag & HISTFLAG_NOEXEC || errflag);
  207. X}
  208. X
  209. X/* remove the current line from the history List */
  210. X
  211. Xvoid remhist() /**/
  212. X{
  213. X    if (!histremmed) { histremmed = 1; curhist--; }
  214. X}
  215. X
  216. X/* begin a word */
  217. X
  218. Xvoid hwbegin() /**/
  219. X{
  220. X    hlastw = hptr;
  221. X}
  222. X
  223. X/* add a word to the history List */
  224. X
  225. Xchar *hwadd() /**/
  226. X{
  227. Xchar *ret = hlastw;
  228. X
  229. X    if (hlastw && hline)
  230. X        {
  231. X        hwaddc(HISTSPACE);
  232. X        if (alstackind || strin)
  233. X            if (!(alstackind == 1 && !alstack[0]))
  234. X                hptr = hlastw;
  235. X        }
  236. X    if (alstat == ALSTAT_JUNK)
  237. X        alstat = 0;
  238. X    return ret;
  239. X}
  240. X
  241. X/* get an argument specification */
  242. X
  243. Xint getargspec(argc,marg) /**/
  244. Xint argc;int marg;
  245. X{
  246. Xint c,ret = -1;
  247. X    if ((c = hgetch()) == '0')
  248. X        return 0;
  249. X    if (idigit(c))
  250. X        {
  251. X        ret = 0;
  252. X        while (idigit(c))
  253. X            {
  254. X            ret = ret*10+c-'0';
  255. X            c = hgetch();
  256. X            }
  257. X        hungetch(c);
  258. X        }
  259. X    else if (c == '^')
  260. X        ret = 1;
  261. X    else if (c == '$')
  262. X        ret = argc;
  263. X    else if (c == '%')
  264. X        {
  265. X        if (marg == -1)
  266. X            {
  267. X            herrflush();
  268. X            zerr("%% with no previous word matched",NULL,0);
  269. X            return -2;
  270. X            }
  271. X        ret = marg;
  272. X        }
  273. X    else
  274. X        hungetch(c);
  275. X    return ret;
  276. X}
  277. X
  278. X/* do ?foo? search */
  279. X
  280. Xint hconsearch(str,marg) /**/
  281. Xchar *str;int *marg;
  282. X{
  283. Xint t0,t1 = 0;
  284. Xchar *s,*hs;
  285. X
  286. X    for (t0 = curhist-1; hs = quietgetevent(t0); t0--)
  287. X        if (s = ztrstr(hs,str)) {
  288. X            while (s != hs) if (*s-- == HISTSPACE) t1++;
  289. X            *marg = t1;
  290. X            return t0;
  291. X        }
  292. X    return -1;
  293. X}
  294. X
  295. X/* do !foo search */
  296. X
  297. Xint hcomsearch(str) /**/
  298. Xchar *str;
  299. X{
  300. Xint t0;
  301. Xchar *hs;
  302. X
  303. X    for (t0 = curhist-1; hs = quietgetevent(t0); t0--)
  304. X        if (!strncmp(hs,str,strlen(str))) return t0;
  305. X    return -1;
  306. X}
  307. X
  308. X/* various utilities for : modifiers */
  309. X
  310. Xint remtpath(junkptr) /**/
  311. Xchar **junkptr;
  312. X{
  313. Xchar *str = *junkptr,*cut;
  314. X    if (cut = strrchr(str,'/')) {
  315. X        if (str != cut) *cut = '\0';
  316. X        else str[1] = '\0';
  317. X        return 1;
  318. X    }
  319. X    return 0;
  320. X}
  321. Xint remtext(junkptr) /**/
  322. Xchar **junkptr;
  323. X{
  324. Xchar *str = *junkptr,*cut;
  325. X    if ((cut = strrchr(str,'.')) && cut != str)
  326. X        {
  327. X        *cut = '\0';
  328. X        return 1;
  329. X        }
  330. X    return 0;
  331. X}
  332. Xint rembutext(junkptr) /**/
  333. Xchar **junkptr;
  334. X{
  335. Xchar *str = *junkptr,*cut;
  336. X    if ((cut = strrchr(str,'.')) && cut != str)
  337. X        {
  338. X        *junkptr = strdup(cut+1);  /* .xx or xx? */
  339. X        return 1;
  340. X        }
  341. X    return 0;
  342. X}
  343. Xint remlpaths(junkptr) /**/
  344. Xchar **junkptr;
  345. X{
  346. Xchar *str = *junkptr,*cut;
  347. X    if (cut = strrchr(str,'/'))
  348. X        {
  349. X        *cut = '\0';
  350. X        *junkptr = strdup(cut+1);
  351. X        return 1;
  352. X        }
  353. X    return 0;
  354. X}
  355. X
  356. Xint makeuppercase(junkptr) /**/
  357. Xchar **junkptr;
  358. X{
  359. Xchar *str = *junkptr;
  360. X
  361. X    for (; *str; str++)
  362. X        *str = tuupper(*str);
  363. X    return 1;
  364. X}
  365. X
  366. Xint makelowercase(junkptr) /**/
  367. Xchar **junkptr;
  368. X{
  369. Xchar *str = *junkptr;
  370. X
  371. X    for (; *str; str++)
  372. X        *str = tulower(*str);
  373. X    return 1;
  374. X}
  375. X
  376. Xvoid subst(strptr,in,out,gbal) /**/
  377. Xchar **strptr;char *in;char *out;int gbal;
  378. X{
  379. Xchar *str = *strptr,*cut,*sptr;
  380. Xint off;
  381. X
  382. X    while (cut = (char *) ztrstr(str,in)) {
  383. X        *cut = '\0';
  384. X        sptr = convamps(out,in);
  385. X        off = cut-*strptr+strlen(sptr);
  386. X        cut += strlen(in);
  387. X        *strptr = tricat(*strptr,sptr,cut);
  388. X        if (gbal) {
  389. X            str = (char *) *strptr+off;
  390. X            continue;
  391. X        }
  392. X        break;
  393. X    }
  394. X}
  395. Xchar *convamps(out,in) /**/
  396. Xchar *out;char *in;
  397. X{
  398. Xchar *ptr,*ret,*pp;
  399. Xint slen,inlen = strlen(in);
  400. X    for (ptr = out, slen = 0; *ptr; ptr++,slen++)
  401. X        if (*ptr == '\\')
  402. X            ptr++;
  403. X        else if (*ptr == '&')
  404. X            slen += inlen-1;
  405. X    ret = pp = alloc(slen+1);
  406. X    for (ptr = out; *ptr; ptr++)
  407. X        if (*ptr == '\\')
  408. X            *pp++ = *++ptr;
  409. X        else if (*ptr == '&')
  410. X            {
  411. X            strcpy(pp,in);
  412. X            pp += inlen;
  413. X            }
  414. X        else
  415. X            *pp++ = *ptr;
  416. X    *pp = '\0';
  417. X    return ret;
  418. X}
  419. X
  420. Xchar *makehstr(s) /**/
  421. Xchar *s;
  422. X{
  423. Xchar *t;
  424. X
  425. X    t = s = strdup(s);
  426. X    for (; *t; t++)
  427. X        if (*t == HISTSPACE)
  428. X            *t = ' ';
  429. X    return s;
  430. X}
  431. X
  432. Xchar *quietgetevent(ev) /**/
  433. Xint ev;
  434. X{
  435. XHistent ent;
  436. X
  437. X    if (ev < firsthist()) return NULL;
  438. X    ent = gethistent(ev);
  439. X    return (lithist) ? ent->lit : ent->lex;
  440. X}
  441. X
  442. Xchar *getevent(ev) /**/
  443. Xint ev;
  444. X{
  445. Xchar *ret;
  446. X
  447. X    ret = quietgetevent(ev);
  448. X    if (!ret) {
  449. X        herrflush();
  450. X        zerr("no such event: %d",NULL,ev);
  451. X    }
  452. X    return ret;
  453. X}
  454. Xint getargc(list) /**/
  455. Xchar *list;
  456. X{
  457. Xint argc = 0;
  458. X
  459. X    for (; *list; list++) if (*list == HISTSPACE) argc++;
  460. X    return argc;
  461. X}
  462. Xchar *getargs(elist,arg1,arg2) /**/
  463. Xchar *elist;int arg1;int arg2;
  464. X{
  465. Xchar *ret = elist,*retn;
  466. Xint acnt = arg2-arg1+1;
  467. X
  468. X    while (arg1--)
  469. X        while (*ret && *ret++ != HISTSPACE);
  470. X    if (!*ret)
  471. X        {
  472. X        herrflush();
  473. X        zerr("no such word in event",NULL,0);
  474. X        return NULL;
  475. X        }
  476. X    retn = ret = strdup(ret);
  477. X    while (acnt > 0)
  478. X        {
  479. X        while (*ret && *ret != HISTSPACE)
  480. X            ret++;
  481. X        if (*ret == HISTSPACE)
  482. X            *ret = ' ';
  483. X        else
  484. X            break;
  485. X        acnt--;
  486. X        }
  487. X    if (acnt > 1 && !*ret)
  488. X        {
  489. X        herrflush();
  490. X        zerr("no such word in event",NULL,0);
  491. X        return NULL;
  492. X        }
  493. X    *ret = '\0';
  494. X    return retn;
  495. X}
  496. X
  497. Xvoid upcase(x) /**/
  498. Xchar **x;
  499. X{
  500. Xchar *pp = *(char **) x;
  501. X
  502. X    for (; *pp; pp++)
  503. X        *pp = tuupper(*pp);
  504. X}
  505. X
  506. Xvoid downcase(x) /**/
  507. Xchar **x;
  508. X{
  509. Xchar *pp = *(char **) x;
  510. X
  511. X    for (; *pp; pp++)
  512. X        *pp = tulower(*pp);
  513. X}
  514. X
  515. Xint quote(tr) /**/
  516. Xchar **tr;
  517. X{
  518. Xchar *ptr,*rptr,**str = (char **) tr;
  519. Xint len = 3;
  520. X    for (ptr = *str; *ptr; ptr++,len++)
  521. X        if (*ptr == '\'') len += 3;
  522. X    ptr = *str;
  523. X    *str = rptr = alloc(len);
  524. X    *rptr++ = '\'';
  525. X    for (; *ptr; ptr++)
  526. X        if (*ptr == '\'') {
  527. X            *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
  528. X        } else
  529. X            *rptr++ = *ptr;
  530. X    *rptr++ = '\'';
  531. X    *rptr++ = 0;
  532. X    str[1] = NULL;
  533. X    return 0;
  534. X}
  535. Xint quotebreak(tr) /**/
  536. Xchar **tr;
  537. X{
  538. Xchar *ptr,*rptr,**str = (char **) tr;
  539. Xint len = 3;
  540. X    for (ptr = *str; *ptr; ptr++,len++)
  541. X        if (*ptr == '\'')
  542. X            len += 3;
  543. X        else if (inblank(*ptr))
  544. X            len += 2;
  545. X    ptr = *str;
  546. X    *str = rptr = alloc(len);
  547. X    *rptr++ = '\'';
  548. X    for (; *ptr; )
  549. X        if (*ptr == '\'') {
  550. X            *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
  551. X            ptr++;
  552. X        } else if (inblank(*ptr)) {
  553. X            *rptr++ = '\''; *rptr++ = *ptr++; *rptr++ = '\'';
  554. X        } else
  555. X            *rptr++ = *ptr++;
  556. X    *rptr++ = '\'';
  557. X    *rptr++ = '\0';
  558. X    return 0;
  559. X}
  560. X
  561. Xvoid herrflush() /**/
  562. X{
  563. X    if (strin)
  564. X        hflush();
  565. X    else while (lastc != '\n' && !lexstop)
  566. X        hgetch();
  567. X}
  568. X
  569. X/* read an arbitrary amount of data into a buffer until stop is found */
  570. X
  571. Xchar *hdynread(stop) /**/
  572. Xint stop;
  573. X{
  574. Xint bsiz = 256,ct = 0,c;
  575. Xchar *buf = zalloc(bsiz),*ptr;
  576. X    ptr = buf;
  577. X    while ((c = hgetch()) != stop && c != '\n' && !lexstop)
  578. X        {
  579. X        if (c == '\\')
  580. X            c = hgetch();
  581. X        *ptr++ = c;
  582. X        if (++ct == bsiz)
  583. X            {
  584. X            buf = realloc(buf,bsiz *= 2);
  585. X            ptr = buf+ct;
  586. X            }
  587. X        }
  588. X    *ptr = 0;
  589. X    if (c == '\n')
  590. X        {
  591. X        hungetch('\n');
  592. X        zerr("delimiter expected",NULL,0);
  593. X        free(buf);
  594. X        return NULL;
  595. X        }
  596. X    return buf;
  597. X}
  598. Xchar *hdynread2(stop) /**/
  599. Xint stop;
  600. X{
  601. Xint bsiz = 256,ct = 0,c;
  602. Xchar *buf = zalloc(bsiz),*ptr;
  603. X    ptr = buf;
  604. X    while ((c = hgetch()) != stop && c != '\n' && !lexstop)
  605. X        {
  606. X        if (c == '\n')
  607. X            {
  608. X            hungetch(c);
  609. X            break;
  610. X            }
  611. X        if (c == '\\')
  612. X            c = hgetch();
  613. X        *ptr++ = c;
  614. X        if (++ct == bsiz)
  615. X            {
  616. X            buf = realloc(buf,bsiz *= 2);
  617. X            ptr = buf+ct;
  618. X            }
  619. X        }
  620. X    *ptr = 0;
  621. X    if (c == '\n')
  622. X        hungetch('\n');
  623. X    return buf;
  624. X}
  625. X
  626. Xvoid inithist() /**/
  627. X{
  628. X    hp_lit = zalloc(sizeof *hp_lit);
  629. X    hp_lit->next = NULL;
  630. X    hp_lit->ptr = hp_lit->pool = zalloc(HEAPSIZE);
  631. X    hp_lit->free = HEAPSIZE;
  632. X    hp_lex = zalloc(sizeof *hp_lex);
  633. X    hp_lex->next = NULL;
  634. X    hp_lex->ptr = hp_lex->pool = zalloc(HEAPSIZE);
  635. X    hp_lex->free = HEAPSIZE;
  636. X    histentct = (lithistsiz > histsiz) ? lithistsiz : histsiz;
  637. X    histentarr = zcalloc(histentct*sizeof *histentarr);
  638. X}
  639. X
  640. Xvoid resizehistents() /**/
  641. X{
  642. Xint newentct,t0,t1,firstlit,firstlex;
  643. XHistent newarr;
  644. X
  645. X    newentct = (lithistsiz > histsiz) ? lithistsiz : histsiz;
  646. X    newarr = zcalloc(newentct*sizeof *newarr);
  647. X    firstlex = curhist-histsiz+1;
  648. X    firstlit = curhist-lithistsiz+1;
  649. X    t0 = firsthist();
  650. X    if (t0 < curhist-newentct) t0 = curhist-newentct;
  651. X    t1 = t0 % newentct;
  652. X    for (; t0 <= curhist; t0++) {
  653. X        newarr[t1] = *gethistent(t0);
  654. X        if (t0 < firstlex) newarr[t1].lex = NULL;
  655. X        if (t0 < firstlit) newarr[t1].lit = NULL;
  656. X        t1++; if (t1 == newentct) t1 = 0;
  657. X    }
  658. X    free(histentarr);
  659. X    histentarr = newarr;
  660. X    histentct = newentct;
  661. X}
  662. X
  663. Xchar *hp_alloc(hp,siz) /**/
  664. XHp *hp; int siz;
  665. X{
  666. Xchar *ret;
  667. XHp h = *hp;
  668. X
  669. X    if (h->free >= siz) {
  670. X        ret = h->ptr;
  671. X        h->ptr += siz;
  672. X        h->free -= siz;
  673. X        return ret;
  674. X    }
  675. X#ifdef MEMDEBUG
  676. X    fprintf(stderr,"new heap (siz = %d, curhist = %d)\n",siz,curhist);
  677. X#endif
  678. X    permalloc();
  679. X    h = zalloc(sizeof *h);
  680. X    h->next = *hp;
  681. X    h->free = (siz > HEAPSIZE) ? siz : HEAPSIZE;
  682. X    h->ptr = h->pool = zalloc(h->free);
  683. X    h->histno = curhist;
  684. X    *hp = h;
  685. X    heapalloc();
  686. X    return hp_alloc(hp,siz);
  687. X}
  688. X
  689. Xchar *hp_realloc(hp,ptr,oldsiz,newsiz) /**/
  690. XHp *hp; char *ptr; int oldsiz; int newsiz;
  691. X{
  692. XHp h = *hp;
  693. Xint delta = newsiz-oldsiz;
  694. Xchar *ret;
  695. X
  696. X    if (h->ptr-oldsiz == ptr && h->free >= delta) {
  697. X        h->free -= delta;
  698. X        h->ptr += delta;
  699. X        return ptr;
  700. X    }
  701. X#ifdef MEMDEBUG
  702. X    fprintf(stderr,"realloc copy\n");
  703. X#endif
  704. X    memcpy(ret = hp_alloc(hp,newsiz),ptr,oldsiz);
  705. X    return ret;
  706. X}
  707. X
  708. Xvoid hp_free(h,ptr,siz) /**/
  709. XHp h; char *ptr; int siz;
  710. X{
  711. X    if (h->ptr-siz == ptr) {
  712. X        h->free += siz;
  713. X        h->ptr -= siz;
  714. X    }
  715. X}
  716. X
  717. Xchar *hp_concat(old,new) /**/
  718. Xchar *old; char *new;
  719. X{
  720. Xint oldlen,newlen;
  721. X
  722. X    oldlen = strlen(old); newlen = strlen(new);
  723. X    old = hp_realloc(&hp_lit,old,oldlen+1,oldlen+newlen+1);
  724. X    strcpy(old+oldlen,new);
  725. X    return old;
  726. X}
  727. X
  728. Xvoid hp_purge(h,lim) /**/
  729. XHp h; int lim;
  730. X{
  731. XHp hlast;
  732. X
  733. X    if (!h->next) return;
  734. X    while (h->next) { hlast = h; h = h->next; }
  735. X    if (h->histno <= lim || h->histno == 0) {
  736. X#ifdef MEMDEBUG
  737. X        fprintf(stderr,"purging %d\n",lim);
  738. X#endif
  739. X        free(h->pool);
  740. X        free(h);
  741. X        hlast->next = NULL;
  742. X    }
  743. X}
  744. X
  745. Xvoid readhistfile(s,err) /**/
  746. Xchar *s;int err;
  747. X{
  748. Xchar buf[1024];
  749. XFILE *in;
  750. XHistent ent;
  751. Xtime_t tim = time(NULL);
  752. X
  753. X    if (!s) return;
  754. X    if (in = fopen(s,"r")) {
  755. X        while (fgets(buf,1024,in)) {
  756. X            int l = strlen(buf);
  757. X            char *pt = buf;
  758. X
  759. X            while (l && buf[l-1] == '\n') {
  760. X                buf[l-1] = '\0';
  761. X                if (l > 1 && buf[l-2] == '\\') {
  762. X                    buf[l-2] = '\n';
  763. X                    fgets(buf+l-1,1024-(l-1),in);
  764. X                    l = strlen(buf);
  765. X                } else break;
  766. X            }
  767. X            for (;*pt;pt++) if (*pt == ' ') *pt = HISTSPACE;
  768. X
  769. X            ent = gethistent(++curhist);
  770. X            ent->lex = hp_alloc(&hp_lex,strlen(buf)+1);
  771. X            strcpy(ent->lex,buf);
  772. X            ent->lit = hp_alloc(&hp_lit,strlen(buf)+1);
  773. X            strcpy(ent->lit,buf);
  774. X            ent->ftim = ent->stim = tim;
  775. X        }
  776. X        fclose(in);
  777. X    } else if (err)
  778. X        zerr("can't read history file",s,0);
  779. X}
  780. X
  781. Xvoid savehistfile(s,err,app) /**/
  782. Xchar *s;int err;int app;
  783. X{
  784. Xchar *t;
  785. XFILE *out;
  786. Xint ev,flag;
  787. X
  788. X    if (!s || !interact) return;
  789. X    ev = curhist-savehist+1;
  790. X    flag = (app) ? O_APPEND : O_TRUNC;
  791. X    if (ev < firsthist()) ev = firsthist();
  792. X    if (out = fdopen(open(s,O_CREAT|O_WRONLY|flag,0600),"w")) {
  793. X        for (; ev <= curhist; ev++) {
  794. X            t = quietgetevent(ev);
  795. X            for (; *t; t++)
  796. X                if (*t == HISTSPACE) fputc(' ',out);
  797. X                else {
  798. X                    if (*t == '\n') fputc('\\',out);
  799. X                    fputc(*t,out);
  800. X                }
  801. X            fputc('\n',out);
  802. X        }
  803. X        fclose(out);
  804. X    } else if (err) zerr("can't write history file: %s",s,0);
  805. X}
  806. X
  807. Xint firsthist() /**/
  808. X{
  809. Xint ev;
  810. XHistent ent;
  811. X
  812. X    ev = curhist-histentct+1;
  813. X    if (ev < 1) ev = 1;
  814. X    do {
  815. X        ent = gethistent(ev);
  816. X        if ((lithist) ? ent->lit : ent->lex) break;
  817. X        ev++;
  818. X    } while (ev < curhist);
  819. X    return ev;
  820. X}
  821. X
  822. SHAR_EOF
  823. echo 'File zsh2.2/src/hist.c is complete' &&
  824. chmod 0644 zsh2.2/src/hist.c ||
  825. echo 'restore of zsh2.2/src/hist.c failed'
  826. Wc_c="`wc -c < 'zsh2.2/src/hist.c'`"
  827. test 23511 -eq "$Wc_c" ||
  828.     echo 'zsh2.2/src/hist.c: original size 23511, current size' "$Wc_c"
  829. rm -f _shar_wnt_.tmp
  830. fi
  831. # ============= zsh2.2/src/init.c ==============
  832. if test -f 'zsh2.2/src/init.c' -a X"$1" != X"-c"; then
  833.     echo 'x - skipping zsh2.2/src/init.c (File already exists)'
  834.     rm -f _shar_wnt_.tmp
  835. else
  836. > _shar_wnt_.tmp
  837. echo 'x - extracting zsh2.2/src/init.c (Text)'
  838. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/init.c' &&
  839. X/*
  840. X *
  841. X * init.c - main loop and initialization routines
  842. X *
  843. X * This file is part of zsh, the Z shell.
  844. X *
  845. X * This software is Copyright 1992 by Paul Falstad
  846. X *
  847. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  848. X * use this software as long as: there is no monetary profit gained
  849. X * specifically from the use or reproduction of this software, it is not
  850. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  851. X * included prominently in any copy made. 
  852. X *
  853. X * The author make no claims as to the fitness or correctness of this software
  854. X * for any use whatsoever, and it is provided as is. Any use of this software
  855. X * is at the user's own risk. 
  856. X *
  857. X */
  858. X
  859. X#define GLOBALS
  860. X#include "zsh.h"
  861. X#include <pwd.h>
  862. X
  863. Xvoid main(argc,argv,envp) /**/
  864. Xint argc; char **argv; char **envp;
  865. X{
  866. Xint notect = 0;
  867. X
  868. X#ifdef LC_ALL
  869. X    setlocale(LC_ALL, "");
  870. X#endif
  871. X    environ = envp;
  872. X    meminit();
  873. X    setflags();
  874. X    parseargs(argv);
  875. X    setmoreflags();
  876. X    setupvals();
  877. X    initialize();
  878. X    heapalloc();
  879. X    runscripts();
  880. X    for(;;)
  881. X        {
  882. X        do
  883. X            loop();
  884. X        while (tok != ENDINPUT);
  885. X        if (!(isset(IGNOREEOF) && interact))
  886. X            {
  887. X#if 0
  888. X            if (interact)
  889. X                fputs(islogin ? "logout\n" : "exit\n",stderr);
  890. X#endif
  891. X            zexit(NULL);
  892. X            continue;
  893. X            }
  894. X        zerrnam("zsh",(!islogin) ? "use 'exit' to exit."
  895. X            : "use 'logout' to logout.",NULL,0);
  896. X        notect++;
  897. X        if (notect == 10)
  898. X            zexit(NULL);
  899. X        }
  900. X}
  901. X
  902. X/* keep executing lists until EOF found */
  903. X
  904. Xvoid loop() /**/
  905. X{
  906. XList list;
  907. XHeap h = (Heap) peekfirst(heaplist);
  908. X
  909. X    pushheap();
  910. X    for(;;)
  911. X        {
  912. X        freeheap();
  913. X        if (interact && isset(SHINSTDIN))
  914. X            preprompt();
  915. X        hbegin();        /* init history mech */
  916. X        intr();            /* interrupts on */
  917. X        ainit();            /* init alias mech */
  918. X        lexinit();
  919. X        errflag = 0;
  920. X        if (!(list = parse_event()))
  921. X            {                /* if we couldn't parse a list */
  922. X            hend();
  923. X            if (tok == ENDINPUT && !errflag)
  924. X                break;
  925. X            continue;
  926. X            }
  927. X        if (hend())
  928. X            {
  929. X            if (stopmsg)        /* unset 'you have stopped jobs' flag */
  930. X                stopmsg--;
  931. X            execlist(list);
  932. X            }
  933. X        if (ferror(stderr))
  934. X            {
  935. X            zerr("write error",NULL,0);
  936. X            clearerr(stderr);
  937. X            }
  938. X        if (subsh)                /* how'd we get this far in a subshell? */
  939. X            exit(lastval);
  940. X        if ((!interact && errflag) || retflag)
  941. X            break;
  942. X        if ((opts['t'] == OPT_SET) || (lastval && opts[ERREXIT] == OPT_SET))
  943. X            {
  944. X            if (sigtrapped[SIGEXIT])
  945. X                dotrap(SIGEXIT);
  946. X            exit(lastval);
  947. X            }
  948. X        }
  949. X    while ((Heap) peekfirst(heaplist) != h)
  950. X        popheap();
  951. X}
  952. X
  953. Xvoid setflags() /**/
  954. X{
  955. Xint c;
  956. X
  957. X    for (c = 0; c != 32; c++)        opts[c] = OPT_UNSET;
  958. X    for (c = 32; c != 128; c++)    opts[c] = OPT_INVALID;
  959. X    for (c = 'a'; c <= 'z'; c++)    opts[c] = opts[c-'a'+'A'] = OPT_UNSET;
  960. X    for (c = '0'; c <= '9'; c++)    opts[c] = OPT_UNSET;
  961. X    opts['A'] = OPT_INVALID;
  962. X    opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
  963. X    opts[BGNICE] = opts[NOTIFY] = OPT_SET;
  964. X    opts[USEZLE] = (interact && SHTTY != -1) ? OPT_SET : OPT_UNSET;
  965. X    opts[HASHCMDS] = opts[HASHLISTALL] = opts[HASHDIRS] = OPT_SET;
  966. X}
  967. X
  968. Xstatic char *cmd;
  969. X
  970. Xvoid parseargs(argv) /**/
  971. Xchar **argv;
  972. X{
  973. Xchar **x;
  974. Xint bk = 0,action;
  975. XLklist paramlist;
  976. X
  977. X    hackzero = argzero = *argv;
  978. X    opts[LOGINSHELL] = (**(argv++) == '-') ? OPT_SET : OPT_UNSET;
  979. X    SHIN = 0;
  980. X    while (!bk && *argv && (**argv == '-' || **argv == '+'))
  981. X        {
  982. X        action = (**argv == '-') ? OPT_SET : OPT_UNSET;
  983. X        while (*++*argv) {
  984. X            if (opts[**argv] == OPT_INVALID) {
  985. X                zerr("bad option: -%c",NULL,**argv);
  986. X                exit(1);
  987. X            }
  988. X            if (bk = **argv == 'b') break;
  989. X            if (**argv == 'c') { /* -c command */
  990. X                argv++;
  991. X                if (!*argv) {
  992. X                    zerr("string expected after -c",NULL,0);
  993. X                    exit(1);
  994. X                }
  995. X                cmd = *argv;
  996. X                opts[INTERACTIVE] = OPT_UNSET;
  997. X                opts['c'] = OPT_SET;
  998. X                break;
  999. X            } else if (**argv == 'o') {
  1000. X                int c;
  1001. X
  1002. X                if (!*++*argv)
  1003. X                    argv++;
  1004. X                if (!*argv) {
  1005. X                    zerr("string expected after -o",NULL,0);
  1006. X                    exit(1);
  1007. X                }
  1008. X                c = optlookup(*argv);
  1009. X                if (c == -1)
  1010. X                    zerr("no such option: %s",*argv,0);
  1011. X                else
  1012. X                    opts[c] = action;
  1013. X                break;
  1014. X            } else opts[**argv] = action;
  1015. X        }
  1016. X        argv++;
  1017. X    }
  1018. X    paramlist = newlist();
  1019. X    if (*argv)
  1020. X        {
  1021. X        if (opts[SHINSTDIN] == OPT_UNSET)
  1022. X            {
  1023. X            SHIN = movefd(open(argzero = *argv,O_RDONLY));
  1024. X            if (SHIN == -1)
  1025. X                {
  1026. X                zerr("can't open input file: %s",*argv,0);
  1027. X                exit(1);
  1028. X                }
  1029. X            opts[INTERACTIVE] = OPT_UNSET;
  1030. X            argv++;
  1031. X            }
  1032. X        while (*argv)
  1033. X            addnode(paramlist,ztrdup(*argv++));
  1034. X        }
  1035. X    else
  1036. X        opts[SHINSTDIN] = OPT_SET;
  1037. X    pparams = x = zcalloc((countnodes(paramlist)+1)*sizeof(char *));
  1038. X    while (*x++ = getnode(paramlist));
  1039. X    free(paramlist);
  1040. X    argzero = ztrdup(argzero);
  1041. X}
  1042. X
  1043. Xvoid setmoreflags() /**/
  1044. X{
  1045. Xint t0;
  1046. Xlong ttpgrp;
  1047. X
  1048. X    /* stdout,stderr fully buffered */
  1049. X#ifdef _IOFBF
  1050. X    setvbuf(stdout,malloc(BUFSIZ),_IOFBF,BUFSIZ);
  1051. X    setvbuf(stderr,malloc(BUFSIZ),_IOFBF,BUFSIZ);
  1052. X#else
  1053. X    setbuffer(stdout,malloc(BUFSIZ),BUFSIZ);
  1054. X    setbuffer(stderr,malloc(BUFSIZ),BUFSIZ);
  1055. X#endif
  1056. X    subsh = 0;
  1057. X#ifndef NOCLOSEFUNNYFDS
  1058. X    /* this works around a bug in some versions of in.rshd */
  1059. X    for (t0 = 3; t0 != 10; t0++)
  1060. X        close(t0);
  1061. X#endif
  1062. X#ifdef JOB_CONTROL
  1063. X    opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
  1064. X    if (jobbing) {
  1065. X        SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
  1066. X        if (SHTTY == -1)
  1067. X            opts[MONITOR] = OPT_UNSET;
  1068. X        else {
  1069. X#ifdef TIOCSETD
  1070. X#ifdef NTTYDISC
  1071. X            int ldisc = NTTYDISC;
  1072. X            ioctl(SHTTY, TIOCSETD, &ldisc);
  1073. X#endif
  1074. X#endif
  1075. X            gettyinfo(&shttyinfo);    /* get tty state */
  1076. X#ifdef sgi
  1077. X            if (shttyinfo.tio.c_cc[VSWTCH] <= 0) /* hack for irises */
  1078. X                shttyinfo.tio.c_cc[VSWTCH] = CSWTCH;
  1079. X#endif
  1080. X            savedttyinfo = shttyinfo;
  1081. X        }
  1082. X#ifdef sgi
  1083. X        setpgrp(0,getpgrp(0));
  1084. X#endif
  1085. X        if ((mypgrp = getpgrp(0)) <= 0)
  1086. X            opts[MONITOR] = OPT_UNSET;
  1087. X        else while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
  1088. X            sleep(1);
  1089. X            mypgrp = getpgrp(0);
  1090. X            if (mypgrp == gettygrp()) break;
  1091. X            killpg(mypgrp,SIGTTIN);
  1092. X            mypgrp = getpgrp(0);
  1093. X        }
  1094. X    } else
  1095. X        SHTTY = -1;
  1096. X#else
  1097. X    opts[MONITOR] = OPT_UNSET;
  1098. X    SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
  1099. X    if (SHTTY != -1) {
  1100. X        gettyinfo(&shttyinfo);
  1101. X        savedttyinfo = shttyinfo;
  1102. X    }
  1103. X#endif
  1104. X}
  1105. X
  1106. Xvoid setupvals() /**/
  1107. X{
  1108. Xstruct passwd *pswd;
  1109. Xchar *ptr,*s;
  1110. Xstatic long bauds[] = {
  1111. X    0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
  1112. X    };
  1113. X
  1114. X    curhist = 0;
  1115. X    histsiz = DEFAULT_HISTSIZE;
  1116. X    lithistsiz = 5;
  1117. X    inithist();
  1118. X    mailcheck = logcheck = 60;
  1119. X    dirstacksize = -1;
  1120. X    listmax = 100;
  1121. X    reporttime = -1;
  1122. X    bangchar = '!';
  1123. X    hashchar = '#';
  1124. X    hatchar = '^';
  1125. X    termok = 0;
  1126. X    curjob = prevjob = coprocin = coprocout = -1;
  1127. X    shtimer = time(NULL);    /* init $SECONDS */
  1128. X    srand((unsigned int) shtimer);
  1129. X    /* build various hash tables; argument to newhtable is table size */
  1130. X    aliastab = newhtable(37);
  1131. X    addreswords();
  1132. X    paramtab = newhtable(151);
  1133. X    cmdnamtab = newhtable(37);
  1134. X    compctltab = newhtable(13);
  1135. X    initxbindtab();
  1136. X    nullcmd = ztrdup("cat");
  1137. X    readnullcmd = ztrdup("more");
  1138. X    prompt = ztrdup("%m%# ");
  1139. X    prompt2 = ztrdup("> ");
  1140. X    prompt3 = ztrdup("?# ");
  1141. X    prompt4 = ztrdup("+ ");
  1142. X    sprompt = ztrdup("zsh: correct `%R' to `%r' [nyae]? ");
  1143. X    term = ztrdup("");
  1144. X    ppid = getppid();
  1145. X#ifdef TIO
  1146. X#ifdef HAS_TCCRAP
  1147. X    baud = cfgetospeed(&shttyinfo.tio);
  1148. X    if (baud < 100) baud = bauds[baud]; /* aren't "standards" great?? */
  1149. X#else
  1150. X    baud = bauds[shttyinfo.tio.c_cflag & CBAUD];
  1151. X#endif
  1152. X#else
  1153. X    baud = bauds[shttyinfo.sgttyb.sg_ospeed];
  1154. X#endif
  1155. X#ifdef TIOCGWINSZ
  1156. X    if (!(columns = shttyinfo.winsize.ws_col))
  1157. X        columns = 80;
  1158. X    if (!(lines = shttyinfo.winsize.ws_row))
  1159. X        lines = 24;
  1160. X#else
  1161. X    columns = 80;
  1162. X    lines = 24;
  1163. X#endif
  1164. X    ifs = ztrdup(" \t\n");
  1165. X    if (pswd = getpwuid(getuid())) {
  1166. X        username = ztrdup(pswd->pw_name);
  1167. X        home = ztrdup(pswd->pw_dir);
  1168. X    } else {
  1169. X        username = ztrdup("");
  1170. X        home = ztrdup("/");
  1171. X    }
  1172. X    if (ptr = zgetenv("LOGNAME"))
  1173. X        logname = ztrdup(ptr);
  1174. X    else
  1175. X        logname = ztrdup(username);
  1176. X    timefmt = ztrdup(DEFTIMEFMT);
  1177. X    watchfmt = ztrdup(DEFWATCHFMT);
  1178. X    if (!(ttystrname = ztrdup(ttyname(SHTTY))))
  1179. X        ttystrname = ztrdup("");
  1180. X    wordchars = ztrdup(DEFWORDCHARS);
  1181. X    fceditparam = ztrdup(DEFFCEDIT);
  1182. X    tmpprefix = ztrdup(DEFTMPPREFIX);
  1183. X    postedit = ztrdup("");
  1184. X    if (ispwd(home)) pwd = ztrdup(home);
  1185. X    else if ((ptr = zgetenv("PWD")) && ispwd(ptr)) pwd = ztrdup(ptr);
  1186. X    else pwd = zgetwd();
  1187. X    oldpwd = ztrdup(pwd);
  1188. X    hostnam = zalloc(256);
  1189. X    underscore = ztrdup("");
  1190. X    gethostname(hostnam,256);
  1191. X    mypid = getpid();
  1192. X    cdpath = mkarray(NULL);
  1193. X    manpath = mkarray(NULL);
  1194. X    fignore = mkarray(NULL);
  1195. X    fpath = mkarray(NULL);
  1196. X    mailpath = mkarray(NULL);
  1197. X    watch = mkarray(NULL);
  1198. X    hosts = mkarray(NULL);
  1199. X    compctlsetup();
  1200. X    userdirs = (char **) zcalloc(sizeof(char *)*2);
  1201. X    usernames = (char **) zcalloc(sizeof(char *)*2);
  1202. X    userdirsz = 2;
  1203. X    userdirct = 0;
  1204. X    optarg = ztrdup("");
  1205. X    zoptind = 1;
  1206. X    schedcmds = NULL;
  1207. X    path = (char **) zalloc(4*sizeof *path);
  1208. X    path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin");
  1209. X    path[2] = ztrdup("/usr/ucb"); path[3] = NULL;
  1210. X    inittyptab();
  1211. X    initlextabs();
  1212. X    setupparams();
  1213. X    setparams();
  1214. X    inittyptab();
  1215. X    if ((s = zgetenv("EMACS")) && !strcmp(s,"t") && !strcmp(term,"emacs"))
  1216. X        opts[USEZLE] = OPT_UNSET;
  1217. X#ifndef HAS_RUSAGE
  1218. X    times(&shtms);
  1219. X#endif
  1220. X}
  1221. X
  1222. Xvoid compctlsetup() /**/
  1223. X{
  1224. Xstatic char
  1225. X    *hs[] = {"telnet","rlogin","ftp","rup","rusers","rsh",NULL},
  1226. X    *os[] = {"setopt","unsetopt",NULL},
  1227. X    *vs[] = {"export","typeset","vared","unset",NULL},
  1228. X    *cs[] = {"which","builtin",NULL},
  1229. X    *bs[] = {"bindkey",NULL};
  1230. X
  1231. X    compctl_process(hs,CC_HOSTS|CC_FILES,NULL);
  1232. X    compctl_process(os,CC_OPTIONS,NULL);
  1233. X    compctl_process(vs,CC_VARS,NULL);
  1234. X    compctl_process(bs,CC_BINDINGS,NULL);
  1235. X    compctl_process(cs,CC_COMMPATH,NULL);
  1236. X    cc_compos.mask   = CC_COMMPATH;
  1237. X    cc_default.mask  = CC_FILES;
  1238. X}
  1239. X
  1240. Xvoid initialize() /**/
  1241. X{
  1242. Xint t0;
  1243. X
  1244. X    breaks = loops = 0;
  1245. X    lastmailcheck = time(NULL);
  1246. X    locallist = NULL;
  1247. X    dirstack = newlist();
  1248. X    bufstack = newlist();
  1249. X    newcmdnamtab();
  1250. X    inbuf = zalloc(inbufsz = 256);
  1251. X    inbufptr = inbuf+inbufsz;
  1252. X    inbufct = 0;
  1253. X#ifndef QDEBUG
  1254. X    signal(SIGQUIT,SIG_IGN);
  1255. X#endif
  1256. X#ifdef RLIM_INFINITY
  1257. X    for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  1258. X        getrlimit(t0,limits+t0);
  1259. X#endif
  1260. X    hsubl = hsubr = NULL;
  1261. X    lastpid = 0;
  1262. X    bshin = fdopen(SHIN,"r");
  1263. X    signal(SIGCHLD,handler);
  1264. X    if (jobbing)
  1265. X        {
  1266. X        int ttypgrp;
  1267. X        for (;;)
  1268. X            {
  1269. X#ifdef TIOCGPGRP
  1270. X            ioctl(SHTTY, TIOCGPGRP, &ttypgrp);
  1271. X#else
  1272. X            ttypgrp = tcgetpgrp(SHTTY);
  1273. X#endif
  1274. X            if (ttypgrp == mypgrp)
  1275. X                break;
  1276. X            kill(0,SIGTTIN);
  1277. X            }
  1278. X        signal(SIGTTOU,SIG_IGN);
  1279. X        signal(SIGTSTP,SIG_IGN);
  1280. X        signal(SIGTTIN,SIG_IGN);
  1281. X        signal(SIGPIPE,SIG_IGN);
  1282. X        attachtty(mypgrp);
  1283. X        }
  1284. X    if (interact)
  1285. X        {
  1286. X        signal(SIGTERM,SIG_IGN);
  1287. X#ifdef SIGWINCH
  1288. X        signal(SIGWINCH,handler);
  1289. X#endif
  1290. X        signal(SIGALRM,handler);
  1291. X        intr();
  1292. X        }
  1293. X}
  1294. X
  1295. Xvoid addreswords() /**/
  1296. X{
  1297. Xstatic char *reswds[] = {
  1298. X    "do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
  1299. X    "if", "while", "function", "repeat", "time", "until", "exec", "command",
  1300. X    "select", "coproc", "noglob", "-", "nocorrect", "foreach", "end", NULL
  1301. X    };
  1302. Xint t0;
  1303. X
  1304. X    for (t0 = 0; reswds[t0]; t0++)
  1305. X        addhperm(reswds[t0],mkanode(NULL,-1-t0),aliastab,NULL);
  1306. X}
  1307. X
  1308. Xvoid runscripts() /**/
  1309. X{
  1310. X#ifdef GLOBALZSHENV
  1311. X    source(GLOBALZSHENV);
  1312. X#endif
  1313. X    if (opts[NORCS] == OPT_SET) {
  1314. X#ifdef GLOBALZPROFILE
  1315. X        if (islogin) source(GLOBALZPROFILE);
  1316. X#endif
  1317. X#ifdef GLOBALZSHRC
  1318. X        source(GLOBALZSHRC);
  1319. X#endif
  1320. X#ifdef GLOBALZLOGIN
  1321. X        if (islogin) source(GLOBALZLOGIN);
  1322. X#endif
  1323. X    } else {
  1324. X        sourcehome(".zshenv");
  1325. X        if (opts[NORCS] == OPT_SET)
  1326. X            return;
  1327. X        if (interact) {
  1328. X            if (islogin) {
  1329. X                sourcehome(".zprofile");
  1330. X#ifdef GLOBALZPROFILE
  1331. X                source(GLOBALZPROFILE);
  1332. X#endif
  1333. X            }
  1334. X#ifdef GLOBALZSHRC
  1335. X            source(GLOBALZSHRC);
  1336. X#endif
  1337. X            sourcehome(".zshrc");
  1338. X            if (islogin) {
  1339. X#ifdef GLOBALZLOGIN
  1340. X                source(GLOBALZLOGIN);
  1341. X#endif
  1342. X                sourcehome(".zlogin");
  1343. X            }
  1344. X        }
  1345. X    }
  1346. X    if (interact)
  1347. X        readhistfile(getsparam("HISTFILE"),0);
  1348. X    if (opts['c'] == OPT_SET)
  1349. X        {
  1350. X        if (SHIN >= 10)
  1351. X            close(SHIN);
  1352. X        SHIN = movefd(open("/dev/null",O_RDONLY));
  1353. X        execstring(cmd);
  1354. X        stopmsg = 1;
  1355. X        zexit(NULL);
  1356. X        }
  1357. X#ifdef TIOCSWINSZ
  1358. X    if (!(columns = shttyinfo.winsize.ws_col))
  1359. X        columns = 80;
  1360. X    if (!(lines = shttyinfo.winsize.ws_row))
  1361. X        lines = 24;
  1362. X#endif
  1363. X}
  1364. X
  1365. Xvoid ainit() /**/
  1366. X{
  1367. X    alstackind = 0;        /* reset alias stack */
  1368. X    alstat = 0;
  1369. X    isfirstln = 1;
  1370. X}
  1371. X
  1372. SHAR_EOF
  1373. chmod 0644 zsh2.2/src/init.c ||
  1374. echo 'restore of zsh2.2/src/init.c failed'
  1375. Wc_c="`wc -c < 'zsh2.2/src/init.c'`"
  1376. test 11807 -eq "$Wc_c" ||
  1377.     echo 'zsh2.2/src/init.c: original size 11807, current size' "$Wc_c"
  1378. rm -f _shar_wnt_.tmp
  1379. fi
  1380. # ============= zsh2.2/src/jobs.c ==============
  1381. if test -f 'zsh2.2/src/jobs.c' -a X"$1" != X"-c"; then
  1382.     echo 'x - skipping zsh2.2/src/jobs.c (File already exists)'
  1383.     rm -f _shar_wnt_.tmp
  1384. else
  1385. > _shar_wnt_.tmp
  1386. echo 'x - extracting zsh2.2/src/jobs.c (Text)'
  1387. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/jobs.c' &&
  1388. X/*
  1389. X *
  1390. X * jobs.c - job control
  1391. X *
  1392. X * This file is part of zsh, the Z shell.
  1393. X *
  1394. X * This software is Copyright 1992 by Paul Falstad
  1395. X *
  1396. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1397. X * use this software as long as: there is no monetary profit gained
  1398. X * specifically from the use or reproduction of this software, it is not
  1399. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1400. X * included prominently in any copy made. 
  1401. X *
  1402. X * The author make no claims as to the fitness or correctness of this software
  1403. X * for any use whatsoever, and it is provided as is. Any use of this software
  1404. X * is at the user's own risk. 
  1405. X *
  1406. X */
  1407. X
  1408. X#include "zsh.h"
  1409. X#include <sys/errno.h>
  1410. X
  1411. X/* != 0 means the handler is active */
  1412. X
  1413. Xstatic int handling = 0;
  1414. X
  1415. X#ifdef INTHANDTYPE
  1416. X#define RETURN return 0
  1417. X#else
  1418. X#define RETURN return
  1419. X#endif
  1420. X
  1421. X/* the signal handler */
  1422. X
  1423. XHANDTYPE handler(sig,code) /**/
  1424. Xint sig;int code;
  1425. X{
  1426. Xlong pid;
  1427. Xint statusp;
  1428. XJob jn;
  1429. Xstruct process *pn;
  1430. X#ifdef HAS_RUSAGE
  1431. Xstruct rusage ru;
  1432. X#else
  1433. Xlong chlds,chldu;
  1434. X#endif
  1435. X
  1436. X#ifdef RESETHANDNEEDED
  1437. X    signal(sig,handler);
  1438. X#endif
  1439. X    if (sig == SIGINT)
  1440. X        {
  1441. X        if (sigtrapped[SIGINT])
  1442. X            dotrap(SIGINT);
  1443. X        else
  1444. X            errflag = 1;
  1445. X        RETURN;
  1446. X        }
  1447. X#ifdef SIGWINCH
  1448. X    if (sig == SIGWINCH)
  1449. X        adjustwinsize();
  1450. X#endif
  1451. X    if (sig != SIGCHLD)
  1452. X        {
  1453. X        dotrap(sig);
  1454. X        if (sig == SIGALRM && !sigtrapped[SIGALRM])
  1455. X            {
  1456. X            zerr("timeout",NULL,0);
  1457. X            exit(1);
  1458. X            }
  1459. X        RETURN;
  1460. X        }
  1461. X    for (;;)
  1462. X        {
  1463. X#ifdef HAS_RUSAGE
  1464. X        pid = wait3((vptr) &statusp,WNOHANG|WUNTRACED,&ru);
  1465. X#else
  1466. X#ifndef WNOHANG
  1467. X        pid = wait(&statusp);
  1468. X#else
  1469. X        pid = wait3((vptr) &statusp,WNOHANG|WUNTRACED,NULL);
  1470. X#endif
  1471. X        chlds = shtms.tms_cstime;
  1472. X        chldu = shtms.tms_cutime;
  1473. X        times(&shtms);
  1474. X#endif
  1475. X        if (pid == -1)
  1476. X            {
  1477. X            if (errno != ECHILD)
  1478. X                zerr("wait failed: %e",NULL,errno);
  1479. X            RETURN;
  1480. X            }
  1481. X        if (!pid)
  1482. X            RETURN;
  1483. X        findproc(pid,&jn,&pn);    /* find the process of this pid */
  1484. X        if (jn)
  1485. X            {
  1486. X            pn->statusp = statusp;
  1487. X            handling = 1;
  1488. X#ifdef HAS_RUSAGE
  1489. X            pn->ti.ru = ru;
  1490. X#else
  1491. X            pn->ti.st = shtms.tms_cstime-chlds;
  1492. X            pn->ti.ut = shtms.tms_cutime-chldu;
  1493. X#endif
  1494. X            pn->endtime = time(NULL);
  1495. X            updatestatus(jn);
  1496. X            handling = 0;
  1497. X            }
  1498. X#if 0
  1499. X        else if (WIFSTOPPED(statusp))
  1500. X            kill(pid,SIGKILL);    /* kill stopped untraced children */
  1501. X#endif
  1502. X        }
  1503. X}
  1504. X
  1505. X/* change job table entry from stopped to running */
  1506. X
  1507. Xvoid makerunning(jn) /**/
  1508. XJob jn;
  1509. X{
  1510. Xstruct process *pn;
  1511. X
  1512. X    jn->stat &= ~STAT_STOPPED;
  1513. X    for (pn = jn->procs; pn; pn = pn->next)
  1514. X        if (WIFSTOPPED(pn->statusp))
  1515. X            pn->statusp = SP_RUNNING;
  1516. X}
  1517. X
  1518. X/* update status of job, possibly printing it */
  1519. X
  1520. Xvoid updatestatus(jn) /**/
  1521. XJob jn;
  1522. X{
  1523. Xstruct process *pn;
  1524. Xint notrunning = 1,alldone = 1,val,job = jn-jobtab,somestopped = 0;
  1525. X
  1526. X    for (pn = jn->procs; pn; pn = pn->next)
  1527. X        {
  1528. X        if (pn->statusp == SP_RUNNING)
  1529. X            notrunning = 0;
  1530. X        if (pn->statusp == SP_RUNNING || WIFSTOPPED(pn->statusp))
  1531. X            alldone = 0;
  1532. X        if (WIFSTOPPED(pn->statusp))
  1533. X            somestopped = 1;
  1534. X        if (!pn->next && jn)
  1535. X            val = (WIFSIGNALED(pn->statusp)) ?
  1536. X                0200 | WTERMSIG(pn->statusp) : WEXITSTATUS(pn->statusp);
  1537. X        }
  1538. X    if (!notrunning)
  1539. X        return;
  1540. X    if (somestopped && (jn->stat & STAT_STOPPED))
  1541. X        return;
  1542. X    jn->stat |= (alldone) ? STAT_CHANGED|STAT_DONE :
  1543. X        STAT_CHANGED|STAT_STOPPED;
  1544. X    if (alldone && job == thisjob)
  1545. X        {
  1546. X        if (!ttyfrozen && !val) {
  1547. X            gettyinfo(&shttyinfo);
  1548. X            if (interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))
  1549. X                sanetty(&shttyinfo);
  1550. X#ifdef TIOCSWINSZ
  1551. X            if (!(columns = shttyinfo.winsize.ws_col))
  1552. X                columns = 80;
  1553. X            lines = shttyinfo.winsize.ws_row;
  1554. X#endif
  1555. X        } else
  1556. X            settyinfo(&shttyinfo);
  1557. X        lastval = val;
  1558. X        }
  1559. X    if ((jn->stat & (STAT_DONE|STAT_STOPPED)) == STAT_STOPPED) {
  1560. X        prevjob = curjob;
  1561. X        curjob = job;
  1562. X    }
  1563. X    if ((isset(NOTIFY) || job == thisjob) && jn->stat & STAT_LOCKED) {
  1564. X        printjob(jn,!!isset(LONGLISTJOBS));
  1565. X        if (zleactive) refresh();
  1566. X    }
  1567. X    if (sigtrapped[SIGCHLD] && job != thisjob)
  1568. X        dotrap(SIGCHLD);
  1569. X}
  1570. X
  1571. X/* find process and job associated with pid */
  1572. X
  1573. Xvoid findproc(pid,jptr,pptr) /**/
  1574. Xint pid;Job *jptr;struct process **pptr;
  1575. X{
  1576. Xstruct process *pn;
  1577. Xint jn;
  1578. X
  1579. X    for (jn = 1; jn != MAXJOB; jn++)
  1580. X        for (pn = jobtab[jn].procs; pn; pn = pn->next)
  1581. X            if (pn->pid == pid)
  1582. X                {
  1583. X                *pptr = pn;
  1584. X                *jptr = jobtab+jn;
  1585. X                return;
  1586. X                }
  1587. X    *pptr = NULL;
  1588. X    *jptr = NULL;
  1589. X}
  1590. X
  1591. X/*
  1592. X    lng = 0 means jobs 
  1593. X    lng = 1 means jobs -l
  1594. X    lng = 2 means jobs -p
  1595. X*/
  1596. X
  1597. Xvoid printjob(jn,lng) /**/
  1598. XJob jn;int lng;
  1599. X{
  1600. Xint job = jn-jobtab,len = 9,sig = -1,sflag = 0,llen,printed = 0;
  1601. Xint conted = 0,lineleng = getlineleng(),skip = 0,doputnl = 0;
  1602. Xstruct process *pn;
  1603. X
  1604. X    if (lng < 0)
  1605. X        {
  1606. X        conted = 1;
  1607. X        lng = 0;
  1608. X        }
  1609. X
  1610. X    /* find length of longest signame, check to see if we
  1611. X        really need to print this job */
  1612. X
  1613. X    for (pn = jn->procs; pn; pn = pn->next)
  1614. X        {
  1615. X        if (pn->statusp != SP_RUNNING)
  1616. X            if (WIFSIGNALED(pn->statusp))
  1617. X                {
  1618. X                sig = WTERMSIG(pn->statusp);
  1619. X                llen = strlen(sigmsg[sig]);
  1620. X                if (WCOREDUMPED(pn->statusp))
  1621. X                    llen += 14;
  1622. X                if (llen > len)
  1623. X                    len = llen;
  1624. X                if (sig != SIGINT && sig != SIGPIPE)
  1625. X                    sflag = 1;
  1626. X                else if (sig == SIGINT)
  1627. X                    errflag = 1;
  1628. X                if (job == thisjob && sig == SIGINT)
  1629. X                    doputnl = 1;
  1630. X                }
  1631. X            else if (WIFSTOPPED(pn->statusp))
  1632. X                {
  1633. X                sig = WSTOPSIG(pn->statusp);
  1634. X                if (strlen(sigmsg[sig]) > len)
  1635. X                    len = strlen(sigmsg[sig]);
  1636. X                if (job == thisjob && sig == SIGTSTP)
  1637. X                    doputnl = 1;
  1638. X                }
  1639. X            else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
  1640. X                    WEXITSTATUS(pn->statusp))
  1641. X                sflag = 1;
  1642. X        }
  1643. X
  1644. X    /* print if necessary */
  1645. X
  1646. X    if (interact && jobbing && ((jn->stat & STAT_STOPPED) || sflag ||
  1647. X            job != thisjob))
  1648. X        {
  1649. X        int len2,fline = 1;
  1650. X        struct process *qn;
  1651. X
  1652. X        trashzle();
  1653. X        if (doputnl)
  1654. X            putc('\n',stderr);
  1655. X        for (pn = jn->procs; pn;)
  1656. X            {
  1657. X            len2 = ((job == thisjob) ? 5 : 10)+len; /* 2 spaces */
  1658. X            if (lng)
  1659. X                qn = pn->next;
  1660. X            else for (qn = pn->next; qn; qn = qn->next)
  1661. X                {
  1662. X                if (qn->statusp != pn->statusp)
  1663. X                    break;
  1664. X                if (strlen(qn->text)+len2+((qn->next) ? 3 : 0) > lineleng)
  1665. X                    break;
  1666. X                len2 += strlen(qn->text)+2;
  1667. X                }
  1668. X            if (job != thisjob)
  1669. X                if (fline)
  1670. X                    fprintf(stderr,"[%d]  %c ",jn-jobtab,(job == curjob) ? '+' :
  1671. X                        (job == prevjob) ? '-' : ' ');
  1672. X                else
  1673. X                    fprintf(stderr,(job > 9) ? "        " : "       ");
  1674. X            else
  1675. X                fprintf(stderr,"zsh: ");
  1676. X            if (lng)
  1677. X                if (lng == 1)
  1678. X                    fprintf(stderr,"%d ",pn->pid);
  1679. X                else
  1680. X                    {
  1681. X                    int x = jn->gleader;
  1682. X
  1683. X                    fprintf(stderr,"%d ",x);
  1684. X                    do skip++; while (x /= 10);
  1685. X                    skip++;
  1686. X                    lng = 0;
  1687. X                    }
  1688. X            else
  1689. X                fprintf(stderr,"%*s",skip,"");
  1690. X            if (pn->statusp == SP_RUNNING)
  1691. X                if (!conted)
  1692. X                    fprintf(stderr,"running%*s",len-7+2,"");
  1693. X                else
  1694. X                    fprintf(stderr,"continued%*s",len-9+2,"");
  1695. X            else if (WIFEXITED(pn->statusp))
  1696. X                if (WEXITSTATUS(pn->statusp))
  1697. X                    fprintf(stderr,"exit %-4d%*s",WEXITSTATUS(pn->statusp),
  1698. X                        len-9+2,"");
  1699. X                else
  1700. X                    fprintf(stderr,"done%*s",len-4+2,"");
  1701. X            else if (WIFSTOPPED(pn->statusp))
  1702. X                fprintf(stderr,"%-*s",len+2,sigmsg[WSTOPSIG(pn->statusp)]);
  1703. X            else if (WCOREDUMPED(pn->statusp))
  1704. X                fprintf(stderr,"%s (core dumped)%*s",
  1705. X                    sigmsg[WTERMSIG(pn->statusp)],
  1706. X                    len-14+2-strlen(sigmsg[WTERMSIG(pn->statusp)]),"");
  1707. X            else
  1708. X                fprintf(stderr,"%-*s",len+2,sigmsg[WTERMSIG(pn->statusp)]);
  1709. X            for (; pn != qn; pn = pn->next)
  1710. X                fprintf(stderr,(pn->next) ? "%s | " : "%s",pn->text);
  1711. X            putc('\n',stderr);
  1712. X            fline = 0;
  1713. X            }
  1714. X        printed = 1;
  1715. X        }
  1716. X    else if (doputnl && interact)
  1717. X        putc('\n',stderr);
  1718. X    fflush(stderr);
  1719. X
  1720. X    /* print "(pwd now: foo)" messages */
  1721. X
  1722. X    if (interact && job==thisjob && strcmp(jn->pwd,pwd))
  1723. X        {
  1724. X        printf("(pwd now: ");
  1725. X        printdir(pwd);
  1726. X        printf(")\n");
  1727. X        fflush(stdout);
  1728. X        }
  1729. X
  1730. X    /* delete job if done */
  1731. X
  1732. X    if (jn->stat & STAT_DONE)
  1733. X        {
  1734. X        static struct job zero;
  1735. X        struct process *nx;
  1736. X        char *s;
  1737. X
  1738. X        if ((jn->stat & STAT_TIMED) || (reporttime != -1 && report(jn))) {
  1739. X            dumptime(jn);
  1740. X            printed = 1;
  1741. X        }
  1742. X        for (pn = jn->procs; pn; pn = nx)
  1743. X            {
  1744. X            nx = pn->next;
  1745. X            free(pn);
  1746. X            }
  1747. X        free(jn->pwd);
  1748. X        if (jn->filelist)
  1749. X            {
  1750. X            while (s = getnode(jn->filelist))
  1751. X                {
  1752. X                unlink(s);
  1753. X                free(s);
  1754. X                }
  1755. X            free(jn->filelist);
  1756. X            }
  1757. X        *jn = zero;
  1758. X        if (job == curjob)
  1759. X            {
  1760. X            curjob = prevjob;
  1761. X            prevjob = job;
  1762. X            }
  1763. X        if (job == prevjob)
  1764. X            setprevjob();
  1765. X        }
  1766. X    else
  1767. X        jn->stat &= ~STAT_CHANGED;
  1768. X}
  1769. X
  1770. X/* set the previous job to something reasonable */
  1771. X
  1772. Xvoid setprevjob() /**/
  1773. X{
  1774. Xint t0;
  1775. X
  1776. X    for (t0 = MAXJOB-1; t0; t0--)
  1777. X        if ((jobtab[t0].stat & STAT_INUSE) && (jobtab[t0].stat & STAT_STOPPED) &&
  1778. X                t0 != curjob && t0 != thisjob)
  1779. X            break;
  1780. X    if (!t0)
  1781. X        for (t0 = MAXJOB-1; t0; t0--)
  1782. X            if ((jobtab[t0].stat & STAT_INUSE) && t0 != curjob && t0 != thisjob)
  1783. X                break;
  1784. X    prevjob = (t0) ? t0 : -1;
  1785. X}
  1786. X
  1787. X/* initialize a job table entry */
  1788. X
  1789. Xvoid initjob() /**/
  1790. X{
  1791. X    jobtab[thisjob].pwd = ztrdup(pwd);
  1792. X    jobtab[thisjob].stat = STAT_INUSE;
  1793. X    jobtab[thisjob].gleader = 0;
  1794. X}
  1795. X
  1796. X/* add a process to the current job */
  1797. X
  1798. Xstruct process *addproc(pid,text) /**/
  1799. Xlong pid;char *text;
  1800. X{
  1801. Xstruct process *process;
  1802. X
  1803. X    if (!jobtab[thisjob].gleader) jobtab[thisjob].gleader = pid;
  1804. X    process = zcalloc(sizeof *process);
  1805. X    process->pid = pid;
  1806. X    if (text) strcpy(process->text,text);
  1807. X    else *process->text = '\0';
  1808. X    process->next = NULL;
  1809. X    process->statusp = SP_RUNNING;
  1810. X    process->bgtime = time(NULL);
  1811. X    if (jobtab[thisjob].procs) {
  1812. X        struct process *n;
  1813. X        for (n = jobtab[thisjob].procs; n->next; n = n->next);
  1814. X        process->next = NULL;
  1815. X        n->next = process;
  1816. X    } else jobtab[thisjob].procs = process;
  1817. X    return process;
  1818. X}
  1819. X
  1820. X/* determine if it's all right to exec a command without
  1821. X    forking in last component of subshells; it's not ok if we have files
  1822. X    to delete */
  1823. X
  1824. Xint execok() /**/
  1825. X{
  1826. XJob jn;
  1827. X
  1828. X    if (!exiting)
  1829. X        return 0;
  1830. X    for (jn = jobtab+1; jn != jobtab+MAXJOB; jn++)
  1831. X        if (jn->stat && jn->filelist)
  1832. X            return 0;
  1833. X    return 1;
  1834. X
  1835. X}
  1836. X
  1837. Xvoid waitforpid(pid) /**/
  1838. Xlong pid;
  1839. X{
  1840. X    while (!errflag && (kill(pid,0) >= 0 || errno != ESRCH)) chldsuspend();
  1841. X}
  1842. X
  1843. X/* wait for a job to finish */
  1844. X
  1845. Xvoid waitjob(job) /**/
  1846. Xint job;
  1847. X{
  1848. Xstatic struct job zero;
  1849. XJob jn;
  1850. X
  1851. X    if (jobtab[job].procs)    /* if any forks were done */
  1852. X        {
  1853. X        jobtab[job].stat |= STAT_LOCKED;
  1854. X        if (jobtab[job].stat & STAT_CHANGED)
  1855. X            printjob(jobtab+job,!!isset(LONGLISTJOBS));
  1856. X        while (jobtab[job].stat &&
  1857. X                !(jobtab[job].stat & (STAT_DONE|STAT_STOPPED)))
  1858. X            chldsuspend();
  1859. X        }
  1860. X    else    /* else do what printjob() usually does */
  1861. X        {
  1862. X        char *s;
  1863. X
  1864. X        jn = jobtab+job;
  1865. X        free(jn->pwd);
  1866. X        if (jn->filelist)
  1867. X            {
  1868. X            while (s = getnode(jn->filelist))
  1869. X                {
  1870. X                unlink(s);
  1871. X                free(s);
  1872. X                }
  1873. X            free(jn->filelist);
  1874. X            }
  1875. X        *jn = zero;
  1876. X        }
  1877. X}
  1878. X
  1879. X/* wait for running job to finish */
  1880. X
  1881. Xvoid waitjobs() /**/
  1882. X{
  1883. X    waitjob(thisjob);
  1884. X    thisjob = -1;
  1885. X}
  1886. X
  1887. X/* clear job table when entering subshells */
  1888. X
  1889. Xvoid clearjobtab() /**/
  1890. X{
  1891. Xstatic struct job zero;
  1892. Xint t0;
  1893. X
  1894. X    for (t0 = 1; t0 != MAXJOB; t0++)
  1895. X        jobtab[thisjob] = zero;
  1896. X}
  1897. X
  1898. X/* get a free entry in the job table to use */
  1899. X
  1900. Xint getfreejob() /**/
  1901. X{
  1902. Xint t0;
  1903. X
  1904. X    for (t0 = 1; t0 != MAXJOB; t0++)
  1905. X        if (!jobtab[t0].stat) {
  1906. X            jobtab[t0].stat |= STAT_INUSE;
  1907. X            return t0;
  1908. X        }
  1909. X    zerr("job table full or recursion limit exceeded",NULL,0);
  1910. X    return -1;
  1911. X}
  1912. X
  1913. X/* print pids for & */
  1914. X
  1915. Xvoid spawnjob() /**/
  1916. X{
  1917. Xstruct process *pn;
  1918. X
  1919. X    if (!subsh)
  1920. X        {
  1921. X        if (curjob == -1 || !(jobtab[curjob].stat & STAT_STOPPED))
  1922. X            {
  1923. X            curjob = thisjob;
  1924. X            setprevjob();
  1925. X            }
  1926. X        else if (prevjob == -1 || !(jobtab[prevjob].stat & STAT_STOPPED))
  1927. X            prevjob = thisjob;
  1928. X        if (interact && jobbing && jobtab[thisjob].procs)
  1929. X            {
  1930. X            fprintf(stderr,"[%d]",thisjob);
  1931. X            for (pn = jobtab[thisjob].procs; pn; pn = pn->next)
  1932. X                fprintf(stderr," %d",pn->pid);
  1933. X            fprintf(stderr,"\n");
  1934. X            fflush(stderr);
  1935. X            }
  1936. X        }
  1937. X    if (!jobtab[thisjob].procs)
  1938. X        {
  1939. X        char *s;
  1940. X        static struct job zero;
  1941. X        struct job *jn;
  1942. X
  1943. X        jn = jobtab+thisjob;
  1944. X        free(jn->pwd);
  1945. X        if (jn->filelist)
  1946. X            {
  1947. X            while (s = getnode(jn->filelist))
  1948. X                {
  1949. X                unlink(s);
  1950. X                free(s);
  1951. X                }
  1952. X            free(jn->filelist);
  1953. X            }
  1954. X        *jn = zero;
  1955. X        }
  1956. X    else
  1957. X        jobtab[thisjob].stat |= STAT_LOCKED;
  1958. X    thisjob = -1;
  1959. X}
  1960. X
  1961. Xvoid fixsigs() /**/
  1962. X{
  1963. X    unblockchld();
  1964. X}
  1965. X
  1966. Xint report(j) /**/
  1967. XJob j;
  1968. X{
  1969. X    if (!j->procs) return 0;
  1970. X#ifdef HAS_RUSAGE
  1971. X    return (j->procs->ti.ru.ru_utime.tv_sec+j->procs->ti.ru.ru_stime.tv_sec)
  1972. X                 >= reporttime;
  1973. X#else
  1974. X    return (j->procs->ti.ut+j->procs->ti.st)/HZ >= reporttime;
  1975. X#endif
  1976. X}
  1977. X
  1978. Xvoid printtime(real,ti,desc) /**/
  1979. Xtime_t real;struct timeinfo *ti;char *desc;
  1980. X{
  1981. Xchar *s;
  1982. X#ifdef sun
  1983. Xlong ticks = 1;
  1984. Xint pk = getpagesize()/1024;
  1985. X#else
  1986. Xlong sec;
  1987. X#endif
  1988. X#ifdef HAS_RUSAGE
  1989. Xstruct rusage *ru = &ti->ru;
  1990. X#endif
  1991. X
  1992. X    if (!desc) desc = "";
  1993. X#ifdef HAS_RUSAGE
  1994. X#ifdef sun
  1995. X    ticks = (ru->ru_utime.tv_sec+ru->ru_stime.tv_sec)*HZ+
  1996. X              (ru->ru_utime.tv_usec+ru->ru_stime.tv_usec)*HZ/1000000;
  1997. X    if (!ticks) ticks = 1;
  1998. X#else
  1999. X    sec = ru->ru_utime.tv_sec + ru->ru_stime.tv_sec;
  2000. X    if (!sec) sec = 1;
  2001. X#endif
  2002. X#endif
  2003. X    for (s = timefmt; *s; s++)
  2004. X        if (*s == '%')
  2005. X            switch(s++,*s)
  2006. X                {
  2007. X                case 'E': fprintf(stderr,"%lds",real); break;
  2008. X#ifndef HAS_RUSAGE
  2009. X                case 'U': fprintf(stderr,"%ld.%03lds",
  2010. X                    ti->ut/HZ,ti->ut*1000/60%1000); break;
  2011. X                case 'S': fprintf(stderr,"%ld.%03lds",
  2012. X                    ti->st/HZ,ti->st*1000/60%1000); break;
  2013. X                case 'P':
  2014. X                    if (real)
  2015. X                        fprintf(stderr,"%d%%",
  2016. X                            (int) (100*((ti->ut+ti->st)/HZ))/real);
  2017. X                    break;
  2018. X#else
  2019. X                case 'U': fprintf(stderr,"%ld.%03lds",
  2020. X                    ru->ru_utime.tv_sec,ru->ru_utime.tv_usec/1000); break;
  2021. X                case 'S': fprintf(stderr,"%ld.%03lds",
  2022. X                    ru->ru_stime.tv_sec,ru->ru_stime.tv_usec/1000); break;
  2023. X                case 'P':
  2024. X                    if (real)
  2025. X                        fprintf(stderr,"%d%%",
  2026. X                            (int) (100*(ru->ru_utime.tv_sec+ru->ru_stime.tv_sec))
  2027. X                                / real);
  2028. X                    break;
  2029. X                case 'W': fprintf(stderr,"%ld",ru->ru_nswap); break;
  2030. X#ifdef sun
  2031. X                case 'K': case 'D':
  2032. X                    fprintf(stderr,"%ld",ru->ru_idrss/ticks*pk); break;
  2033. X                case 'M': fprintf(stderr,"%ld",ru->ru_maxrss*pk); break;
  2034. X#else
  2035. X                case 'X': fprintf(stderr,"%ld",ru->ru_ixrss/sec); break;
  2036. X                case 'D': fprintf(stderr,"%ld",
  2037. X                    (ru->ru_idrss+ru->ru_isrss)/sec); break;
  2038. X                case 'K': fprintf(stderr,"%ld",
  2039. X                    (ru->ru_ixrss+ru->ru_idrss+ru->ru_isrss)/sec); break;
  2040. X                case 'M': fprintf(stderr,"%ld",ru->ru_maxrss/1024); break;
  2041. X#endif
  2042. X                case 'F': fprintf(stderr,"%ld",ru->ru_majflt); break;
  2043. X                case 'R': fprintf(stderr,"%ld",ru->ru_minflt); break;
  2044. X                case 'I': fprintf(stderr,"%ld",ru->ru_inblock); break;
  2045. X                case 'O': fprintf(stderr,"%ld",ru->ru_oublock); break;
  2046. X                case 'r': fprintf(stderr,"%ld",ru->ru_msgrcv); break;
  2047. X                case 's': fprintf(stderr,"%ld",ru->ru_msgsnd); break;
  2048. X                case 'k': fprintf(stderr,"%ld",ru->ru_nsignals); break;
  2049. X                case 'w': fprintf(stderr,"%ld",ru->ru_nvcsw); break;
  2050. X                case 'c': fprintf(stderr,"%ld",ru->ru_nivcsw); break;
  2051. X#endif
  2052. X                case 'J': fprintf(stderr,"%s",desc); break;
  2053. X                default: fprintf(stderr,"%%%c",*s); break;
  2054. X                }
  2055. X        else
  2056. X            putc(*s,stderr);
  2057. X    putc('\n',stderr);
  2058. X    fflush(stderr);
  2059. X}
  2060. X
  2061. Xvoid dumptime(jn) /**/
  2062. XJob jn;
  2063. X{
  2064. Xstruct process *pn = jn->procs;
  2065. X
  2066. X    if (!jn->procs)
  2067. X        return;
  2068. X    for (pn = jn->procs; pn; pn = pn->next)
  2069. X        printtime(pn->endtime-pn->bgtime,&pn->ti,pn->text);
  2070. X}
  2071. X
  2072. Xvoid shelltime() /**/
  2073. X{
  2074. Xstruct timeinfo ti;
  2075. X#ifdef HAS_RUSAGE
  2076. Xstruct rusage ru;
  2077. X
  2078. X    getrusage(RUSAGE_SELF,&ru);
  2079. X    memcpy(&ti.ru,&ru,sizeof(ru));
  2080. X    printtime(time(NULL)-shtimer,&ti,"shell");
  2081. X
  2082. X    getrusage(RUSAGE_CHILDREN,&ru);
  2083. X    memcpy(&ti.ru,&ru,sizeof(ru));
  2084. X    printtime(time(NULL)-shtimer,&ti,"children");
  2085. X#else
  2086. Xstruct tms buf;
  2087. X
  2088. X    times(&buf);
  2089. X    ti.ut = buf.tms_utime;
  2090. X    ti.st = buf.tms_stime;
  2091. X    printtime(time(NULL)-shtimer,&ti,"shell");
  2092. X    ti.ut = buf.tms_cutime;
  2093. X    ti.st = buf.tms_cstime;
  2094. X    printtime(time(NULL)-shtimer,&ti,"children");
  2095. X#endif
  2096. X}
  2097. X
  2098. X/* SIGHUP any jobs left running */
  2099. X
  2100. Xvoid killrunjobs() /**/
  2101. X{
  2102. Xint t0,killed = 0;
  2103. X
  2104. X    if (isset(NOHUP)) return;
  2105. X    for (t0 = 1; t0 != MAXJOB; t0++)
  2106. X        if (t0 != thisjob && (jobtab[t0].stat & STAT_LOCKED) &&
  2107. X                !(jobtab[t0].stat & STAT_STOPPED)) {
  2108. X            if (killpg(jobtab[t0].gleader,SIGHUP) != -1) killed++;
  2109. X        }
  2110. X    if (killed) zerr("warning: %d jobs SIGHUPed",NULL,killed);
  2111. X}
  2112. X
  2113. X/* check to see if user has jobs running/stopped */
  2114. X
  2115. Xvoid checkjobs() /**/
  2116. X{
  2117. Xint t0;
  2118. X
  2119. X    scanjobs();
  2120. X    for (t0 = 1; t0 != MAXJOB; t0++)
  2121. X        if (t0 != thisjob && jobtab[t0].stat & STAT_LOCKED)
  2122. X            break;
  2123. X    if (t0 != MAXJOB) {
  2124. X        if (jobtab[t0].stat & STAT_STOPPED) {
  2125. X#ifdef USE_SUSPENDED
  2126. X            zerr("you have suspended jobs.",NULL,0);
  2127. X#else
  2128. X            zerr("you have stopped jobs.",NULL,0);
  2129. X#endif
  2130. X        } else
  2131. X            zerr("you have running jobs.",NULL,0);
  2132. X        stopmsg = 1;
  2133. X    }
  2134. X}
  2135. X
  2136. X/* send a signal to a job (simply involves kill if monitoring is on) */
  2137. X
  2138. Xint killjb(jn,sig) /**/
  2139. XJob jn;int sig;
  2140. X{
  2141. Xstruct process *pn;
  2142. Xint err;
  2143. X
  2144. X    if (jobbing)
  2145. X        return(killpg(jn->gleader,sig));
  2146. X    for (pn = jn->procs; pn; pn = pn->next)
  2147. X        if ((err = kill(pn->pid,sig)) == -1 && errno != ESRCH)
  2148. X            return -1;
  2149. X    return err;
  2150. X}
  2151. X
  2152. SHAR_EOF
  2153. chmod 0644 zsh2.2/src/jobs.c ||
  2154. echo 'restore of zsh2.2/src/jobs.c failed'
  2155. Wc_c="`wc -c < 'zsh2.2/src/jobs.c'`"
  2156. test 16421 -eq "$Wc_c" ||
  2157.     echo 'zsh2.2/src/jobs.c: original size 16421, current size' "$Wc_c"
  2158. rm -f _shar_wnt_.tmp
  2159. fi
  2160. # ============= zsh2.2/src/lex.c ==============
  2161. if test -f 'zsh2.2/src/lex.c' -a X"$1" != X"-c"; then
  2162.     echo 'x - skipping zsh2.2/src/lex.c (File already exists)'
  2163.     rm -f _shar_wnt_.tmp
  2164. else
  2165. > _shar_wnt_.tmp
  2166. echo 'x - extracting zsh2.2/src/lex.c (Text)'
  2167. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/lex.c' &&
  2168. X/*
  2169. X *
  2170. X * lex.c - lexical analysis
  2171. X *
  2172. X * This file is part of zsh, the Z shell.
  2173. X *
  2174. X * This software is Copyright 1992 by Paul Falstad
  2175. X *
  2176. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2177. X * use this software as long as: there is no monetary profit gained
  2178. X * specifically from the use or reproduction of this software, it is not
  2179. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2180. X * included prominently in any copy made. 
  2181. X *
  2182. X * The author make no claims as to the fitness or correctness of this software
  2183. X * for any use whatsoever, and it is provided as is. Any use of this software
  2184. X * is at the user's own risk. 
  2185. X *
  2186. X */
  2187. X
  2188. X#include "zsh.h"
  2189. X
  2190. X/* lexical state */
  2191. X
  2192. Xstatic int xincmdpos,xincond,xincasepat,dbparens,xdbparens,xalstat;
  2193. Xstatic char *xhlastw;
  2194. X
  2195. Xstatic int xisfirstln, xisfirstch, xhistremmed, xhistdone,
  2196. X    xspaceflag, xstophist, xlithist, xalstackind,xhlinesz;
  2197. Xstatic char *xhline, *xhptr;
  2198. X
  2199. X/* save the lexical state */
  2200. X
  2201. X/* is this a hack or what? */
  2202. X
  2203. Xvoid lexsave() /**/
  2204. X{
  2205. X    xincmdpos = incmdpos;
  2206. X    xincond = incond;
  2207. X    xincasepat = incasepat;
  2208. X    xdbparens = dbparens;
  2209. X    xalstat = alstat;
  2210. X    xalstackind = alstackind;
  2211. X    xisfirstln = isfirstln;
  2212. X    xisfirstch = isfirstch;
  2213. X    xhistremmed = histremmed;
  2214. X    xhistdone = histdone;
  2215. X    xspaceflag = spaceflag;
  2216. X    xstophist = stophist;
  2217. X    xlithist = lithist;
  2218. X    xhline = hline;
  2219. X    xhptr = hptr;
  2220. X    xhlastw = hlastw;
  2221. X    xhlinesz = hlinesz;
  2222. X    inredir = 0;
  2223. X}
  2224. X
  2225. X/* restore lexical state */
  2226. X
  2227. Xvoid lexrestore() /**/
  2228. X{
  2229. X    incmdpos = xincmdpos;
  2230. X    incond = xincond;
  2231. X    incasepat = xincasepat;
  2232. X    dbparens = xdbparens;
  2233. X    alstat = xalstat;
  2234. X    isfirstln = xisfirstln;
  2235. X    isfirstch = xisfirstch;
  2236. X    histremmed = xhistremmed;
  2237. X    histdone = xhistdone;
  2238. X    spaceflag = xspaceflag;
  2239. X    stophist = xstophist;
  2240. X    lithist = xlithist;
  2241. X    hline = xhline;
  2242. X    hptr = xhptr;
  2243. X    hlastw = xhlastw;
  2244. X    clearalstack();
  2245. X    alstackind = xalstackind;
  2246. X    hlinesz = xhlinesz;
  2247. X    lexstop = errflag = 0;
  2248. X}
  2249. X
  2250. Xvoid yylex() /**/
  2251. X{
  2252. X    if (tok == LEXERR) return;
  2253. X    do
  2254. X        tok = gettok();
  2255. X    while (tok != ENDINPUT && exalias());
  2256. X    if (tok != NEWLIN) isnewlin = 0;
  2257. X    else isnewlin = (inbufct) ? -1 : 1;
  2258. X    if (tok == SEMI || tok == NEWLIN) tok = SEPER;
  2259. X}
  2260. X
  2261. Xvoid ctxtlex() /**/
  2262. X{
  2263. Xstatic int oldpos;
  2264. X
  2265. X    yylex();
  2266. X    switch (tok) {
  2267. X    case SEPER: case NEWLIN: case SEMI: case DSEMI: case AMPER:
  2268. X    case INPAR: case INBRACE: case DBAR: case DAMPER: case BAR:
  2269. X    case BARAMP: case INOUTPAR: case DO: case THEN: case ELIF:
  2270. X    case ELSE: incmdpos = 1; break;
  2271. X    case STRING: /* case ENVSTRING: */ case ENVARRAY: case OUTPAR:
  2272. X    case CASE: incmdpos = 0; break;
  2273. X    }
  2274. X    if (IS_REDIROP(tok) || tok == FOR || tok == FOREACH || tok == SELECT) {
  2275. X        inredir = 1;
  2276. X        oldpos = incmdpos;
  2277. X        incmdpos = 0;
  2278. X    } else if (inredir) {
  2279. X        incmdpos = oldpos;
  2280. X        inredir = 0;
  2281. X    }
  2282. X}
  2283. X
  2284. X#define LX1_BKSLASH 0
  2285. X#define LX1_COMMENT 1
  2286. X#define LX1_NEWLIN 2
  2287. X#define LX1_SEMI 3
  2288. X#define LX1_BANG 4
  2289. X#define LX1_AMPER 5
  2290. X#define LX1_BAR 6
  2291. SHAR_EOF
  2292. true || echo 'restore of zsh2.2/src/lex.c failed'
  2293. fi
  2294. echo 'End of zsh2.2 part 9'
  2295. echo 'File zsh2.2/src/lex.c is continued in part 10'
  2296. echo 10 > _shar_seq_.tmp
  2297. exit 0
  2298.  
  2299. exit 0 # Just in case...
  2300.