home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume29
/
zsh2.2
/
part09
< prev
next >
Wrap
Text File
|
1992-05-13
|
50KB
|
2,318 lines
Newsgroups: comp.sources.misc
From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
Subject: v29i105: zsh2.2 - The Z shell, Part09/17
Message-ID: <1992May13.160404.9847@sparky.imd.sterling.com>
X-Md4-Signature: d245b6fdbcbd95f7f7f27301a0db0e57
Date: Wed, 13 May 1992 16:04:04 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
Posting-number: Volume 29, Issue 105
Archive-name: zsh2.2/part09
Environment: BSD
Supersedes: zsh2.1: Volume 24, Issue 1-19
#!/bin/sh
# this is aa.09 (part 9 of zsh2.2)
# do not concatenate these parts, unpack them in order with /bin/sh
# file zsh2.2/src/hist.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 9; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping zsh2.2/src/hist.c'
else
echo 'x - continuing file zsh2.2/src/hist.c'
sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.2/src/hist.c' &&
X if (hlastw == hptr)
X zerr("hungetc attempted at buffer start",NULL,0);
X else {
X hptr--;
X if (*hptr == '!' && unset(NOBANGHIST)) hptr--;
X }
X }
X hungetch(c);
X}
X
Xvoid hungetch(c) /**/
Xint c;
X{
X if (lexstop)
X return;
X if (inbufct == inbufsz)
X {
X hungets(" ");
X *inbufptr = c;
X }
X else
X {
X *--inbufptr = c;
X inbufct++;
X }
X}
X
X/* begin reading a string */
X
Xvoid strinbeg() /**/
X{
X strin = 1;
X hbegin();
X lexinit();
X}
X
X/* done reading a string */
X
Xvoid strinend() /**/
X{
X strin = 0;
X isfirstch = 1;
X histdone = 0;
X hend();
X}
X
X/* stuff a whole file into the input queue and print it */
X
Xint stuff(fn) /**/
Xchar *fn;
X{
XFILE *in;
Xchar *buf;
Xint len;
X
X if (!(in = fopen(fn,"r")))
X {
X zerr("can't open %s",fn,0);
X return 1;
X }
X fseek(in,0,2);
X len = ftell(in);
X fseek(in,0,0);
X buf = alloc(len+1);
X if (!(fread(buf,len,1,in)))
X {
X zerr("read error on %s",fn,0);
X fclose(in);
X free(buf);
X return 1;
X }
X fclose(in);
X buf[len] = '\0';
X fwrite(buf,len,1,stdout);
X hungets(buf);
X return 0;
X}
X
X/* flush input queue */
X
Xvoid hflush() /**/
X{
X inbufptr += inbufct;
X inbufct = 0;
X}
X
X/* initialize the history mechanism */
X
Xvoid hbegin() /**/
X{
X isfirstln = isfirstch = 1;
X histremmed = errflag = histdone = spaceflag = 0;
X stophist = isset(NOBANGHIST) || unset(SHINSTDIN);
X lithist = isset(HISTLIT);
X hline = hptr = hp_alloc(&hp_lex,hlinesz = 16);
X curhistent = gethistent(curhist);
X if (!curhistent->ftim) curhistent->ftim = time(NULL);
X if (interact && isset(SHINSTDIN) && !strin) {
X inittty();
X defev = curhist++;
X if (curhist-histsiz >= 0) gethistent(curhist-histsiz)->lex = NULL;
X if (curhist-lithistsiz >= 0) gethistent(curhist-lithistsiz)->lit = NULL;
X curhistent = gethistent(curhist);
X hp_purge(hp_lex,curhist-histsiz);
X hp_purge(hp_lit,curhist-lithistsiz);
X curhistent->lex = hline;
X *(curhistent->lit = hp_alloc(&hp_lit,1)) = '\0';
X } else
X histremmed = 1;
X}
X
Xvoid inittty() /**/
X{
X attachtty(mypgrp);
X}
X
X/* say we're done using the history mechanism */
X
Xint hend() /**/
X{
Xint flag,save = 1;
XHistent he;
X
X if (!hline)
X return 1;
X if (!interact || strin || unset(SHINSTDIN)) {
X hp_free(hp_lex,hline,hlinesz);
X return 1;
X }
X flag = histdone;
X histdone = 0;
X if (hptr < hline+2)
X save = 0;
X else {
X char *s,*t;
X
X s = curhistent->lit;
X if (*s && *(t = s+strlen(s)-1) == HISTSPACE) *t = '\0';
X hptr[-1] = '\0';
X if (hptr[-2] == '\n')
X if (hline[1]) {
X if (hptr[-3] == HISTSPACE) hptr[-3] = '\0';
X } else save = 0;
X he = gethistent(curhist-1);
X if (!strcmp(hline,"\n") ||
X (isset(HISTIGNOREDUPS) && he->lex && !strcmp(he->lex,hline)) ||
X (isset(HISTIGNORESPACE) && spaceflag))
X save = 0;
X }
X if (flag & (HISTFLAG_DONE|HISTFLAG_RECALL)) {
X char *ptr,*p;
X p = ptr = ztrdup(hline);
X for (;*p;p++) if (*p == HISTSPACE) *p = ' ';
X if ((flag & (HISTFLAG_DONE|HISTFLAG_RECALL)) == HISTFLAG_DONE) {
X fprintf(stderr,"%s\n",ptr);
X fflush(stderr);
X }
X if (flag & HISTFLAG_RECALL) {
X permalloc();
X pushnode(bufstack,ptr);
X lastalloc();
X save = 0;
X } else free(ptr);
X }
X curhistent->stim = time(NULL);
X curhistent->ftim = 0L;
X if (!save) remhist();
X if (hline && !curhistent->lex) hp_free(hp_lex,hline,hlinesz);
X hline = NULL;
X return !(flag & HISTFLAG_NOEXEC || errflag);
X}
X
X/* remove the current line from the history List */
X
Xvoid remhist() /**/
X{
X if (!histremmed) { histremmed = 1; curhist--; }
X}
X
X/* begin a word */
X
Xvoid hwbegin() /**/
X{
X hlastw = hptr;
X}
X
X/* add a word to the history List */
X
Xchar *hwadd() /**/
X{
Xchar *ret = hlastw;
X
X if (hlastw && hline)
X {
X hwaddc(HISTSPACE);
X if (alstackind || strin)
X if (!(alstackind == 1 && !alstack[0]))
X hptr = hlastw;
X }
X if (alstat == ALSTAT_JUNK)
X alstat = 0;
X return ret;
X}
X
X/* get an argument specification */
X
Xint getargspec(argc,marg) /**/
Xint argc;int marg;
X{
Xint c,ret = -1;
X
X if ((c = hgetch()) == '0')
X return 0;
X if (idigit(c))
X {
X ret = 0;
X while (idigit(c))
X {
X ret = ret*10+c-'0';
X c = hgetch();
X }
X hungetch(c);
X }
X else if (c == '^')
X ret = 1;
X else if (c == '$')
X ret = argc;
X else if (c == '%')
X {
X if (marg == -1)
X {
X herrflush();
X zerr("%% with no previous word matched",NULL,0);
X return -2;
X }
X ret = marg;
X }
X else
X hungetch(c);
X return ret;
X}
X
X/* do ?foo? search */
X
Xint hconsearch(str,marg) /**/
Xchar *str;int *marg;
X{
Xint t0,t1 = 0;
Xchar *s,*hs;
X
X for (t0 = curhist-1; hs = quietgetevent(t0); t0--)
X if (s = ztrstr(hs,str)) {
X while (s != hs) if (*s-- == HISTSPACE) t1++;
X *marg = t1;
X return t0;
X }
X return -1;
X}
X
X/* do !foo search */
X
Xint hcomsearch(str) /**/
Xchar *str;
X{
Xint t0;
Xchar *hs;
X
X for (t0 = curhist-1; hs = quietgetevent(t0); t0--)
X if (!strncmp(hs,str,strlen(str))) return t0;
X return -1;
X}
X
X/* various utilities for : modifiers */
X
Xint remtpath(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if (cut = strrchr(str,'/')) {
X if (str != cut) *cut = '\0';
X else str[1] = '\0';
X return 1;
X }
X return 0;
X}
X
Xint remtext(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if ((cut = strrchr(str,'.')) && cut != str)
X {
X *cut = '\0';
X return 1;
X }
X return 0;
X}
X
Xint rembutext(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if ((cut = strrchr(str,'.')) && cut != str)
X {
X *junkptr = strdup(cut+1); /* .xx or xx? */
X return 1;
X }
X return 0;
X}
X
Xint remlpaths(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if (cut = strrchr(str,'/'))
X {
X *cut = '\0';
X *junkptr = strdup(cut+1);
X return 1;
X }
X return 0;
X}
X
Xint makeuppercase(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr;
X
X for (; *str; str++)
X *str = tuupper(*str);
X return 1;
X}
X
Xint makelowercase(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr;
X
X for (; *str; str++)
X *str = tulower(*str);
X return 1;
X}
X
Xvoid subst(strptr,in,out,gbal) /**/
Xchar **strptr;char *in;char *out;int gbal;
X{
Xchar *str = *strptr,*cut,*sptr;
Xint off;
X
X while (cut = (char *) ztrstr(str,in)) {
X *cut = '\0';
X sptr = convamps(out,in);
X off = cut-*strptr+strlen(sptr);
X cut += strlen(in);
X *strptr = tricat(*strptr,sptr,cut);
X if (gbal) {
X str = (char *) *strptr+off;
X continue;
X }
X break;
X }
X}
X
Xchar *convamps(out,in) /**/
Xchar *out;char *in;
X{
Xchar *ptr,*ret,*pp;
Xint slen,inlen = strlen(in);
X
X for (ptr = out, slen = 0; *ptr; ptr++,slen++)
X if (*ptr == '\\')
X ptr++;
X else if (*ptr == '&')
X slen += inlen-1;
X ret = pp = alloc(slen+1);
X for (ptr = out; *ptr; ptr++)
X if (*ptr == '\\')
X *pp++ = *++ptr;
X else if (*ptr == '&')
X {
X strcpy(pp,in);
X pp += inlen;
X }
X else
X *pp++ = *ptr;
X *pp = '\0';
X return ret;
X}
X
Xchar *makehstr(s) /**/
Xchar *s;
X{
Xchar *t;
X
X t = s = strdup(s);
X for (; *t; t++)
X if (*t == HISTSPACE)
X *t = ' ';
X return s;
X}
X
Xchar *quietgetevent(ev) /**/
Xint ev;
X{
XHistent ent;
X
X if (ev < firsthist()) return NULL;
X ent = gethistent(ev);
X return (lithist) ? ent->lit : ent->lex;
X}
X
Xchar *getevent(ev) /**/
Xint ev;
X{
Xchar *ret;
X
X ret = quietgetevent(ev);
X if (!ret) {
X herrflush();
X zerr("no such event: %d",NULL,ev);
X }
X return ret;
X}
X
Xint getargc(list) /**/
Xchar *list;
X{
Xint argc = 0;
X
X for (; *list; list++) if (*list == HISTSPACE) argc++;
X return argc;
X}
X
Xchar *getargs(elist,arg1,arg2) /**/
Xchar *elist;int arg1;int arg2;
X{
Xchar *ret = elist,*retn;
Xint acnt = arg2-arg1+1;
X
X while (arg1--)
X while (*ret && *ret++ != HISTSPACE);
X if (!*ret)
X {
X herrflush();
X zerr("no such word in event",NULL,0);
X return NULL;
X }
X retn = ret = strdup(ret);
X while (acnt > 0)
X {
X while (*ret && *ret != HISTSPACE)
X ret++;
X if (*ret == HISTSPACE)
X *ret = ' ';
X else
X break;
X acnt--;
X }
X if (acnt > 1 && !*ret)
X {
X herrflush();
X zerr("no such word in event",NULL,0);
X return NULL;
X }
X *ret = '\0';
X return retn;
X}
X
Xvoid upcase(x) /**/
Xchar **x;
X{
Xchar *pp = *(char **) x;
X
X for (; *pp; pp++)
X *pp = tuupper(*pp);
X}
X
Xvoid downcase(x) /**/
Xchar **x;
X{
Xchar *pp = *(char **) x;
X
X for (; *pp; pp++)
X *pp = tulower(*pp);
X}
X
Xint quote(tr) /**/
Xchar **tr;
X{
Xchar *ptr,*rptr,**str = (char **) tr;
Xint len = 3;
X
X for (ptr = *str; *ptr; ptr++,len++)
X if (*ptr == '\'') len += 3;
X ptr = *str;
X *str = rptr = alloc(len);
X *rptr++ = '\'';
X for (; *ptr; ptr++)
X if (*ptr == '\'') {
X *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
X } else
X *rptr++ = *ptr;
X *rptr++ = '\'';
X *rptr++ = 0;
X str[1] = NULL;
X return 0;
X}
X
Xint quotebreak(tr) /**/
Xchar **tr;
X{
Xchar *ptr,*rptr,**str = (char **) tr;
Xint len = 3;
X
X for (ptr = *str; *ptr; ptr++,len++)
X if (*ptr == '\'')
X len += 3;
X else if (inblank(*ptr))
X len += 2;
X ptr = *str;
X *str = rptr = alloc(len);
X *rptr++ = '\'';
X for (; *ptr; )
X if (*ptr == '\'') {
X *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
X ptr++;
X } else if (inblank(*ptr)) {
X *rptr++ = '\''; *rptr++ = *ptr++; *rptr++ = '\'';
X } else
X *rptr++ = *ptr++;
X *rptr++ = '\'';
X *rptr++ = '\0';
X return 0;
X}
X
Xvoid herrflush() /**/
X{
X if (strin)
X hflush();
X else while (lastc != '\n' && !lexstop)
X hgetch();
X}
X
X/* read an arbitrary amount of data into a buffer until stop is found */
X
Xchar *hdynread(stop) /**/
Xint stop;
X{
Xint bsiz = 256,ct = 0,c;
Xchar *buf = zalloc(bsiz),*ptr;
X
X ptr = buf;
X while ((c = hgetch()) != stop && c != '\n' && !lexstop)
X {
X if (c == '\\')
X c = hgetch();
X *ptr++ = c;
X if (++ct == bsiz)
X {
X buf = realloc(buf,bsiz *= 2);
X ptr = buf+ct;
X }
X }
X *ptr = 0;
X if (c == '\n')
X {
X hungetch('\n');
X zerr("delimiter expected",NULL,0);
X free(buf);
X return NULL;
X }
X return buf;
X}
X
Xchar *hdynread2(stop) /**/
Xint stop;
X{
Xint bsiz = 256,ct = 0,c;
Xchar *buf = zalloc(bsiz),*ptr;
X
X ptr = buf;
X while ((c = hgetch()) != stop && c != '\n' && !lexstop)
X {
X if (c == '\n')
X {
X hungetch(c);
X break;
X }
X if (c == '\\')
X c = hgetch();
X *ptr++ = c;
X if (++ct == bsiz)
X {
X buf = realloc(buf,bsiz *= 2);
X ptr = buf+ct;
X }
X }
X *ptr = 0;
X if (c == '\n')
X hungetch('\n');
X return buf;
X}
X
Xvoid inithist() /**/
X{
X hp_lit = zalloc(sizeof *hp_lit);
X hp_lit->next = NULL;
X hp_lit->ptr = hp_lit->pool = zalloc(HEAPSIZE);
X hp_lit->free = HEAPSIZE;
X hp_lex = zalloc(sizeof *hp_lex);
X hp_lex->next = NULL;
X hp_lex->ptr = hp_lex->pool = zalloc(HEAPSIZE);
X hp_lex->free = HEAPSIZE;
X histentct = (lithistsiz > histsiz) ? lithistsiz : histsiz;
X histentarr = zcalloc(histentct*sizeof *histentarr);
X}
X
Xvoid resizehistents() /**/
X{
Xint newentct,t0,t1,firstlit,firstlex;
XHistent newarr;
X
X newentct = (lithistsiz > histsiz) ? lithistsiz : histsiz;
X newarr = zcalloc(newentct*sizeof *newarr);
X firstlex = curhist-histsiz+1;
X firstlit = curhist-lithistsiz+1;
X t0 = firsthist();
X if (t0 < curhist-newentct) t0 = curhist-newentct;
X t1 = t0 % newentct;
X for (; t0 <= curhist; t0++) {
X newarr[t1] = *gethistent(t0);
X if (t0 < firstlex) newarr[t1].lex = NULL;
X if (t0 < firstlit) newarr[t1].lit = NULL;
X t1++; if (t1 == newentct) t1 = 0;
X }
X free(histentarr);
X histentarr = newarr;
X histentct = newentct;
X}
X
Xchar *hp_alloc(hp,siz) /**/
XHp *hp; int siz;
X{
Xchar *ret;
XHp h = *hp;
X
X if (h->free >= siz) {
X ret = h->ptr;
X h->ptr += siz;
X h->free -= siz;
X return ret;
X }
X#ifdef MEMDEBUG
X fprintf(stderr,"new heap (siz = %d, curhist = %d)\n",siz,curhist);
X#endif
X permalloc();
X h = zalloc(sizeof *h);
X h->next = *hp;
X h->free = (siz > HEAPSIZE) ? siz : HEAPSIZE;
X h->ptr = h->pool = zalloc(h->free);
X h->histno = curhist;
X *hp = h;
X heapalloc();
X return hp_alloc(hp,siz);
X}
X
Xchar *hp_realloc(hp,ptr,oldsiz,newsiz) /**/
XHp *hp; char *ptr; int oldsiz; int newsiz;
X{
XHp h = *hp;
Xint delta = newsiz-oldsiz;
Xchar *ret;
X
X if (h->ptr-oldsiz == ptr && h->free >= delta) {
X h->free -= delta;
X h->ptr += delta;
X return ptr;
X }
X#ifdef MEMDEBUG
X fprintf(stderr,"realloc copy\n");
X#endif
X memcpy(ret = hp_alloc(hp,newsiz),ptr,oldsiz);
X return ret;
X}
X
Xvoid hp_free(h,ptr,siz) /**/
XHp h; char *ptr; int siz;
X{
X if (h->ptr-siz == ptr) {
X h->free += siz;
X h->ptr -= siz;
X }
X}
X
Xchar *hp_concat(old,new) /**/
Xchar *old; char *new;
X{
Xint oldlen,newlen;
X
X oldlen = strlen(old); newlen = strlen(new);
X old = hp_realloc(&hp_lit,old,oldlen+1,oldlen+newlen+1);
X strcpy(old+oldlen,new);
X return old;
X}
X
Xvoid hp_purge(h,lim) /**/
XHp h; int lim;
X{
XHp hlast;
X
X if (!h->next) return;
X while (h->next) { hlast = h; h = h->next; }
X if (h->histno <= lim || h->histno == 0) {
X#ifdef MEMDEBUG
X fprintf(stderr,"purging %d\n",lim);
X#endif
X free(h->pool);
X free(h);
X hlast->next = NULL;
X }
X}
X
Xvoid readhistfile(s,err) /**/
Xchar *s;int err;
X{
Xchar buf[1024];
XFILE *in;
XHistent ent;
Xtime_t tim = time(NULL);
X
X if (!s) return;
X if (in = fopen(s,"r")) {
X while (fgets(buf,1024,in)) {
X int l = strlen(buf);
X char *pt = buf;
X
X while (l && buf[l-1] == '\n') {
X buf[l-1] = '\0';
X if (l > 1 && buf[l-2] == '\\') {
X buf[l-2] = '\n';
X fgets(buf+l-1,1024-(l-1),in);
X l = strlen(buf);
X } else break;
X }
X for (;*pt;pt++) if (*pt == ' ') *pt = HISTSPACE;
X
X ent = gethistent(++curhist);
X ent->lex = hp_alloc(&hp_lex,strlen(buf)+1);
X strcpy(ent->lex,buf);
X ent->lit = hp_alloc(&hp_lit,strlen(buf)+1);
X strcpy(ent->lit,buf);
X ent->ftim = ent->stim = tim;
X }
X fclose(in);
X } else if (err)
X zerr("can't read history file",s,0);
X}
X
Xvoid savehistfile(s,err,app) /**/
Xchar *s;int err;int app;
X{
Xchar *t;
XFILE *out;
Xint ev,flag;
X
X if (!s || !interact) return;
X ev = curhist-savehist+1;
X flag = (app) ? O_APPEND : O_TRUNC;
X if (ev < firsthist()) ev = firsthist();
X if (out = fdopen(open(s,O_CREAT|O_WRONLY|flag,0600),"w")) {
X for (; ev <= curhist; ev++) {
X t = quietgetevent(ev);
X for (; *t; t++)
X if (*t == HISTSPACE) fputc(' ',out);
X else {
X if (*t == '\n') fputc('\\',out);
X fputc(*t,out);
X }
X fputc('\n',out);
X }
X fclose(out);
X } else if (err) zerr("can't write history file: %s",s,0);
X}
X
Xint firsthist() /**/
X{
Xint ev;
XHistent ent;
X
X ev = curhist-histentct+1;
X if (ev < 1) ev = 1;
X do {
X ent = gethistent(ev);
X if ((lithist) ? ent->lit : ent->lex) break;
X ev++;
X } while (ev < curhist);
X return ev;
X}
X
SHAR_EOF
echo 'File zsh2.2/src/hist.c is complete' &&
chmod 0644 zsh2.2/src/hist.c ||
echo 'restore of zsh2.2/src/hist.c failed'
Wc_c="`wc -c < 'zsh2.2/src/hist.c'`"
test 23511 -eq "$Wc_c" ||
echo 'zsh2.2/src/hist.c: original size 23511, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.2/src/init.c ==============
if test -f 'zsh2.2/src/init.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.2/src/init.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.2/src/init.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/init.c' &&
X/*
X *
X * init.c - main loop and initialization routines
X *
X * This file is part of zsh, the Z shell.
X *
X * This software is Copyright 1992 by Paul Falstad
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made.
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk.
X *
X */
X
X#define GLOBALS
X#include "zsh.h"
X#include <pwd.h>
X
Xvoid main(argc,argv,envp) /**/
Xint argc; char **argv; char **envp;
X{
Xint notect = 0;
X
X#ifdef LC_ALL
X setlocale(LC_ALL, "");
X#endif
X environ = envp;
X meminit();
X setflags();
X parseargs(argv);
X setmoreflags();
X setupvals();
X initialize();
X heapalloc();
X runscripts();
X for(;;)
X {
X do
X loop();
X while (tok != ENDINPUT);
X if (!(isset(IGNOREEOF) && interact))
X {
X#if 0
X if (interact)
X fputs(islogin ? "logout\n" : "exit\n",stderr);
X#endif
X zexit(NULL);
X continue;
X }
X zerrnam("zsh",(!islogin) ? "use 'exit' to exit."
X : "use 'logout' to logout.",NULL,0);
X notect++;
X if (notect == 10)
X zexit(NULL);
X }
X}
X
X/* keep executing lists until EOF found */
X
Xvoid loop() /**/
X{
XList list;
XHeap h = (Heap) peekfirst(heaplist);
X
X pushheap();
X for(;;)
X {
X freeheap();
X if (interact && isset(SHINSTDIN))
X preprompt();
X hbegin(); /* init history mech */
X intr(); /* interrupts on */
X ainit(); /* init alias mech */
X lexinit();
X errflag = 0;
X if (!(list = parse_event()))
X { /* if we couldn't parse a list */
X hend();
X if (tok == ENDINPUT && !errflag)
X break;
X continue;
X }
X if (hend())
X {
X if (stopmsg) /* unset 'you have stopped jobs' flag */
X stopmsg--;
X execlist(list);
X }
X if (ferror(stderr))
X {
X zerr("write error",NULL,0);
X clearerr(stderr);
X }
X if (subsh) /* how'd we get this far in a subshell? */
X exit(lastval);
X if ((!interact && errflag) || retflag)
X break;
X if ((opts['t'] == OPT_SET) || (lastval && opts[ERREXIT] == OPT_SET))
X {
X if (sigtrapped[SIGEXIT])
X dotrap(SIGEXIT);
X exit(lastval);
X }
X }
X while ((Heap) peekfirst(heaplist) != h)
X popheap();
X}
X
Xvoid setflags() /**/
X{
Xint c;
X
X for (c = 0; c != 32; c++) opts[c] = OPT_UNSET;
X for (c = 32; c != 128; c++) opts[c] = OPT_INVALID;
X for (c = 'a'; c <= 'z'; c++) opts[c] = opts[c-'a'+'A'] = OPT_UNSET;
X for (c = '0'; c <= '9'; c++) opts[c] = OPT_UNSET;
X opts['A'] = OPT_INVALID;
X opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
X opts[BGNICE] = opts[NOTIFY] = OPT_SET;
X opts[USEZLE] = (interact && SHTTY != -1) ? OPT_SET : OPT_UNSET;
X opts[HASHCMDS] = opts[HASHLISTALL] = opts[HASHDIRS] = OPT_SET;
X}
X
Xstatic char *cmd;
X
Xvoid parseargs(argv) /**/
Xchar **argv;
X{
Xchar **x;
Xint bk = 0,action;
XLklist paramlist;
X
X hackzero = argzero = *argv;
X opts[LOGINSHELL] = (**(argv++) == '-') ? OPT_SET : OPT_UNSET;
X SHIN = 0;
X while (!bk && *argv && (**argv == '-' || **argv == '+'))
X {
X action = (**argv == '-') ? OPT_SET : OPT_UNSET;
X while (*++*argv) {
X if (opts[**argv] == OPT_INVALID) {
X zerr("bad option: -%c",NULL,**argv);
X exit(1);
X }
X if (bk = **argv == 'b') break;
X if (**argv == 'c') { /* -c command */
X argv++;
X if (!*argv) {
X zerr("string expected after -c",NULL,0);
X exit(1);
X }
X cmd = *argv;
X opts[INTERACTIVE] = OPT_UNSET;
X opts['c'] = OPT_SET;
X break;
X } else if (**argv == 'o') {
X int c;
X
X if (!*++*argv)
X argv++;
X if (!*argv) {
X zerr("string expected after -o",NULL,0);
X exit(1);
X }
X c = optlookup(*argv);
X if (c == -1)
X zerr("no such option: %s",*argv,0);
X else
X opts[c] = action;
X break;
X } else opts[**argv] = action;
X }
X argv++;
X }
X paramlist = newlist();
X if (*argv)
X {
X if (opts[SHINSTDIN] == OPT_UNSET)
X {
X SHIN = movefd(open(argzero = *argv,O_RDONLY));
X if (SHIN == -1)
X {
X zerr("can't open input file: %s",*argv,0);
X exit(1);
X }
X opts[INTERACTIVE] = OPT_UNSET;
X argv++;
X }
X while (*argv)
X addnode(paramlist,ztrdup(*argv++));
X }
X else
X opts[SHINSTDIN] = OPT_SET;
X pparams = x = zcalloc((countnodes(paramlist)+1)*sizeof(char *));
X while (*x++ = getnode(paramlist));
X free(paramlist);
X argzero = ztrdup(argzero);
X}
X
Xvoid setmoreflags() /**/
X{
Xint t0;
Xlong ttpgrp;
X
X /* stdout,stderr fully buffered */
X#ifdef _IOFBF
X setvbuf(stdout,malloc(BUFSIZ),_IOFBF,BUFSIZ);
X setvbuf(stderr,malloc(BUFSIZ),_IOFBF,BUFSIZ);
X#else
X setbuffer(stdout,malloc(BUFSIZ),BUFSIZ);
X setbuffer(stderr,malloc(BUFSIZ),BUFSIZ);
X#endif
X subsh = 0;
X#ifndef NOCLOSEFUNNYFDS
X /* this works around a bug in some versions of in.rshd */
X for (t0 = 3; t0 != 10; t0++)
X close(t0);
X#endif
X#ifdef JOB_CONTROL
X opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
X if (jobbing) {
X SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
X if (SHTTY == -1)
X opts[MONITOR] = OPT_UNSET;
X else {
X#ifdef TIOCSETD
X#ifdef NTTYDISC
X int ldisc = NTTYDISC;
X ioctl(SHTTY, TIOCSETD, &ldisc);
X#endif
X#endif
X gettyinfo(&shttyinfo); /* get tty state */
X#ifdef sgi
X if (shttyinfo.tio.c_cc[VSWTCH] <= 0) /* hack for irises */
X shttyinfo.tio.c_cc[VSWTCH] = CSWTCH;
X#endif
X savedttyinfo = shttyinfo;
X }
X#ifdef sgi
X setpgrp(0,getpgrp(0));
X#endif
X if ((mypgrp = getpgrp(0)) <= 0)
X opts[MONITOR] = OPT_UNSET;
X else while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
X sleep(1);
X mypgrp = getpgrp(0);
X if (mypgrp == gettygrp()) break;
X killpg(mypgrp,SIGTTIN);
X mypgrp = getpgrp(0);
X }
X } else
X SHTTY = -1;
X#else
X opts[MONITOR] = OPT_UNSET;
X SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
X if (SHTTY != -1) {
X gettyinfo(&shttyinfo);
X savedttyinfo = shttyinfo;
X }
X#endif
X}
X
Xvoid setupvals() /**/
X{
Xstruct passwd *pswd;
Xchar *ptr,*s;
Xstatic long bauds[] = {
X 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
X };
X
X curhist = 0;
X histsiz = DEFAULT_HISTSIZE;
X lithistsiz = 5;
X inithist();
X mailcheck = logcheck = 60;
X dirstacksize = -1;
X listmax = 100;
X reporttime = -1;
X bangchar = '!';
X hashchar = '#';
X hatchar = '^';
X termok = 0;
X curjob = prevjob = coprocin = coprocout = -1;
X shtimer = time(NULL); /* init $SECONDS */
X srand((unsigned int) shtimer);
X /* build various hash tables; argument to newhtable is table size */
X aliastab = newhtable(37);
X addreswords();
X paramtab = newhtable(151);
X cmdnamtab = newhtable(37);
X compctltab = newhtable(13);
X initxbindtab();
X nullcmd = ztrdup("cat");
X readnullcmd = ztrdup("more");
X prompt = ztrdup("%m%# ");
X prompt2 = ztrdup("> ");
X prompt3 = ztrdup("?# ");
X prompt4 = ztrdup("+ ");
X sprompt = ztrdup("zsh: correct `%R' to `%r' [nyae]? ");
X term = ztrdup("");
X ppid = getppid();
X#ifdef TIO
X#ifdef HAS_TCCRAP
X baud = cfgetospeed(&shttyinfo.tio);
X if (baud < 100) baud = bauds[baud]; /* aren't "standards" great?? */
X#else
X baud = bauds[shttyinfo.tio.c_cflag & CBAUD];
X#endif
X#else
X baud = bauds[shttyinfo.sgttyb.sg_ospeed];
X#endif
X#ifdef TIOCGWINSZ
X if (!(columns = shttyinfo.winsize.ws_col))
X columns = 80;
X if (!(lines = shttyinfo.winsize.ws_row))
X lines = 24;
X#else
X columns = 80;
X lines = 24;
X#endif
X ifs = ztrdup(" \t\n");
X if (pswd = getpwuid(getuid())) {
X username = ztrdup(pswd->pw_name);
X home = ztrdup(pswd->pw_dir);
X } else {
X username = ztrdup("");
X home = ztrdup("/");
X }
X if (ptr = zgetenv("LOGNAME"))
X logname = ztrdup(ptr);
X else
X logname = ztrdup(username);
X timefmt = ztrdup(DEFTIMEFMT);
X watchfmt = ztrdup(DEFWATCHFMT);
X if (!(ttystrname = ztrdup(ttyname(SHTTY))))
X ttystrname = ztrdup("");
X wordchars = ztrdup(DEFWORDCHARS);
X fceditparam = ztrdup(DEFFCEDIT);
X tmpprefix = ztrdup(DEFTMPPREFIX);
X postedit = ztrdup("");
X if (ispwd(home)) pwd = ztrdup(home);
X else if ((ptr = zgetenv("PWD")) && ispwd(ptr)) pwd = ztrdup(ptr);
X else pwd = zgetwd();
X oldpwd = ztrdup(pwd);
X hostnam = zalloc(256);
X underscore = ztrdup("");
X gethostname(hostnam,256);
X mypid = getpid();
X cdpath = mkarray(NULL);
X manpath = mkarray(NULL);
X fignore = mkarray(NULL);
X fpath = mkarray(NULL);
X mailpath = mkarray(NULL);
X watch = mkarray(NULL);
X hosts = mkarray(NULL);
X compctlsetup();
X userdirs = (char **) zcalloc(sizeof(char *)*2);
X usernames = (char **) zcalloc(sizeof(char *)*2);
X userdirsz = 2;
X userdirct = 0;
X optarg = ztrdup("");
X zoptind = 1;
X schedcmds = NULL;
X path = (char **) zalloc(4*sizeof *path);
X path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin");
X path[2] = ztrdup("/usr/ucb"); path[3] = NULL;
X inittyptab();
X initlextabs();
X setupparams();
X setparams();
X inittyptab();
X if ((s = zgetenv("EMACS")) && !strcmp(s,"t") && !strcmp(term,"emacs"))
X opts[USEZLE] = OPT_UNSET;
X#ifndef HAS_RUSAGE
X times(&shtms);
X#endif
X}
X
Xvoid compctlsetup() /**/
X{
Xstatic char
X *hs[] = {"telnet","rlogin","ftp","rup","rusers","rsh",NULL},
X *os[] = {"setopt","unsetopt",NULL},
X *vs[] = {"export","typeset","vared","unset",NULL},
X *cs[] = {"which","builtin",NULL},
X *bs[] = {"bindkey",NULL};
X
X compctl_process(hs,CC_HOSTS|CC_FILES,NULL);
X compctl_process(os,CC_OPTIONS,NULL);
X compctl_process(vs,CC_VARS,NULL);
X compctl_process(bs,CC_BINDINGS,NULL);
X compctl_process(cs,CC_COMMPATH,NULL);
X cc_compos.mask = CC_COMMPATH;
X cc_default.mask = CC_FILES;
X}
X
Xvoid initialize() /**/
X{
Xint t0;
X
X breaks = loops = 0;
X lastmailcheck = time(NULL);
X locallist = NULL;
X dirstack = newlist();
X bufstack = newlist();
X newcmdnamtab();
X inbuf = zalloc(inbufsz = 256);
X inbufptr = inbuf+inbufsz;
X inbufct = 0;
X#ifndef QDEBUG
X signal(SIGQUIT,SIG_IGN);
X#endif
X#ifdef RLIM_INFINITY
X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
X getrlimit(t0,limits+t0);
X#endif
X hsubl = hsubr = NULL;
X lastpid = 0;
X bshin = fdopen(SHIN,"r");
X signal(SIGCHLD,handler);
X if (jobbing)
X {
X int ttypgrp;
X for (;;)
X {
X#ifdef TIOCGPGRP
X ioctl(SHTTY, TIOCGPGRP, &ttypgrp);
X#else
X ttypgrp = tcgetpgrp(SHTTY);
X#endif
X if (ttypgrp == mypgrp)
X break;
X kill(0,SIGTTIN);
X }
X signal(SIGTTOU,SIG_IGN);
X signal(SIGTSTP,SIG_IGN);
X signal(SIGTTIN,SIG_IGN);
X signal(SIGPIPE,SIG_IGN);
X attachtty(mypgrp);
X }
X if (interact)
X {
X signal(SIGTERM,SIG_IGN);
X#ifdef SIGWINCH
X signal(SIGWINCH,handler);
X#endif
X signal(SIGALRM,handler);
X intr();
X }
X}
X
Xvoid addreswords() /**/
X{
Xstatic char *reswds[] = {
X "do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
X "if", "while", "function", "repeat", "time", "until", "exec", "command",
X "select", "coproc", "noglob", "-", "nocorrect", "foreach", "end", NULL
X };
Xint t0;
X
X for (t0 = 0; reswds[t0]; t0++)
X addhperm(reswds[t0],mkanode(NULL,-1-t0),aliastab,NULL);
X}
X
Xvoid runscripts() /**/
X{
X#ifdef GLOBALZSHENV
X source(GLOBALZSHENV);
X#endif
X if (opts[NORCS] == OPT_SET) {
X#ifdef GLOBALZPROFILE
X if (islogin) source(GLOBALZPROFILE);
X#endif
X#ifdef GLOBALZSHRC
X source(GLOBALZSHRC);
X#endif
X#ifdef GLOBALZLOGIN
X if (islogin) source(GLOBALZLOGIN);
X#endif
X } else {
X sourcehome(".zshenv");
X if (opts[NORCS] == OPT_SET)
X return;
X if (interact) {
X if (islogin) {
X sourcehome(".zprofile");
X#ifdef GLOBALZPROFILE
X source(GLOBALZPROFILE);
X#endif
X }
X#ifdef GLOBALZSHRC
X source(GLOBALZSHRC);
X#endif
X sourcehome(".zshrc");
X if (islogin) {
X#ifdef GLOBALZLOGIN
X source(GLOBALZLOGIN);
X#endif
X sourcehome(".zlogin");
X }
X }
X }
X if (interact)
X readhistfile(getsparam("HISTFILE"),0);
X if (opts['c'] == OPT_SET)
X {
X if (SHIN >= 10)
X close(SHIN);
X SHIN = movefd(open("/dev/null",O_RDONLY));
X execstring(cmd);
X stopmsg = 1;
X zexit(NULL);
X }
X#ifdef TIOCSWINSZ
X if (!(columns = shttyinfo.winsize.ws_col))
X columns = 80;
X if (!(lines = shttyinfo.winsize.ws_row))
X lines = 24;
X#endif
X}
X
Xvoid ainit() /**/
X{
X alstackind = 0; /* reset alias stack */
X alstat = 0;
X isfirstln = 1;
X}
X
SHAR_EOF
chmod 0644 zsh2.2/src/init.c ||
echo 'restore of zsh2.2/src/init.c failed'
Wc_c="`wc -c < 'zsh2.2/src/init.c'`"
test 11807 -eq "$Wc_c" ||
echo 'zsh2.2/src/init.c: original size 11807, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.2/src/jobs.c ==============
if test -f 'zsh2.2/src/jobs.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.2/src/jobs.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.2/src/jobs.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/jobs.c' &&
X/*
X *
X * jobs.c - job control
X *
X * This file is part of zsh, the Z shell.
X *
X * This software is Copyright 1992 by Paul Falstad
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made.
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk.
X *
X */
X
X#include "zsh.h"
X#include <sys/errno.h>
X
X/* != 0 means the handler is active */
X
Xstatic int handling = 0;
X
X#ifdef INTHANDTYPE
X#define RETURN return 0
X#else
X#define RETURN return
X#endif
X
X/* the signal handler */
X
XHANDTYPE handler(sig,code) /**/
Xint sig;int code;
X{
Xlong pid;
Xint statusp;
XJob jn;
Xstruct process *pn;
X#ifdef HAS_RUSAGE
Xstruct rusage ru;
X#else
Xlong chlds,chldu;
X#endif
X
X#ifdef RESETHANDNEEDED
X signal(sig,handler);
X#endif
X if (sig == SIGINT)
X {
X if (sigtrapped[SIGINT])
X dotrap(SIGINT);
X else
X errflag = 1;
X RETURN;
X }
X#ifdef SIGWINCH
X if (sig == SIGWINCH)
X adjustwinsize();
X#endif
X if (sig != SIGCHLD)
X {
X dotrap(sig);
X if (sig == SIGALRM && !sigtrapped[SIGALRM])
X {
X zerr("timeout",NULL,0);
X exit(1);
X }
X RETURN;
X }
X for (;;)
X {
X#ifdef HAS_RUSAGE
X pid = wait3((vptr) &statusp,WNOHANG|WUNTRACED,&ru);
X#else
X#ifndef WNOHANG
X pid = wait(&statusp);
X#else
X pid = wait3((vptr) &statusp,WNOHANG|WUNTRACED,NULL);
X#endif
X chlds = shtms.tms_cstime;
X chldu = shtms.tms_cutime;
X times(&shtms);
X#endif
X if (pid == -1)
X {
X if (errno != ECHILD)
X zerr("wait failed: %e",NULL,errno);
X RETURN;
X }
X if (!pid)
X RETURN;
X findproc(pid,&jn,&pn); /* find the process of this pid */
X if (jn)
X {
X pn->statusp = statusp;
X handling = 1;
X#ifdef HAS_RUSAGE
X pn->ti.ru = ru;
X#else
X pn->ti.st = shtms.tms_cstime-chlds;
X pn->ti.ut = shtms.tms_cutime-chldu;
X#endif
X pn->endtime = time(NULL);
X updatestatus(jn);
X handling = 0;
X }
X#if 0
X else if (WIFSTOPPED(statusp))
X kill(pid,SIGKILL); /* kill stopped untraced children */
X#endif
X }
X}
X
X/* change job table entry from stopped to running */
X
Xvoid makerunning(jn) /**/
XJob jn;
X{
Xstruct process *pn;
X
X jn->stat &= ~STAT_STOPPED;
X for (pn = jn->procs; pn; pn = pn->next)
X if (WIFSTOPPED(pn->statusp))
X pn->statusp = SP_RUNNING;
X}
X
X/* update status of job, possibly printing it */
X
Xvoid updatestatus(jn) /**/
XJob jn;
X{
Xstruct process *pn;
Xint notrunning = 1,alldone = 1,val,job = jn-jobtab,somestopped = 0;
X
X for (pn = jn->procs; pn; pn = pn->next)
X {
X if (pn->statusp == SP_RUNNING)
X notrunning = 0;
X if (pn->statusp == SP_RUNNING || WIFSTOPPED(pn->statusp))
X alldone = 0;
X if (WIFSTOPPED(pn->statusp))
X somestopped = 1;
X if (!pn->next && jn)
X val = (WIFSIGNALED(pn->statusp)) ?
X 0200 | WTERMSIG(pn->statusp) : WEXITSTATUS(pn->statusp);
X }
X if (!notrunning)
X return;
X if (somestopped && (jn->stat & STAT_STOPPED))
X return;
X jn->stat |= (alldone) ? STAT_CHANGED|STAT_DONE :
X STAT_CHANGED|STAT_STOPPED;
X if (alldone && job == thisjob)
X {
X if (!ttyfrozen && !val) {
X gettyinfo(&shttyinfo);
X if (interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))
X sanetty(&shttyinfo);
X#ifdef TIOCSWINSZ
X if (!(columns = shttyinfo.winsize.ws_col))
X columns = 80;
X lines = shttyinfo.winsize.ws_row;
X#endif
X } else
X settyinfo(&shttyinfo);
X lastval = val;
X }
X if ((jn->stat & (STAT_DONE|STAT_STOPPED)) == STAT_STOPPED) {
X prevjob = curjob;
X curjob = job;
X }
X if ((isset(NOTIFY) || job == thisjob) && jn->stat & STAT_LOCKED) {
X printjob(jn,!!isset(LONGLISTJOBS));
X if (zleactive) refresh();
X }
X if (sigtrapped[SIGCHLD] && job != thisjob)
X dotrap(SIGCHLD);
X}
X
X/* find process and job associated with pid */
X
Xvoid findproc(pid,jptr,pptr) /**/
Xint pid;Job *jptr;struct process **pptr;
X{
Xstruct process *pn;
Xint jn;
X
X for (jn = 1; jn != MAXJOB; jn++)
X for (pn = jobtab[jn].procs; pn; pn = pn->next)
X if (pn->pid == pid)
X {
X *pptr = pn;
X *jptr = jobtab+jn;
X return;
X }
X *pptr = NULL;
X *jptr = NULL;
X}
X
X/*
X lng = 0 means jobs
X lng = 1 means jobs -l
X lng = 2 means jobs -p
X*/
X
Xvoid printjob(jn,lng) /**/
XJob jn;int lng;
X{
Xint job = jn-jobtab,len = 9,sig = -1,sflag = 0,llen,printed = 0;
Xint conted = 0,lineleng = getlineleng(),skip = 0,doputnl = 0;
Xstruct process *pn;
X
X if (lng < 0)
X {
X conted = 1;
X lng = 0;
X }
X
X /* find length of longest signame, check to see if we
X really need to print this job */
X
X for (pn = jn->procs; pn; pn = pn->next)
X {
X if (pn->statusp != SP_RUNNING)
X if (WIFSIGNALED(pn->statusp))
X {
X sig = WTERMSIG(pn->statusp);
X llen = strlen(sigmsg[sig]);
X if (WCOREDUMPED(pn->statusp))
X llen += 14;
X if (llen > len)
X len = llen;
X if (sig != SIGINT && sig != SIGPIPE)
X sflag = 1;
X else if (sig == SIGINT)
X errflag = 1;
X if (job == thisjob && sig == SIGINT)
X doputnl = 1;
X }
X else if (WIFSTOPPED(pn->statusp))
X {
X sig = WSTOPSIG(pn->statusp);
X if (strlen(sigmsg[sig]) > len)
X len = strlen(sigmsg[sig]);
X if (job == thisjob && sig == SIGTSTP)
X doputnl = 1;
X }
X else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
X WEXITSTATUS(pn->statusp))
X sflag = 1;
X }
X
X /* print if necessary */
X
X if (interact && jobbing && ((jn->stat & STAT_STOPPED) || sflag ||
X job != thisjob))
X {
X int len2,fline = 1;
X struct process *qn;
X
X trashzle();
X if (doputnl)
X putc('\n',stderr);
X for (pn = jn->procs; pn;)
X {
X len2 = ((job == thisjob) ? 5 : 10)+len; /* 2 spaces */
X if (lng)
X qn = pn->next;
X else for (qn = pn->next; qn; qn = qn->next)
X {
X if (qn->statusp != pn->statusp)
X break;
X if (strlen(qn->text)+len2+((qn->next) ? 3 : 0) > lineleng)
X break;
X len2 += strlen(qn->text)+2;
X }
X if (job != thisjob)
X if (fline)
X fprintf(stderr,"[%d] %c ",jn-jobtab,(job == curjob) ? '+' :
X (job == prevjob) ? '-' : ' ');
X else
X fprintf(stderr,(job > 9) ? " " : " ");
X else
X fprintf(stderr,"zsh: ");
X if (lng)
X if (lng == 1)
X fprintf(stderr,"%d ",pn->pid);
X else
X {
X int x = jn->gleader;
X
X fprintf(stderr,"%d ",x);
X do skip++; while (x /= 10);
X skip++;
X lng = 0;
X }
X else
X fprintf(stderr,"%*s",skip,"");
X if (pn->statusp == SP_RUNNING)
X if (!conted)
X fprintf(stderr,"running%*s",len-7+2,"");
X else
X fprintf(stderr,"continued%*s",len-9+2,"");
X else if (WIFEXITED(pn->statusp))
X if (WEXITSTATUS(pn->statusp))
X fprintf(stderr,"exit %-4d%*s",WEXITSTATUS(pn->statusp),
X len-9+2,"");
X else
X fprintf(stderr,"done%*s",len-4+2,"");
X else if (WIFSTOPPED(pn->statusp))
X fprintf(stderr,"%-*s",len+2,sigmsg[WSTOPSIG(pn->statusp)]);
X else if (WCOREDUMPED(pn->statusp))
X fprintf(stderr,"%s (core dumped)%*s",
X sigmsg[WTERMSIG(pn->statusp)],
X len-14+2-strlen(sigmsg[WTERMSIG(pn->statusp)]),"");
X else
X fprintf(stderr,"%-*s",len+2,sigmsg[WTERMSIG(pn->statusp)]);
X for (; pn != qn; pn = pn->next)
X fprintf(stderr,(pn->next) ? "%s | " : "%s",pn->text);
X putc('\n',stderr);
X fline = 0;
X }
X printed = 1;
X }
X else if (doputnl && interact)
X putc('\n',stderr);
X fflush(stderr);
X
X /* print "(pwd now: foo)" messages */
X
X if (interact && job==thisjob && strcmp(jn->pwd,pwd))
X {
X printf("(pwd now: ");
X printdir(pwd);
X printf(")\n");
X fflush(stdout);
X }
X
X /* delete job if done */
X
X if (jn->stat & STAT_DONE)
X {
X static struct job zero;
X struct process *nx;
X char *s;
X
X if ((jn->stat & STAT_TIMED) || (reporttime != -1 && report(jn))) {
X dumptime(jn);
X printed = 1;
X }
X for (pn = jn->procs; pn; pn = nx)
X {
X nx = pn->next;
X free(pn);
X }
X free(jn->pwd);
X if (jn->filelist)
X {
X while (s = getnode(jn->filelist))
X {
X unlink(s);
X free(s);
X }
X free(jn->filelist);
X }
X *jn = zero;
X if (job == curjob)
X {
X curjob = prevjob;
X prevjob = job;
X }
X if (job == prevjob)
X setprevjob();
X }
X else
X jn->stat &= ~STAT_CHANGED;
X}
X
X/* set the previous job to something reasonable */
X
Xvoid setprevjob() /**/
X{
Xint t0;
X
X for (t0 = MAXJOB-1; t0; t0--)
X if ((jobtab[t0].stat & STAT_INUSE) && (jobtab[t0].stat & STAT_STOPPED) &&
X t0 != curjob && t0 != thisjob)
X break;
X if (!t0)
X for (t0 = MAXJOB-1; t0; t0--)
X if ((jobtab[t0].stat & STAT_INUSE) && t0 != curjob && t0 != thisjob)
X break;
X prevjob = (t0) ? t0 : -1;
X}
X
X/* initialize a job table entry */
X
Xvoid initjob() /**/
X{
X jobtab[thisjob].pwd = ztrdup(pwd);
X jobtab[thisjob].stat = STAT_INUSE;
X jobtab[thisjob].gleader = 0;
X}
X
X/* add a process to the current job */
X
Xstruct process *addproc(pid,text) /**/
Xlong pid;char *text;
X{
Xstruct process *process;
X
X if (!jobtab[thisjob].gleader) jobtab[thisjob].gleader = pid;
X process = zcalloc(sizeof *process);
X process->pid = pid;
X if (text) strcpy(process->text,text);
X else *process->text = '\0';
X process->next = NULL;
X process->statusp = SP_RUNNING;
X process->bgtime = time(NULL);
X if (jobtab[thisjob].procs) {
X struct process *n;
X for (n = jobtab[thisjob].procs; n->next; n = n->next);
X process->next = NULL;
X n->next = process;
X } else jobtab[thisjob].procs = process;
X return process;
X}
X
X/* determine if it's all right to exec a command without
X forking in last component of subshells; it's not ok if we have files
X to delete */
X
Xint execok() /**/
X{
XJob jn;
X
X if (!exiting)
X return 0;
X for (jn = jobtab+1; jn != jobtab+MAXJOB; jn++)
X if (jn->stat && jn->filelist)
X return 0;
X return 1;
X
X}
X
Xvoid waitforpid(pid) /**/
Xlong pid;
X{
X while (!errflag && (kill(pid,0) >= 0 || errno != ESRCH)) chldsuspend();
X}
X
X/* wait for a job to finish */
X
Xvoid waitjob(job) /**/
Xint job;
X{
Xstatic struct job zero;
XJob jn;
X
X if (jobtab[job].procs) /* if any forks were done */
X {
X jobtab[job].stat |= STAT_LOCKED;
X if (jobtab[job].stat & STAT_CHANGED)
X printjob(jobtab+job,!!isset(LONGLISTJOBS));
X while (jobtab[job].stat &&
X !(jobtab[job].stat & (STAT_DONE|STAT_STOPPED)))
X chldsuspend();
X }
X else /* else do what printjob() usually does */
X {
X char *s;
X
X jn = jobtab+job;
X free(jn->pwd);
X if (jn->filelist)
X {
X while (s = getnode(jn->filelist))
X {
X unlink(s);
X free(s);
X }
X free(jn->filelist);
X }
X *jn = zero;
X }
X}
X
X/* wait for running job to finish */
X
Xvoid waitjobs() /**/
X{
X waitjob(thisjob);
X thisjob = -1;
X}
X
X/* clear job table when entering subshells */
X
Xvoid clearjobtab() /**/
X{
Xstatic struct job zero;
Xint t0;
X
X for (t0 = 1; t0 != MAXJOB; t0++)
X jobtab[thisjob] = zero;
X}
X
X/* get a free entry in the job table to use */
X
Xint getfreejob() /**/
X{
Xint t0;
X
X for (t0 = 1; t0 != MAXJOB; t0++)
X if (!jobtab[t0].stat) {
X jobtab[t0].stat |= STAT_INUSE;
X return t0;
X }
X zerr("job table full or recursion limit exceeded",NULL,0);
X return -1;
X}
X
X/* print pids for & */
X
Xvoid spawnjob() /**/
X{
Xstruct process *pn;
X
X if (!subsh)
X {
X if (curjob == -1 || !(jobtab[curjob].stat & STAT_STOPPED))
X {
X curjob = thisjob;
X setprevjob();
X }
X else if (prevjob == -1 || !(jobtab[prevjob].stat & STAT_STOPPED))
X prevjob = thisjob;
X if (interact && jobbing && jobtab[thisjob].procs)
X {
X fprintf(stderr,"[%d]",thisjob);
X for (pn = jobtab[thisjob].procs; pn; pn = pn->next)
X fprintf(stderr," %d",pn->pid);
X fprintf(stderr,"\n");
X fflush(stderr);
X }
X }
X if (!jobtab[thisjob].procs)
X {
X char *s;
X static struct job zero;
X struct job *jn;
X
X jn = jobtab+thisjob;
X free(jn->pwd);
X if (jn->filelist)
X {
X while (s = getnode(jn->filelist))
X {
X unlink(s);
X free(s);
X }
X free(jn->filelist);
X }
X *jn = zero;
X }
X else
X jobtab[thisjob].stat |= STAT_LOCKED;
X thisjob = -1;
X}
X
Xvoid fixsigs() /**/
X{
X unblockchld();
X}
X
Xint report(j) /**/
XJob j;
X{
X if (!j->procs) return 0;
X#ifdef HAS_RUSAGE
X return (j->procs->ti.ru.ru_utime.tv_sec+j->procs->ti.ru.ru_stime.tv_sec)
X >= reporttime;
X#else
X return (j->procs->ti.ut+j->procs->ti.st)/HZ >= reporttime;
X#endif
X}
X
Xvoid printtime(real,ti,desc) /**/
Xtime_t real;struct timeinfo *ti;char *desc;
X{
Xchar *s;
X#ifdef sun
Xlong ticks = 1;
Xint pk = getpagesize()/1024;
X#else
Xlong sec;
X#endif
X#ifdef HAS_RUSAGE
Xstruct rusage *ru = &ti->ru;
X#endif
X
X if (!desc) desc = "";
X#ifdef HAS_RUSAGE
X#ifdef sun
X ticks = (ru->ru_utime.tv_sec+ru->ru_stime.tv_sec)*HZ+
X (ru->ru_utime.tv_usec+ru->ru_stime.tv_usec)*HZ/1000000;
X if (!ticks) ticks = 1;
X#else
X sec = ru->ru_utime.tv_sec + ru->ru_stime.tv_sec;
X if (!sec) sec = 1;
X#endif
X#endif
X for (s = timefmt; *s; s++)
X if (*s == '%')
X switch(s++,*s)
X {
X case 'E': fprintf(stderr,"%lds",real); break;
X#ifndef HAS_RUSAGE
X case 'U': fprintf(stderr,"%ld.%03lds",
X ti->ut/HZ,ti->ut*1000/60%1000); break;
X case 'S': fprintf(stderr,"%ld.%03lds",
X ti->st/HZ,ti->st*1000/60%1000); break;
X case 'P':
X if (real)
X fprintf(stderr,"%d%%",
X (int) (100*((ti->ut+ti->st)/HZ))/real);
X break;
X#else
X case 'U': fprintf(stderr,"%ld.%03lds",
X ru->ru_utime.tv_sec,ru->ru_utime.tv_usec/1000); break;
X case 'S': fprintf(stderr,"%ld.%03lds",
X ru->ru_stime.tv_sec,ru->ru_stime.tv_usec/1000); break;
X case 'P':
X if (real)
X fprintf(stderr,"%d%%",
X (int) (100*(ru->ru_utime.tv_sec+ru->ru_stime.tv_sec))
X / real);
X break;
X case 'W': fprintf(stderr,"%ld",ru->ru_nswap); break;
X#ifdef sun
X case 'K': case 'D':
X fprintf(stderr,"%ld",ru->ru_idrss/ticks*pk); break;
X case 'M': fprintf(stderr,"%ld",ru->ru_maxrss*pk); break;
X#else
X case 'X': fprintf(stderr,"%ld",ru->ru_ixrss/sec); break;
X case 'D': fprintf(stderr,"%ld",
X (ru->ru_idrss+ru->ru_isrss)/sec); break;
X case 'K': fprintf(stderr,"%ld",
X (ru->ru_ixrss+ru->ru_idrss+ru->ru_isrss)/sec); break;
X case 'M': fprintf(stderr,"%ld",ru->ru_maxrss/1024); break;
X#endif
X case 'F': fprintf(stderr,"%ld",ru->ru_majflt); break;
X case 'R': fprintf(stderr,"%ld",ru->ru_minflt); break;
X case 'I': fprintf(stderr,"%ld",ru->ru_inblock); break;
X case 'O': fprintf(stderr,"%ld",ru->ru_oublock); break;
X case 'r': fprintf(stderr,"%ld",ru->ru_msgrcv); break;
X case 's': fprintf(stderr,"%ld",ru->ru_msgsnd); break;
X case 'k': fprintf(stderr,"%ld",ru->ru_nsignals); break;
X case 'w': fprintf(stderr,"%ld",ru->ru_nvcsw); break;
X case 'c': fprintf(stderr,"%ld",ru->ru_nivcsw); break;
X#endif
X case 'J': fprintf(stderr,"%s",desc); break;
X default: fprintf(stderr,"%%%c",*s); break;
X }
X else
X putc(*s,stderr);
X putc('\n',stderr);
X fflush(stderr);
X}
X
Xvoid dumptime(jn) /**/
XJob jn;
X{
Xstruct process *pn = jn->procs;
X
X if (!jn->procs)
X return;
X for (pn = jn->procs; pn; pn = pn->next)
X printtime(pn->endtime-pn->bgtime,&pn->ti,pn->text);
X}
X
Xvoid shelltime() /**/
X{
Xstruct timeinfo ti;
X#ifdef HAS_RUSAGE
Xstruct rusage ru;
X
X getrusage(RUSAGE_SELF,&ru);
X memcpy(&ti.ru,&ru,sizeof(ru));
X printtime(time(NULL)-shtimer,&ti,"shell");
X
X getrusage(RUSAGE_CHILDREN,&ru);
X memcpy(&ti.ru,&ru,sizeof(ru));
X printtime(time(NULL)-shtimer,&ti,"children");
X#else
Xstruct tms buf;
X
X times(&buf);
X ti.ut = buf.tms_utime;
X ti.st = buf.tms_stime;
X printtime(time(NULL)-shtimer,&ti,"shell");
X ti.ut = buf.tms_cutime;
X ti.st = buf.tms_cstime;
X printtime(time(NULL)-shtimer,&ti,"children");
X#endif
X}
X
X/* SIGHUP any jobs left running */
X
Xvoid killrunjobs() /**/
X{
Xint t0,killed = 0;
X
X if (isset(NOHUP)) return;
X for (t0 = 1; t0 != MAXJOB; t0++)
X if (t0 != thisjob && (jobtab[t0].stat & STAT_LOCKED) &&
X !(jobtab[t0].stat & STAT_STOPPED)) {
X if (killpg(jobtab[t0].gleader,SIGHUP) != -1) killed++;
X }
X if (killed) zerr("warning: %d jobs SIGHUPed",NULL,killed);
X}
X
X/* check to see if user has jobs running/stopped */
X
Xvoid checkjobs() /**/
X{
Xint t0;
X
X scanjobs();
X for (t0 = 1; t0 != MAXJOB; t0++)
X if (t0 != thisjob && jobtab[t0].stat & STAT_LOCKED)
X break;
X if (t0 != MAXJOB) {
X if (jobtab[t0].stat & STAT_STOPPED) {
X#ifdef USE_SUSPENDED
X zerr("you have suspended jobs.",NULL,0);
X#else
X zerr("you have stopped jobs.",NULL,0);
X#endif
X } else
X zerr("you have running jobs.",NULL,0);
X stopmsg = 1;
X }
X}
X
X/* send a signal to a job (simply involves kill if monitoring is on) */
X
Xint killjb(jn,sig) /**/
XJob jn;int sig;
X{
Xstruct process *pn;
Xint err;
X
X if (jobbing)
X return(killpg(jn->gleader,sig));
X for (pn = jn->procs; pn; pn = pn->next)
X if ((err = kill(pn->pid,sig)) == -1 && errno != ESRCH)
X return -1;
X return err;
X}
X
SHAR_EOF
chmod 0644 zsh2.2/src/jobs.c ||
echo 'restore of zsh2.2/src/jobs.c failed'
Wc_c="`wc -c < 'zsh2.2/src/jobs.c'`"
test 16421 -eq "$Wc_c" ||
echo 'zsh2.2/src/jobs.c: original size 16421, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.2/src/lex.c ==============
if test -f 'zsh2.2/src/lex.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.2/src/lex.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.2/src/lex.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/lex.c' &&
X/*
X *
X * lex.c - lexical analysis
X *
X * This file is part of zsh, the Z shell.
X *
X * This software is Copyright 1992 by Paul Falstad
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made.
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk.
X *
X */
X
X#include "zsh.h"
X
X/* lexical state */
X
Xstatic int xincmdpos,xincond,xincasepat,dbparens,xdbparens,xalstat;
Xstatic char *xhlastw;
X
Xstatic int xisfirstln, xisfirstch, xhistremmed, xhistdone,
X xspaceflag, xstophist, xlithist, xalstackind,xhlinesz;
Xstatic char *xhline, *xhptr;
X
X/* save the lexical state */
X
X/* is this a hack or what? */
X
Xvoid lexsave() /**/
X{
X xincmdpos = incmdpos;
X xincond = incond;
X xincasepat = incasepat;
X xdbparens = dbparens;
X xalstat = alstat;
X xalstackind = alstackind;
X xisfirstln = isfirstln;
X xisfirstch = isfirstch;
X xhistremmed = histremmed;
X xhistdone = histdone;
X xspaceflag = spaceflag;
X xstophist = stophist;
X xlithist = lithist;
X xhline = hline;
X xhptr = hptr;
X xhlastw = hlastw;
X xhlinesz = hlinesz;
X inredir = 0;
X}
X
X/* restore lexical state */
X
Xvoid lexrestore() /**/
X{
X incmdpos = xincmdpos;
X incond = xincond;
X incasepat = xincasepat;
X dbparens = xdbparens;
X alstat = xalstat;
X isfirstln = xisfirstln;
X isfirstch = xisfirstch;
X histremmed = xhistremmed;
X histdone = xhistdone;
X spaceflag = xspaceflag;
X stophist = xstophist;
X lithist = xlithist;
X hline = xhline;
X hptr = xhptr;
X hlastw = xhlastw;
X clearalstack();
X alstackind = xalstackind;
X hlinesz = xhlinesz;
X lexstop = errflag = 0;
X}
X
Xvoid yylex() /**/
X{
X if (tok == LEXERR) return;
X do
X tok = gettok();
X while (tok != ENDINPUT && exalias());
X if (tok != NEWLIN) isnewlin = 0;
X else isnewlin = (inbufct) ? -1 : 1;
X if (tok == SEMI || tok == NEWLIN) tok = SEPER;
X}
X
Xvoid ctxtlex() /**/
X{
Xstatic int oldpos;
X
X yylex();
X switch (tok) {
X case SEPER: case NEWLIN: case SEMI: case DSEMI: case AMPER:
X case INPAR: case INBRACE: case DBAR: case DAMPER: case BAR:
X case BARAMP: case INOUTPAR: case DO: case THEN: case ELIF:
X case ELSE: incmdpos = 1; break;
X case STRING: /* case ENVSTRING: */ case ENVARRAY: case OUTPAR:
X case CASE: incmdpos = 0; break;
X }
X if (IS_REDIROP(tok) || tok == FOR || tok == FOREACH || tok == SELECT) {
X inredir = 1;
X oldpos = incmdpos;
X incmdpos = 0;
X } else if (inredir) {
X incmdpos = oldpos;
X inredir = 0;
X }
X}
X
X#define LX1_BKSLASH 0
X#define LX1_COMMENT 1
X#define LX1_NEWLIN 2
X#define LX1_SEMI 3
X#define LX1_BANG 4
X#define LX1_AMPER 5
X#define LX1_BAR 6
SHAR_EOF
true || echo 'restore of zsh2.2/src/lex.c failed'
fi
echo 'End of zsh2.2 part 9'
echo 'File zsh2.2/src/lex.c is continued in part 10'
echo 10 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...