pfalstad@phoenix.princeton.edu (Paul Falstad) (04/24/91)
Submitted-by: Paul Falstad <pfalstad@phoenix.princeton.edu> Posting-number: Volume 18, Issue 88 Archive-name: zsh2.00/part05 #!/bin/sh # this is zsh2.00.00.shar.05 (part 5 of zsh2.00.00) # do not concatenate these parts, unpack them in order with /bin/sh # file zsh2.00/src/cond.c continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 5; 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.00/src/cond.c' else echo 'x - continuing file zsh2.00/src/cond.c' sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.00/src/cond.c' && X X cond.c - evaluate conditional expressions X X This file is part of zsh, the Z shell. X X zsh is free software; no one can prevent you from reading the source X code, or giving it to someone else. X X This file is copyrighted under the GNU General Public License, which X can be found in the file called COPYING. X X Copyright (C) 1990, 1991 Paul Falstad X X zsh is distributed in the hope that it will be useful, but X WITHOUT ANY WARRANTY. No author or distributor accepts X responsibility to anyone for the consequences of using it or for X whether it serves any particular purpose or works at all, unless he X says so in writing. Refer to the GNU General Public License X for full details. X X Everyone is granted permission to copy, modify and redistribute X zsh, but only under the conditions described in the GNU General Public X License. A copy of this license is supposed to have been given to you X along with zsh so you can know your rights and responsibilities. X It should be in a file named COPYING. X X Among other things, the copyright notice and this notice must be X preserved on all copies. X X*/ X X#include "zsh.h" X#include "funcs.h" X X#ifndef F_OK X#define F_OK 00 X#define R_OK 04 X#define W_OK 02 X#define X_OK 01 X#endif X Xint evalcond(c) /**/ XCond c; X{ Xstruct stat *st; X X switch (c->type) X { X case COND_NOT: return !evalcond(c->left); X case COND_AND: return evalcond(c->left) && evalcond(c->right); X case COND_OR: return evalcond(c->left) || evalcond(c->right); X } X singsub((char **) &c->left); X if (c->right) X singsub((char **) &c->right); X switch (c->type) X { X case COND_STREQ: return matchpat(c->left,c->right); X case COND_STRNEQ: return !matchpat(c->left,c->right); X case COND_STRLT: return strcmp(c->left,c->right) < 0; X case COND_STRGTR: return strcmp(c->left,c->right) > 0; X case 'a': return(doaccess(c->left,F_OK)); X case 'b': return(S_ISBLK(dostat(c->left))); X case 'c': return(S_ISCHR(dostat(c->left))); X case 'd': return(S_ISDIR(dostat(c->left))); X case 'f': return(S_ISREG(dostat(c->left))); X case 'g': return(!!(dostat(c->left) & S_ISGID)); X case 'k': return(!!(dostat(c->left) & S_ISVTX)); X case 'n': return(!strlen(c->left)); X case 'o': return(optison(c->left)); X case 'p': return(S_ISFIFO(dostat(c->left))); X case 'r': return(doaccess(c->left,R_OK)); X case 's': return((st = getstat(c->left)) && !!(st->st_size)); X case 'S': return(S_ISSOCK(dostat(c->left))); X case 'u': return(!!(dostat(c->left) & S_ISUID)); X case 'w': return(doaccess(c->left,W_OK)); X case 'x': return(doaccess(c->left,X_OK)); X case 'z': return(!!strlen(c->left)); X case 'L': return(S_ISLNK(dostat(c->left))); X case 'O': return((st = getstat(c->left)) && st->st_uid == geteuid()); X case 'G': return((st = getstat(c->left)) && st->st_gid == getegid()); X case 't': return isatty(matheval(c->left)); X case COND_EQ: return matheval(c->left) == matheval(c->right); X case COND_NE: return matheval(c->left) != matheval(c->right); X case COND_LT: return matheval(c->left) < matheval(c->right); X case COND_GT: return matheval(c->left) > matheval(c->right); X case COND_LE: return matheval(c->left) <= matheval(c->right); X case COND_GE: return matheval(c->left) >= matheval(c->right); X case COND_NT: case COND_OT: X { X time_t a; X if (!(st = getstat(c->left))) X return 0; X a = st->st_mtime; X if (!(st = getstat(c->right))) X return 0; X return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime; X } X case COND_EF: X { X dev_t d; X ino_t i; X X if (!(st = getstat(c->left))) X return 0; X d = st->st_dev; X i = st->st_ino; X if (!(st = getstat(c->right))) X return 0; X return d == st->st_dev && i == st->st_ino; X } X default: zerr("bad cond structure",NULL,0); X } X return 0; X} X Xint doaccess(s,c) /**/ Xchar *s;int c; X{ X return !access(s,c); X} X Xstruct stat *getstat(s) /**/ Xchar *s; X{ Xstatic struct stat st; X X if (!strncmp(s,"/dev/fd/",8)) X { X if (fstat(atoi(s+8),&st)) X return NULL; X } X else if (lstat(s,&st)) X return NULL; X return &st; X} X Xunsigned short dostat(s) /**/ Xchar *s; X{ Xstruct stat *st; X X if (!(st = getstat(s))) X return 0; X return st->st_mode; X} X Xint optison(s) /**/ Xchar *s; X{ Xint i; X X if (strlen(s) == 1) X return opts[*s]; X if ((i = optlookup(s)) != -1) X return opts[i]; X zerr("no such option: %s",s,0); X return 0; X} X SHAR_EOF echo 'File zsh2.00/src/cond.c is complete' && chmod 0644 zsh2.00/src/cond.c || echo 'restore of zsh2.00/src/cond.c failed' Wc_c="`wc -c < 'zsh2.00/src/cond.c'`" test 4322 -eq "$Wc_c" || echo 'zsh2.00/src/cond.c: original size 4322, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/cond.pro ============== if test -f 'zsh2.00/src/cond.pro' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/cond.pro (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/cond.pro (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/cond.pro' && Xint evalcond DCLPROTO((Cond c)); Xint doaccess DCLPROTO((char *s,int c)); Xstruct stat *getstat DCLPROTO((char *s)); Xunsigned short dostat DCLPROTO((char *s)); Xint optison DCLPROTO((char *s)); SHAR_EOF chmod 0644 zsh2.00/src/cond.pro || echo 'restore of zsh2.00/src/cond.pro failed' Wc_c="`wc -c < 'zsh2.00/src/cond.pro'`" test 191 -eq "$Wc_c" || echo 'zsh2.00/src/cond.pro: original size 191, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/exec.c ============== if test -f 'zsh2.00/src/exec.c' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/exec.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/exec.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/exec.c' && X/* X X exec.c - command execution X X This file is part of zsh, the Z shell. X X zsh is free software; no one can prevent you from reading the source X code, or giving it to someone else. X X This file is copyrighted under the GNU General Public License, which X can be found in the file called COPYING. X X Copyright (C) 1990, 1991 Paul Falstad X X zsh is distributed in the hope that it will be useful, but X WITHOUT ANY WARRANTY. No author or distributor accepts X responsibility to anyone for the consequences of using it or for X whether it serves any particular purpose or works at all, unless he X says so in writing. Refer to the GNU General Public License X for full details. X X Everyone is granted permission to copy, modify and redistribute X zsh, but only under the conditions described in the GNU General Public X License. A copy of this license is supposed to have been given to you X along with zsh so you can know your rights and responsibilities. X It should be in a file named COPYING. X X Among other things, the copyright notice and this notice must be X preserved on all copies. X X*/ X X#include "zsh.h" X#include "funcs.h" X#include <sys/errno.h> X#include <sys/dir.h> X X#define execerr() { if (forked) exit(1); \ X closemnodes(mfds); errflag = 1; return; } X X/* parse list in a string */ X XList parselstring(s) /**/ Xchar *s; X{ XList l; X X hungets(s); X strinbeg(); X pushheap(); X if (!(l = parlist())) X { X strinend(); X hflush(); X popheap(); X return NULL; X } X strinend(); X return l; X} X X/* execute a string */ X Xvoid execstring(s) /**/ Xchar *s; X{ XList l; X X if (l = parselstring(s)) X { X execlist(l); X popheap(); X } X} X X/* duplicate a list and run it */ X Xvoid newrunlist(l) /**/ XList l; X{ X List a = dupstruct(l); runlist(a); X} X X/* fork and set limits */ X Xint phork() /**/ X{ Xint pid = fork(),t0; X X if (pid == -1) X { X zerr("fork failed: %e",NULL,errno); X return -1; X } X if (!pid) X for (t0 = 0; t0 != RLIM_NLIMITS; t0++) X setrlimit(t0,limits+t0); X return pid; X} X X/* execute a current shell command */ X Xint execcursh(cmd) /**/ XCmd cmd; X{ X runlist(cmd->u.list); X cmd->u.list = NULL; X return lastval; X} X X/* execve after handling $_ and #! */ X Xvoid zexecve(pth,argv,ee,b1,b2) /**/ Xchar *pth;char **argv;int *ee;char *b1;char *b2; X{ Xint eno; Xchar buf[MAXPATHLEN*2]; Xchar **eep; X X for (eep = environ; *eep; eep++) X if (**eep == '_' && (*eep)[1] == '=') X break; X buf[0] = '_'; X buf[1] = '='; X if (*pth == '/') X strcpy(buf+2,pth); X else X sprintf(buf+2,"%s/%s",cwd,pth); X if (!*eep) X eep[1] = NULL; X *eep = buf; X execve(pth,argv,environ); X if ((eno = errno) == ENOEXEC) X { X char buf[33],*ptr,*ptr2,*argv0; X int fd,ct,t0; X X if ((fd = open(pth,O_RDONLY)) >= 0) X { X argv0 = *argv; X *argv = pth; X ct = read(fd,buf,32); X close(fd); X if (ct > 0) X { X if (buf[0] == '#') X if (buf[1] == '!') X { X for (t0 = 0; t0 != ct; t0++) X if (buf[t0] == '\n') X buf[t0] = '\0'; X buf[32] = '\0'; X for (ptr = buf+2; *ptr && *ptr == ' '; ptr++); X for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++); X if (*ptr) X { X *ptr = '\0'; X argv[-2] = ptr2; X argv[-1] = ptr+1; X execve(ptr2,argv-2,environ); X } X else X { X argv[-1] = ptr2; X execve(ptr2,argv-1,environ); X } X } X else X { X argv[-1] = MYSELF; X execve(MYSELF,argv-1,environ); X } X else X { X for (t0 = 0; t0 != ct; t0++) X if (!buf[t0]) X break; X if (t0 == ct) X { X argv[-1] = "/bin/sh"; X execve("/bin/sh",argv-1,environ); X } X } X } X else X eno = errno; X *argv = argv0; X } X else X eno = errno; X } X if (ee && eno != ENOENT) X { X *ee = eno; X strcpy(b1,b2); X } X} X X#define MAXCMDLEN (MAXPATHLEN*4) X X/* execute an external command */ X Xvoid execute(args,dash) /**/ XLklist args;int dash; X{ Xchar **argv,*arg0; Xchar *z,*s,buf[MAXCMDLEN],buf2[MAXCMDLEN]; XCmdnam cn; Xint tl,ee = 0; X X cn = gethnode(peekfirst(args),cmdnamtab); X if (s = zgetenv("STTY")) X zyztem("stty",s); X arg0 = peekfirst(args); X if (z = zgetenv("ARGV0")) X { X setdata(firstnode(args),ztrdup(z)); X delenv(z-6); X } X else if (dash) X { X sprintf(buf2,"-%s",arg0); X setdata(firstnode(args),ztrdup(buf2)); X } X argv = makecline(args); X fixsigs(); X if (cn && (cn->type != BUILTIN && cn->type != SHFUNC)) X { X if (cn->type == EXCMD_POSTDOT) X zexecve(arg0,argv,&ee,buf2,buf); X zexecve(cn->u.nam,argv,&ee,buf2,buf); X } X for (s = arg0; *s; s++) X if (*s == '/') X { X zexecve(arg0,argv,NULL,NULL,NULL); X if (arg0 == s || unset(PATHDIRS)) X { X zerr("%e: %s",arg0,errno); X _exit(1); X } X break; X } X for (; *path; path++) X if ((*path)[0] == '.' && !(*path)[1]) X zexecve(arg0,argv,&ee,buf2,buf); X else X { X tl = strlen(*path); X strcpy(buf,*path); X buf[tl] = '/'; X if (strlen(arg0)+strlen(buf)+1 >= MAXCMDLEN) X { X zerr("command too long: %s",arg0,0); X _exit(1); X } X strcpy(buf+tl+1,arg0); X zexecve(buf,argv,&ee,buf2,buf); X } X if (ee) X { X zerr("%e: %s",arg0,ee); X _exit(1); X } X zerr("command not found: %s",arg0,0); X _exit(1); X} X X#define try(X) { if (!access(X,X_OK)) return ztrdup(X); } X X/* get the pathname of a command */ X Xchar *findcmd(arg0) /**/ Xchar *arg0; X{ Xchar *s,buf[MAXPATHLEN]; Xint tl; Xstruct cmdnam *cn = gethnode(arg0,cmdnamtab); Xchar **pp = path; X X if (cn && (cn->type == EXCMD_POSTDOT || cn->type == EXCMD_PREDOT)) X { X if (cn->type == EXCMD_POSTDOT) X { X strcpy(buf,"./"); X strcat(buf,arg0); X try(buf); X } X try(cn->u.nam); X } X for (s = arg0; *s; s++) X if (*s == '/') X { X try(arg0); X if (s == arg0 || unset(PATHDIRS)) X goto failed; X break; X } X for (; *pp; pp++) X if (**pp == '.') X { X strcpy(buf,"./"); X strcat(buf,arg0); X try(buf); X } X else X { X tl = strlen(*pp); X strcpy(buf,*pp); X buf[tl] = '/'; X strcpy(buf+tl+1,arg0); X try(buf); X } Xfailed: X return NULL; X} X Xvoid execlist(list) /**/ XList list; X{ X if (breaks) X return; X simplifyright(list); X switch(list->type) X { X case SYNC: X case ASYNC: X execlist2(list->left,list->type,!list->right); X if (sigtrapped[SIGDEBUG]) X dotrap(SIGDEBUG); X if (sigtrapped[SIGERR] && lastval) X dotrap(SIGERR); X if (list->right && !retflag) X execlist(list->right); X break; X } X} X Xvoid execlist2(list,type,last1) /**/ XSublist list;int type;int last1; X{ X switch(list->type) X { X case END: X execpline(list,type,last1); X break; X case ORNEXT: X if (!execpline(list,SYNC,0)) X execlist2(list->right,type,last1); X break; X case ANDNEXT: X if (execpline(list,SYNC,0)) X execlist2(list->right,type,last1); X break; X } X} X Xint execpline(l,how,last1) /**/ XSublist l;int how;int last1; X{ Xint ipipe[2],opipe[2]; X X ipipe[0] = ipipe[1] = opipe[0] = opipe[1] = 0; X sigblock(sigmask(SIGCHLD)); X if ((thisjob = getfreejob()) == -1) X return 1; X initjob(); X if (how == TIMED) X { X jobtab[thisjob].stat |= STAT_TIMED; X how = SYNC; X } X if (l->flags & PFLAG_COPROC) X { X how = ASYNC; X mpipe(ipipe); X mpipe(opipe); X if (coprocin) X { X close(coprocin); X close(coprocout); X } X coprocin = ipipe[0]; X coprocout = opipe[1]; X } X execpline2(l->left,how,opipe[0],ipipe[1],last1); X if (how == ASYNC) X { X spawnjob(); X sigsetmask(0); X return 1; X } X else X { X waitjobs(); X sigsetmask(0); X if (l->flags & PFLAG_NOT) X lastval = !lastval; X return !lastval; X } X} X Xvoid execpline2(pline,how,input,output,last1) /**/ XPline pline;int how;int input;int output;int last1; X{ Xint pid; Xint pipes[2]; X X if (breaks) X return; X if (!pline) X return; X if (pline->type == END) X { X execcmd(pline->left,input,output,how==ASYNC,last1); X pline->left = NULL; X } X else X { X mpipe(pipes); X X /* if we are doing "foo | bar" where foo is a current X shell command, do foo in the current shell and do X the rest of the pipeline in a subshell. */ X X if (pline->left->type >= CURSH && how == SYNC) X { X if (!(pid = fork())) X { X close(pipes[1]); X entersubsh(1); X exiting = 1; X execpline2(pline->right,ASYNC,pipes[0],output,1); X _exit(lastval); X } X else if (pid == -1) X zerr("fork failed: %e",NULL,errno); X else X { X char *s,*text; X X close(pipes[0]); X text = s = gettext((void *) pline->right,0); X addproc(pid,text)->lastfg = 1; X pline->right = NULL; X } X } X X /* otherwise just do the pipeline normally. */ X X execcmd(pline->left,input,pipes[1],how==ASYNC,0); X pline->left = NULL; X close(pipes[1]); X if (pline->right) X { X execpline2(pline->right,how,pipes[0],output,last1); X close(pipes[0]); X } X } X} X X/* make the argv array */ X Xchar **makecline(list) /**/ Xstruct lklist *list; X{ Xint ct = 0; XLknode node; Xchar **argv,**ptr; X X if (isset(XTRACE)) X { X fprintf(stderr,"%s",(prompt4) ? prompt4 : ""); X for (node = firstnode(list); node; incnode(node),ct++); X ptr = argv = 2+(char **) ncalloc((ct+4)*sizeof(char *)); X for (node = firstnode(list); node; incnode(node)) X if (*(char *) getdata(node)) X { X *ptr++ = getdata(node); X untokenize(getdata(node)); X fputs(getdata(node),stderr); X if (nextnode(node)) X fputc(' ',stderr); X } X *ptr = NULL; X fputc('\n',stderr); X fflush(stderr); X return(argv); X } X else X { X for (node = firstnode(list); node; incnode(node),ct++); X ptr = argv = 2+(char **) ncalloc((ct+4)*sizeof(char *)); X for (node = firstnode(list); node; incnode(node)) X if (*(char *) getdata(node)) X { X *ptr++ = getdata(node); X untokenize(getdata(node)); X } X *ptr = NULL; X return(argv); X } X} X X/* untokenize the command line and remove null arguments */ X Xvoid fixcline(l) /**/ XLklist l; X{ XLknode node,next; X X for (node = firstnode(l); node; node = next) X { X next = nextnode(node); X if (*(char *) getdata(node)) X untokenize(getdata(node)); X else X uremnode(l,node); X } X} X Xvoid untokenize(s) /**/ Xchar *s; X{ X for (; *s; s++) X if (itok(*s)) X if (*s == Nularg) X chuck(s--); X else X *s = ztokens[*s-Pound]; X} X X/* nonzero if we shouldn't clobber a file */ X Xint dontclob(f) /**/ Xstruct redir *f; X{ Xstruct stat buf; X X if (unset(NOCLOBBER) || f->type & 1) X return 0; X if (stat(f->name,&buf) == -1) X return 1; X return S_ISREG(buf.st_mode); X} X X/* close an multio (success) */ X Xvoid closemn(mfds,fd) /**/ Xstruct multio **mfds;int fd; X{ X if (mfds[fd]) X { X if (mfds[fd]->ct > 1) X if (mfds[fd]->rflag == 0) X catproc(mfds[fd]); X else X teeproc(mfds[fd]); X mfds[fd] = NULL; X } X} X X/* close all the mnodes (failure) */ X Xvoid closemnodes(mfds) /**/ Xstruct multio **mfds; X{ Xint t0,t1; X X for (t0 = 0; t0 != 10; t0++) X if (mfds[t0]) X { X for (t1 = 0; t1 != mfds[t0]->ct; t1++) X close(mfds[t0]->fds[t1]); X mfds[t0] = NULL; X } X} X X/* add a fd to an multio */ X/* an multio is a list of fds associated with a certain fd. X thus if you do "foo >bar >ble", the multio for fd 1 will have X two fds, the result of open("bar",...), and the result of X open("ble",....). */ X Xvoid addfd(forked,save,mfds,fd1,fd2,rflag) /**/ Xint forked;int *save;struct multio **mfds;int fd1;int fd2;int rflag; X{ Xint pipes[2]; X X if (!mfds[fd1]) /* starting a new multio */ X { X mfds[fd1] = alloc(sizeof(struct multio)); X if (!forked && fd1 != fd2 && fd1 < 10) X save[fd1] = movefd(fd1); X redup(fd2,fd1); X mfds[fd1]->ct = 1; X mfds[fd1]->fds[0] = fd1; X mfds[fd1]->rflag = rflag; X } X else X { X if (mfds[fd1]->rflag != rflag) X { X zerr("file mode mismatch on fd %d",NULL,fd1); X return; X } X if (mfds[fd1]->ct == 1) /* split the stream */ X { X mfds[fd1]->fds[0] = movefd(fd1); X mfds[fd1]->fds[1] = movefd(fd2); X mpipe(pipes); X mfds[fd1]->pipe = pipes[1-rflag]; X redup(pipes[rflag],fd1); X mfds[fd1]->ct = 2; X } X else /* add another fd to an already split stream */ X mfds[fd1]->fds[mfds[fd1]->ct++] = movefd(fd2); X } X} X Xvoid addvars(l,export) /**/ XLklist l;int export; X{ Xstruct varasg *v; XLklist vl; X X while (full(l)) X { X char **arr,**ptr; X X v = ugetnode(l); X singsub(&v->name); X if (errflag) X return; X untokenize(v->name); X if (v->type == PMFLAG_s) X { X vl = newlist(); X addnode(vl,v->str); X } X else X vl = v->arr; X prefork(vl); X if (errflag) X return; X postfork(vl,1); X if (errflag) X return; X if (v->type == PMFLAG_s) X { X Param pm; X char *val; X X if (!full(vl)) X pm = setsparam(v->name,val = ztrdup("")); X else X { X untokenize(peekfirst(vl)); X pm = setsparam(v->name,val = ztrdup(ugetnode(vl))); X } X if (export && !(pm->flags & PMFLAG_x)) X addenv(v->name,val); X continue; X } X ptr = arr = (char **) zalloc(sizeof(char **)*(countnodes(v->arr)+1)); X while (full(v->arr)) X { X *ptr = ztrdup(ugetnode(v->arr)); X untokenize(*ptr++); X } X *ptr = NULL; X setaparam(v->name,arr); X } X} X Xvoid execcmd(cmd,input,output,bkg,last1) /**/ XCmd cmd;int input;int output;int bkg;int last1; X{ Xint type; Xlong pid = 0; XLklist args = cmd->args; Xint save[10],t0; Xstruct redir *fn; Xstruct multio *mfds[10]; Xint fil,forked = 0,iscursh = 0,nullexec = 0; XCmdnam chn = NULL; Xchar *text; X X for (t0 = 0; t0 != 10; t0++) X { X save[t0] = 0; X mfds[t0] = NULL; X } X if ((type = cmd->type) == SIMPLE && !full(args)) X if (full(cmd->redir)) X if (cmd->flags & CFLAG_EXEC) X nullexec = 1; X else X addnode(args,strdup("cat")); X else X { X addvars(cmd->vars,0); X return; X } X if (full(args) && *(char *) peekfirst(args) == '%') X { X insnode(args,(Lknode) args,strdup((bkg) ? "bg" : "fg")); X bkg = 0; X } X if (isset(AUTORESUME) && !full(cmd->redir) && full(args) && X type == SIMPLE && !nextnode(firstnode(args)) && X findjobnam(peekfirst(args)) != -1) X pushnode(args,strdup("fg")); X if (unset(RMSTARSILENT) && interact && isset(SHINSTDIN) && X type == SIMPLE && full(args) && nextnode(firstnode(args)) && X !strcmp(peekfirst(args),"rm")) X { X char *s = getdata(nextnode(firstnode(args))); X X if (s[0] == Star && !s[1]) X checkrmall(); X } X if (jobbing) /* get the text associated with this command */ X { X char *s; X s = text = gettext((void *) cmd,0); X } X else X text = NULL; X prefork(args); /* do prefork substitutions */ X if (errflag) X { X lastval = 1; X return; X } X if (full(args) && !(cmd->flags & CFLAG_COMMAND)) X chn = gethnode(peekfirst(args),cmdnamtab); X if (!pathsuppress && !chn && isset(AUTOCD) && full(args) && X !full(cmd->redir) && X !nextnode(firstnode(args)) && cancd(peekfirst(args))) X { X pushnode(args,strdup("cd")); X chn = gethnode("cd",cmdnamtab); X } X X /* this is nonzero if cmd is a current shell procedure */ X X iscursh = (type >= CURSH) || (type == SIMPLE && chn && X (chn->type == BUILTIN || chn->type == SHFUNC)); X X /* if this command is backgrounded or (this is an external X command and we are not exec'ing it) or this is a builtin X with output piped somewhere, then fork. If this is the X last stage in a subshell pipeline, don't fork, but make X the rest of the function think we forked. */ X X if (bkg || !(iscursh || (cmd->flags & CFLAG_EXEC)) || X (chn && (chn->type == BUILTIN || chn->type == SHFUNC) && output)) X { X pid = (last1 && execok()) ? 0 : phork(); X if (pid == -1) X return; X if (pid) X { X if (pid == -1) X zerr("%e",NULL,errno); X else X ( void ) addproc(pid,text); X return; X } X entersubsh(bkg); X forked = 1; X } X if (bkg && isset(BGNICE)) /* stupid */ X nice(5); X if (input) /* add pipeline input/output to mnodes */ X addfd(forked,save,mfds,0,input,0); X if (output) X addfd(forked,save,mfds,1,output,1); X spawnpipes(cmd->redir); /* do process substitutions */ X while (full(cmd->redir)) X if ((fn = ugetnode(cmd->redir))->type == INPIPE) X { X if (fn->fd2 == -1) X execerr(); X addfd(forked,save,mfds,fn->fd1,fn->fd2,0); X } X else if (fn->type == OUTPIPE) X { X if (fn->fd2 == -1) X execerr(); X addfd(forked,save,mfds,fn->fd1,fn->fd2,1); X } X else X { X if (!(fn->type == HERESTR || fn->type == CLOSE || fn->type == X MERGE || fn->type == MERGEOUT)) X if (xpandredir(fn,cmd->redir)) X continue; X if (fn->type == HERESTR) X { X fil = getherestr(fn); X if (fil == -1) X { X if (errno != EINTR) X zerr("%e",NULL,errno); X execerr(); X } X addfd(forked,save,mfds,fn->fd1,fil,0); X } X else if (fn->type == READ) X { X fil = open(fn->name,O_RDONLY); X if (fil == -1) X { X if (errno != EINTR) X zerr("%e: %s",fn->name,errno); X execerr(); X } X addfd(forked,save,mfds,fn->fd1,fil,0); X } X else if (fn->type == CLOSE) X { X if (!forked && fn->fd1 < 3) X { X zerr("can't close fd %d without forking",NULL,fn->fd1); X execerr(); X } X closemn(mfds,fn->fd1); X close(fn->fd1); X } X else if (fn->type == MERGE || fn->type == MERGEOUT) X { X fil = dup(fn->fd2); X if (mfds[fn->fd1]) X redup(fil,fn->fd1); X else X addfd(forked,save,mfds,fn->fd1,fil,fn->type == MERGEOUT); X } X else X { X if (fn->type >= APP) X fil = open(fn->name,isset(NOCLOBBER) ? X O_WRONLY|O_APPEND : O_WRONLY|O_APPEND|O_CREAT,0666); X else X fil = open(fn->name,dontclob(fn) ? X O_WRONLY|O_CREAT|O_EXCL : O_WRONLY|O_CREAT|O_TRUNC,0666); X if (fil == -1) X { X if (errno != EINTR) X zerr("%e: %s",fn->name,errno); X execerr(); X } X addfd(forked,save,mfds,fn->fd1,fil,1); X } X } X postfork(args,!(cmd->flags & CFLAG_NOGLOB)); X /* perform postfork substitutions */ X if (errflag) X { X lastval = 1; X goto err; X } X X /* we are done with redirection. close the mnodes, spawning X tee/cat processes as necessary. */ X for (t0 = 0; t0 != 10; t0++) X closemn(mfds,t0); X X if (nullexec) X return; X if (unset(NOEXEC)) X if (type >= CTIME) X { X static int (*func[]) DCLPROTO((Cmd)) = { X exectime,execcursh,execfuncdef,execfor,execwhile, X execrepeat,execif,execcase,execselect,execcond }; X X fixcline(args); X lastval = (func[type-CTIME])(cmd); X } X else if (iscursh) /* builtin or shell function */ X { X if (cmd->vars) X addvars(cmd->vars,0); X fixcline(args); X if (chn && chn->type == SHFUNC) X execshfunc(cmd,chn); X else X { X lastval = execbin(args,chn); X if (isset(PRINTEXITVALUE) && lastval) X zerr("exit %d",NULL,lastval); X fflush(stdout); X if (ferror(stdout)) X { X zerr("write error: %e",NULL,errno); X clearerr(stdout); X } X } X } X else X { X if (cmd->vars) X addvars(cmd->vars,1); X if (type == SIMPLE) X { X closem(); X execute(args,cmd->flags & CFLAG_DASH); X } X else /* ( ... ) */ X execlist(cmd->u.list); X } Xerr: X if (forked) X _exit(lastval); X fixfds(save); X} X X/* restore fds after redirecting a builtin */ X Xvoid fixfds(save) /**/ Xint *save; X{ Xint t0; X X for (t0 = 0; t0 != 10; t0++) X if (save[t0]) X redup(save[t0],t0); X} X Xvoid entersubsh(bkg) /**/ Xint bkg; X{ X if (!jobbing) X { X if (bkg && isatty(0)) X { X close(0); X if (open("/dev/null",O_RDWR)) X { X zerr("can't open /dev/null: %e",NULL,errno); X _exit(1); X } X } X } X else if (!jobtab[thisjob].gleader) X { X setpgrp(0L,jobtab[thisjob].gleader = getpid()); X if (!bkg) X attachtty(jobtab[thisjob].gleader); X } X else X setpgrp(0L,jobtab[thisjob].gleader); X subsh = 1; X if (SHTTY != -1) X { X close(SHTTY); X SHTTY = -1; X } X if (jobbing) X { X signal(SIGTTOU,SIG_DFL); X signal(SIGTTIN,SIG_DFL); X signal(SIGTSTP,SIG_DFL); X signal(SIGPIPE,SIG_DFL); X } X if (interact) X { X signal(SIGTERM,SIG_DFL); X if (sigtrapped[SIGINT]) X signal(SIGINT,SIG_IGN); X } X if (!sigtrapped[SIGQUIT]) X signal(SIGQUIT,SIG_DFL); X opts[MONITOR] = OPT_UNSET; X clearjobtab(); X} X X/* close all internal shell fds */ X Xvoid closem() /**/ X{ Xint t0; X X for (t0 = 10; t0 != NOFILE; t0++) X close(t0); X} X X/* convert here document into a here string */ X Xchar *gethere(str) /**/ Xchar *str; X{ Xchar pbuf[256]; Xint qt = 0,siz = 0,l,strip = 0; Xchar *s,*t,*bptr; X X for (s = str; *s; s++) X if (*s == Nularg) X qt = 1; X untokenize(str); X if (*str == '-') X { X str++; X strip = 1; X while (*str == '\t') X str++; X } X t = ztrdup(""); X for(;;) X { X char *u,*v; X X if (!fgets(pbuf,256,bshin)) X break; X bptr = pbuf; X if (strip) X while (*bptr == '\t') X bptr++; X for (u = bptr, v = str; *u != '\n' && *v; u++,v++) X if (*u != *v) X break; X if (!(*u == '\n' && !*v)) X { X l = strlen(bptr); X if (!qt && l > 1 && bptr[l-1] == '\n' && bptr[l-2] == '\\') X bptr[l -= 2] = '\0'; X t = realloc(t,siz+l+1); X strncpy(t+siz,bptr,l); X siz += l; X } X else X break; X } X t[siz] = '\0'; X if (siz && t[siz-1] == '\n') X t[siz-1] = '\0'; X if (!qt) X for (s = t; *s; s++) X if (*s == '$') X *s = Qstring; X else if (*s == '`') X *s = Qtick; X else if (*s == '\\') X { X s++; X if (!*s) X break; X } X s = strdup(t); X free(t); X return s; X} X X/* open here string fd */ X Xint getherestr(fn) /**/ Xstruct redir *fn; X{ XLklist fake; Xchar *s = gettemp(),*t; Xint fd; X X fake = newlist(); X addnode(fake,fn->name); X prefork(fake); X if (!errflag) X postfork(fake,1); X if (errflag) X return -1; X if ((fd = open(s,O_CREAT|O_WRONLY,0600)) == -1) X return -1; X while (t = ugetnode(fake)) X { X untokenize(t); X write(fd,t,strlen(t)); X if (full(fake)) X write(fd," ",1); X } X write(fd,"\n",1); X close(fd); X fd = open(s,O_RDONLY); X unlink(s); X return fd; X} X Xvoid catproc(mn) /**/ Xstruct multio *mn; X{ Xint len,t0; Xchar *buf; X X if (phork()) X { X for (t0 = 0; t0 != mn->ct; t0++) X close(mn->fds[t0]); X close(mn->pipe); X return; X } X closeallelse(mn); X buf = zalloc(4096); X for (t0 = 0; t0 != mn->ct; t0++) X while (len = read(mn->fds[t0],buf,4096)) X write(mn->pipe,buf,len); X _exit(0); X} X Xvoid teeproc(mn) /**/ Xstruct multio *mn; X{ Xint len,t0; Xchar *buf; X X if (phork()) X { X for (t0 = 0; t0 != mn->ct; t0++) X close(mn->fds[t0]); X close(mn->pipe); X return; X } X buf = zalloc(4096); X closeallelse(mn); X while ((len = read(mn->pipe,buf,4096)) > 0) X for (t0 = 0; t0 != mn->ct; t0++) X write(mn->fds[t0],buf,len); X _exit(0); X} X Xvoid closeallelse(mn) /**/ Xstruct multio *mn; X{ Xint t0,t1; X X for (t0 = 0; t0 != NOFILE; t0++) X if (mn->pipe != t0) X { X for (t1 = 0; t1 != mn->ct; t1++) X if (mn->fds[t1] == t0) X break; X if (t1 == mn->ct) X close(t0); X } X} X Xlong int zstrtol(s,t,base) /**/ Xchar *s;char **t;int base; X{ Xint ret = 0; X X for (; *s >= '0' && *s < ('0'+base); s++) X ret = ret*base+*s-'0'; X if (t) X *t = (char *) s; X return ret; X} X X/* $(...) */ X XLklist getoutput(cmd,qt) /**/ Xchar *cmd;int qt; X{ XList list; Xint pipes[2]; X X if (*cmd == '<') X { X int stream; X char *fi; X X fi = strdup(cmd+1); X if (*fi == '~') X *fi = Tilde; X else if (*fi == '=') X *fi = Equals; X singsub(&fi); X if (errflag) X return NULL; X stream = open(fi,O_RDONLY); X if (stream == -1) X { X zerr("%e: %s",cmd+1,errno); X return NULL; X } X return readoutput(stream,qt); X } X if (!(list = parselstring(cmd))) X return NULL; X mpipe(pipes); X if (phork()) X { X popheap(); X close(pipes[1]); X return readoutput(pipes[0],qt); X } X subsh = 1; X close(pipes[0]); X redup(pipes[1],1); X entersubsh(0); X signal(SIGTSTP,SIG_IGN); X exiting = 1; X execlist(list); X close(1); X exit(0); return NULL; X} X X/* read output of command substitution */ X XLklist readoutput(in,qt) /**/ Xint in;int qt; X{ XLklist ret; Xchar *buf,*ptr; Xint bsiz,c,cnt = 0; XFILE *fin; X X fin = fdopen(in,"r"); X ret = newlist(); X ptr = buf = zalloc(bsiz = 256); X while ((c = fgetc(fin)) != EOF) X if (!qt && isep(c)) X { X if (cnt) X { X *ptr = '\0'; X addnode(ret,ztrdup(buf)); X cnt = 0; X ptr = buf; X } X } X else X { X *ptr++ = c; X if (++cnt == bsiz) X { X char *pp = zalloc(bsiz *= 2); X X memcpy(pp,buf,cnt); X free(buf); X ptr = (buf = pp)+cnt; X } X } X if (qt && ptr != buf && ptr[-1] == '\n') X ptr[-1] = '\0'; X if (cnt) X addnode(ret,ztrdup(buf)); X free(buf); X fclose(fin); X return ret; X} X X/* =(...) */ X Xchar *getoutputfile(cmd) /**/ Xchar *cmd; X{ X#ifdef WAITPID Xint pid; X#endif Xchar *nam = gettemp(),*str; Xint tfil; XList list; X X if (thisjob == -1) X return NULL; X for (str = cmd; *str && *str != Outpar; str++); X if (!*str) X zerr("oops.",NULL,0); X *str = '\0'; X if (!(list = parselstring(cmd))) X return NULL; X permalloc(); X if (!jobtab[thisjob].filelist) X jobtab[thisjob].filelist = newlist(); X addnode(jobtab[thisjob].filelist,ztrdup(nam)); X heapalloc(); X#ifdef WAITPID X if (pid = phork()) X { X popheap(); X waitpid(pid,NULL,WUNTRACED); X return nam; X } X#else X if (waitfork()) X return nam; X#endif X subsh = 1; X close(1); X entersubsh(0); X tfil = creat(nam,0666); X exiting = 1; X execlist(list); X close(1); X exit(0); return NULL; X} X X/* get a temporary named pipe */ X Xchar *namedpipe() /**/ X{ Xchar *tnam = gettemp(); X X mknod(tnam,0010666,0); X return tnam; X} X X/* <(...) */ X Xchar *getoutproc(cmd) /**/ Xchar *cmd; X{ XList list; Xint fd; Xchar *pnam,*str; X X if (thisjob == -1) X return NULL; X for (str = cmd; *str && *str != Outpar; str++); X if (!*str) X zerr("oops.",NULL,0); X *str = '\0'; X pnam = namedpipe(); X permalloc(); X if (!jobtab[thisjob].filelist) X jobtab[thisjob].filelist = newlist(); X addnode(jobtab[thisjob].filelist,ztrdup(pnam)); X heapalloc(); X if (!(list = parselstring(cmd))) X return NULL; X if (phork()) X { X popheap(); X return pnam; X } X entersubsh(1); X fd = open(pnam,O_WRONLY); X if (fd == -1) X { X zerr("can't open %s: %e",pnam,errno); X _exit(0); X } X redup(fd,1); X fd = open("/dev/null",O_RDONLY); X redup(fd,0); X exiting = 1; X execlist(list); X close(1); X _exit(0); return NULL; X} X X/* >(...) */ X Xchar *getinproc(cmd) /**/ Xchar *cmd; X{ XList list; Xint pid,fd; Xchar *pnam,*str; X X if (thisjob == -1) X return NULL; X for (str = cmd; *str && *str != Outpar; str++); X if (!*str) X zerr("oops.",NULL,0); X *str = '\0'; X pnam = namedpipe(); X permalloc(); X if (!jobtab[thisjob].filelist) X jobtab[thisjob].filelist = newlist(); X addnode(jobtab[thisjob].filelist,ztrdup(pnam)); X heapalloc(); X if (!(list = parselstring(cmd))) X return NULL; X if (pid = phork()) X { X popheap(); X return pnam; X } X entersubsh(1); X fd = open(pnam,O_RDONLY); X redup(fd,0); X exiting = 1; X execlist(list); X _exit(0); return NULL; X} X X/* > >(...) (does not use named pipes) */ X Xint getinpipe(cmd) /**/ Xchar *cmd; X{ XList list; Xint pipes[2]; Xchar *str = cmd; X X for (str = cmd; *str && *str != Outpar; str++); X if (!*str) X zerr("oops.",NULL,0); X *str = '\0'; X if (!(list = parselstring(cmd+2))) X return -1; X mpipe(pipes); X if (phork()) X { X popheap(); X close(pipes[1]); X return pipes[0]; X } X close(pipes[0]); X entersubsh(1); X redup(pipes[1],1); X exiting = 1; X execlist(list); X _exit(0); return 0; X} X X/* < <(...) */ X Xint getoutpipe(cmd) /**/ Xchar *cmd; X{ XList list; Xint pipes[2]; Xchar *str; X X for (str = cmd; *str && *str != Outpar; str++); X if (!*str) X zerr("oops.",NULL,0); X *str = '\0'; X if (!(list = parselstring(cmd+2))) X return -1; X strinend(); X mpipe(pipes); X if (phork()) X { X popheap(); X close(pipes[0]); X return pipes[1]; X } X close(pipes[1]); X entersubsh(1); X redup(pipes[0],0); X exiting = 1; X execlist(list); X _exit(0); return 0; X} X X/* run a list, saving the current job num */ X Xvoid runlist(l) /**/ XList l; X{ Xint cj = thisjob; X X execlist(l); X thisjob = cj; X} X Xchar *gettemp() /**/ X{ X return mktemp(strdup("/tmp/zshXXXXXX")); X} X X/* my getwd; all the other ones I tried confused the SIGCHLD handler */ X Xchar *zgetwd() /**/ X{ Xstatic char buf0[MAXPATHLEN]; Xchar buf3[MAXPATHLEN],*buf2 = buf0+1; Xstruct stat sbuf; Xstruct direct *de; XDIR *dir; Xino_t ino = -1; Xdev_t dev = -1; X X holdintr(); X buf2[0] = '\0'; X buf0[0] = '/'; X for(;;) X { X if (stat(".",&sbuf) < 0) X { X chdir(buf0); X noholdintr(); X return ztrdup("."); X } X ino = sbuf.st_ino; X dev = sbuf.st_dev; X if (stat("..",&sbuf) < 0) X { X chdir(buf0); X noholdintr(); X return ztrdup("."); X } X if (sbuf.st_ino == ino && sbuf.st_dev == dev) X { X chdir(buf0); X noholdintr(); X return ztrdup(buf0); X } X dir = opendir(".."); X if (!dir) X { X chdir(buf0); X noholdintr(); X return ztrdup("."); X } X chdir(".."); X readdir(dir); readdir(dir); X while (de = readdir(dir)) X if (de->d_ino == ino) X { X lstat(de->d_name,&sbuf); X if (sbuf.st_dev == dev) X goto match; X } X rewinddir(dir); X readdir(dir); readdir(dir); X while (de = readdir(dir)) X { X lstat(de->d_name,&sbuf); X if (sbuf.st_dev == dev) X goto match; X } X noholdintr(); X closedir(dir); X return ztrdup("."); Xmatch: X strcpy(buf3,de->d_name); X if (*buf2) X strcat(buf3,"/"); X strcat(buf3,buf2); X strcpy(buf2,buf3); X closedir(dir); X } X} X X/* open pipes with fds >= 10 */ X Xvoid mpipe(pp) /**/ Xint *pp; X{ X pipe(pp); X pp[0] = movefd(pp[0]); X pp[1] = movefd(pp[1]); X} X X/* do process substitution with redirection */ X Xvoid spawnpipes(l) /**/ XLklist l; X{ XLknode n = firstnode(l); Xstruct redir *f; X X for (; n; incnode(n)) X { X f = getdata(n); X if (f->type == OUTPIPE) X { X char *str = f->name; X f->fd2 = getoutpipe(str); X } X if (f->type == INPIPE) X { X char *str = f->name; X f->fd2 = getinpipe(str); X } X } X} X X/* perform time ... command */ X Xint exectime(cmd) /**/ XCmd cmd; X{ Xint jb = thisjob; X X execpline(cmd->u.pline,TIMED,0); X thisjob = jb; X return lastval; X} X X/* define a function */ X Xint execfuncdef(cmd) /**/ XCmd cmd; X{ XCmdnam cc; Xchar *s; X X permalloc(); X while (s = ugetnode(cmd->args)) X { X cc = zalloc(sizeof *cc); X cc->type = SHFUNC; X cc->flags = 0; X cc->u.list = dupstruct(cmd->u.list); X addhnode(ztrdup(s),cc,cmdnamtab,freecmdnam); X if (!strncmp(s,"TRAP",4)) X { X int t0 = getsignum(s+4); X X if (t0 != -1) X settrap(t0,cmd->u.list); X } X } X heapalloc(); X return 0; X} X X/* evaluate a [[ ... ]] */ X Xint execcond(cmd) /**/ XCmd cmd; X{ X return !evalcond(cmd->u.cond); X} X Xvoid execshfunc(cmd,cn) /**/ XCmd cmd;Cmdnam cn; X{ Xchar **tab,**x,*oargv0; Xint oxtr = opts[XTRACE],flags,xexittr; XList l; XLklist olist; Xchar *s; XList xexitfn; X X if (errflag) X return; X l = cn->u.list; X if (!l) X { X char *nam; X X if (!(l = getfpfunc(nam = peekfirst(cmd->args)))) X { X zerr("function not found: %s",nam,0); X lastval = 1; X return; X } X cn->flags &= ~PMFLAG_u; X permalloc(); X cn->u.list = dupstruct(l); X heapalloc(); X } X flags = cn->flags; X xexittr = sigtrapped[SIGEXIT]; X xexitfn = sigfuncs[SIGEXIT]; X tab = pparams; X oargv0 = argzero; X if (flags & PMFLAG_t) X opts[XTRACE] = OPT_SET; X pparams = x = zcalloc(((sizeof *x)*(1+countnodes(cmd->args)))); X argzero = ztrdup(ugetnode(cmd->args)); X while (*x = ugetnode(cmd->args)) X *x = ztrdup(*x), x++; X permalloc(); X olist = locallist; X locallist = newlist(); X heapalloc(); X newrunlist(l); X while (s = getnode(locallist)) X unsetparam(s); X free(locallist); X locallist = olist; X retflag = 0; X cmd->u.list = NULL; X freearray(pparams); X free(argzero); X argzero = oargv0; X pparams = tab; X if (sigtrapped[SIGEXIT]) X dotrap(SIGEXIT); X if (sigfuncs[SIGEXIT]) X freestruct(sigfuncs[SIGEXIT]); X sigtrapped[SIGEXIT] = xexittr; X sigfuncs[SIGEXIT] = xexitfn; X opts[XTRACE] = oxtr; X} X X/* search fpath for an undefined function */ X XList getfpfunc(s) /**/ Xchar *s; X{ Xchar **pp = fpath,buf[MAXPATHLEN]; Xint fd; X X for (; *pp; pp++) X { X sprintf(buf,"%s/%s",*pp,s); X if (!access(buf,X_OK) && (fd = open(buf,O_RDONLY)) != -1) X { X int len = lseek(fd,0,2); X X if (len == -1) X close(fd); X else X { X char *d; X X lseek(fd,0,0); X d = zcalloc(len+1); X if (read(fd,d,len) != len) X { X free(d); X close(fd); X } X else X { X close(fd); X return parselstring(d); X } X } X } X } X return NULL; X} X X/* check to see if AUTOCD applies here */ X Xint cancd(s) Xchar *s; X{ Xchar *t; X X for (t = s; *t; t++) X if (*t == '/') X break; X if (!*t) X { X char sbuf[MAXPATHLEN],**cp; X X if (cancd2(s)) X return 1; X for (cp = cdpath; *cp; cp++) X { X sprintf(sbuf,"%s/%s",*cp,s); X if (cancd2(sbuf)) X return 1; X } X return 0; X } X return cancd2(s); X} X Xint cancd2(s) Xchar *s; X{ Xstruct stat buf; X X return !(access(s,X_OK) || lstat(s,&buf) || !S_ISDIR(buf.st_mode)); X} X SHAR_EOF chmod 0644 zsh2.00/src/exec.c || echo 'restore of zsh2.00/src/exec.c failed' Wc_c="`wc -c < 'zsh2.00/src/exec.c'`" test 31640 -eq "$Wc_c" || echo 'zsh2.00/src/exec.c: original size 31640, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/exec.pro ============== if test -f 'zsh2.00/src/exec.pro' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/exec.pro (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/exec.pro (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/exec.pro' && XList parselstring DCLPROTO((char *s)); Xvoid execstring DCLPROTO((char *s)); Xvoid newrunlist DCLPROTO((List l)); Xint phork DCLPROTO((void)); Xint execcursh DCLPROTO((Cmd cmd)); Xvoid zexecve DCLPROTO((char *pth,char **argv,int *ee,char *b1,char *b2)); Xvoid execute DCLPROTO((Lklist args,int dash)); Xchar *findcmd DCLPROTO((char *arg0)); Xvoid execlist DCLPROTO((List list)); Xvoid execlist2 DCLPROTO((Sublist list,int type,int last1)); Xint execpline DCLPROTO((Sublist l,int how,int last1)); Xvoid execpline2 DCLPROTO((Pline pline,int how,int input,int output,int last1)); Xchar **makecline DCLPROTO((struct lklist *list)); Xvoid fixcline DCLPROTO((Lklist l)); Xvoid untokenize DCLPROTO((char *s)); Xint dontclob DCLPROTO((struct redir *f)); Xvoid closemn DCLPROTO((struct multio **mfds,int fd)); Xvoid closemnodes DCLPROTO((struct multio **mfds)); Xvoid addfd DCLPROTO((int forked,int *save,struct multio **mfds,int fd1,int fd2,int rflag)); Xvoid addvars DCLPROTO((Lklist l,int export)); Xvoid execcmd DCLPROTO((Cmd cmd,int input,int output,int bkg,int last1)); Xvoid fixfds DCLPROTO((int *save)); Xvoid entersubsh DCLPROTO((int bkg)); Xvoid closem DCLPROTO((void)); Xchar *gethere DCLPROTO((char *str)); Xint getherestr DCLPROTO((struct redir *fn)); Xvoid catproc DCLPROTO((struct multio *mn)); Xvoid teeproc DCLPROTO((struct multio *mn)); Xvoid closeallelse DCLPROTO((struct multio *mn)); Xlong int zstrtol DCLPROTO((char *s,char **t,int base)); XLklist getoutput DCLPROTO((char *cmd,int qt)); XLklist readoutput DCLPROTO((int in,int qt)); Xchar *getoutputfile DCLPROTO((char *cmd)); Xchar *namedpipe DCLPROTO((void)); Xchar *getoutproc DCLPROTO((char *cmd)); Xchar *getinproc DCLPROTO((char *cmd)); Xint getinpipe DCLPROTO((char *cmd)); Xint getoutpipe DCLPROTO((char *cmd)); Xvoid runlist DCLPROTO((List l)); Xchar *gettemp DCLPROTO((void)); Xchar *zgetwd DCLPROTO((void)); Xvoid mpipe DCLPROTO((int *pp)); Xvoid spawnpipes DCLPROTO((Lklist l)); Xint exectime DCLPROTO((Cmd cmd)); Xint execfuncdef DCLPROTO((Cmd cmd)); Xint execcond DCLPROTO((Cmd cmd)); Xvoid execshfunc DCLPROTO((Cmd cmd,Cmdnam cn)); XList getfpfunc DCLPROTO((char *s)); SHAR_EOF chmod 0644 zsh2.00/src/exec.pro || echo 'restore of zsh2.00/src/exec.pro failed' Wc_c="`wc -c < 'zsh2.00/src/exec.pro'`" test 2101 -eq "$Wc_c" || echo 'zsh2.00/src/exec.pro: original size 2101, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/funcs.h ============== if test -f 'zsh2.00/src/funcs.h' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/funcs.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/funcs.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/funcs.h' && X#include "glob.pro" X#include "hist.pro" X#include "table.pro" X#include "subst.pro" X#include "params.pro" X#include "builtin.pro" X#include "loop.pro" X#include "jobs.pro" X#include "exec.pro" X#include "init.pro" X#include "lex.pro" X#include "parse.pro" X#include "utils.pro" X#include "cond.pro" X#include "mem.pro" X#include "text.pro" X#include "watch.pro" X X#include "zle_emacs.pro" X#include "zle_utils.pro" X#include "zle_main.pro" X#include "zle_refresh.pro" X#include "zle_tricky.pro" X#include "zle_vi.pro" X Xchar *mktemp DCLPROTO((char *)); Xchar *malloc DCLPROTO((int)); Xchar *realloc DCLPROTO((char *,int)); Xchar *calloc DCLPROTO((int,int)); Xchar *ttyname DCLPROTO((int)); Xchar *tgetstr(); SHAR_EOF chmod 0644 zsh2.00/src/funcs.h || echo 'restore of zsh2.00/src/funcs.h failed' Wc_c="`wc -c < 'zsh2.00/src/funcs.h'`" test 682 -eq "$Wc_c" || echo 'zsh2.00/src/funcs.h: original size 682, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/glob.c ============== if test -f 'zsh2.00/src/glob.c' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/glob.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/glob.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/glob.c' && X/* X X glob.c - filename generation X X This file is part of zsh, the Z shell. X X zsh is free software; no one can prevent you from reading the source X code, or giving it to someone else. X X This file is copyrighted under the GNU General Public License, which X can be found in the file called COPYING. X X Copyright (C) 1990, 1991 Paul Falstad X X zsh is distributed in the hope that it will be useful, but X WITHOUT ANY WARRANTY. No author or distributor accepts X responsibility to anyone for the consequences of using it or for X whether it serves any particular purpose or works at all, unless he X says so in writing. Refer to the GNU General Public License X for full details. X X Everyone is granted permission to copy, modify and redistribute X zsh, but only under the conditions described in the GNU General Public X License. A copy of this license is supposed to have been given to you X along with zsh so you can know your rights and responsibilities. X It should be in a file named COPYING. X X Among other things, the copyright notice and this notice must be X preserved on all copies. X X*/ X X#include "zsh.h" X#include "funcs.h" X#ifndef INT_MAX X#include <limits.h> X#endif X#include <sys/dir.h> X#include <sys/errno.h> X X#define exists(X) (access(X,0) == 0) X Xstatic int mode; /* != 0 if we are parsing glob patterns */ Xstatic int pathpos; /* position in pathbuf */ Xstatic int matchsz; /* size of matchbuf */ Xstatic int matchct; /* number of matches found */ Xstatic char pathbuf[MAXPATHLEN]; /* pathname buffer */ Xstatic char **matchbuf; /* array of matches */ Xstatic char **matchptr; /* &matchbuf[matchct] */ X X/* max # of qualifiers */ X X#define QUALCT 16 X Xstatic int (*qualfuncs[QUALCT])DCLPROTO((struct stat *,long)); Xstatic long qualdata[QUALCT]; Xstatic int qualsense[QUALCT]; Xstatic int qualct; X X/* pathname component in filename patterns */ X Xstruct complist { X Complist next; X Comp comp; X int closure; /* 1 if this is a (foo/)# */ X }; Xstruct comp { X Comp left,right,next; X char *str; X int closure,last; X }; X Xvoid glob(list,np) /**/ XLklist list;Lknode *np; X{ XLknode node = prevnode(*np); XLknode next = nextnode(*np); Xint sl; /* length of the pattern */ Xchar *ostr; /* the pattern before the parser chops it up */ XComplist q; /* pattern after parsing */ Xchar *str = getdata(*np); /* the pattern */ X X sl = strlen(str); X ostr = strdup(str); X uremnode(list,*np); X qualct = 0; X if (str[sl-1] == Outpar) /* check for qualifiers */ X { X char *s; X int sense = 0; X long data; X int (*func) DCLPROTO((struct stat *,long)); X X for (s = str+sl-2; s != str; s--) X if (*s == Bar || *s == Outpar || *s == Inpar) X break; X if (*s == Inpar) X { X *s++ = '\0'; X func = NULL; X while (*s != Outpar) X { X func = NULL; X if (idigit(*s)) X { X func = qualflags; X data = 0; X while (idigit(*s)) X data = data*010+(*s-'0'); X } X else switch (*s++) X { X case Hat: sense = 1-sense; break; X case '@': func = qualmode; data = S_IFLNK; break; X case '=': func = qualmode; data = S_IFSOCK; break; X case 'p': func = qualmode; data = S_IFIFO; break; X case '/': func = qualmode; data = S_IFDIR; break; X case '.': func = qualmode; data = S_IFREG; break; X case '%': func = qualisdev; break; X case Star: func = qualflags; data = 0100; break; X case 'R': func = qualflags; data = 0004; break; X case 'W': func = qualflags; data = 0002; break; X case 'X': func = qualflags; data = 0001; break; X case 'r': func = qualflags; data = 0400; break; X case 'w': func = qualflags; data = 0200; break; X case 'x': func = qualflags; data = 0100; break; X case 's': func = qualflags; data = 04000; break; X case 'S': func = qualflags; data = 02000; break; X case 'd': func = qualdev; data = qgetnum(&s); break; X case 'l': func = qualnlink; data = qgetnum(&s); break; X case 'U': func = qualuid; data = geteuid(); break; X case 'G': func = qualgid; data = getegid(); break; X case 'u': func = qualuid; data = qgetnum(&s); break; X case 'g': func = qualgid; data = qgetnum(&s); break; X default: zerr("unknown file attribute",NULL,0); return; X } X if (func) X { X if (qualct == 15) X { X zerr("too many qualifiers",NULL,0); X return; X } X qualfuncs[qualct] = func; X qualsense[qualct] = sense; X qualdata[qualct] = data; X qualct++; X } X if (errflag) X return; X } X } X } X else if (str[sl-1] == '/') /* foo/ == foo(/) */ X { X str[sl-1] = '\0'; X qualfuncs[0] = qualmode; X qualdata[0] = S_IFDIR; X qualsense[0] = 0; X qualct = 1; X } X if (*str == '/') /* pattern has absolute path */ X { X str++; X pathbuf[0] = '/'; X pathbuf[pathpos = 1] = '\0'; X } X else /* pattern is relative to cwd */ X pathbuf[pathpos = 0] = '\0'; X q = parsepat(str); X if (!q || errflag) /* if parsing failed */ X { X if (isset(NOBADPATTERN)) X { X insnode(list,node,ostr); X return; X } X errflag = 0; X zerr("bad pattern: %s",ostr,0); X return; X } X matchptr = matchbuf = (char **) zalloc((matchsz = 16)*sizeof(char *)); X matchct = 0; X scanner(q); /* do the globbing */ X if (!matchct && unset(NULLGLOB)) X if (unset(NONOMATCH)) X { X zerr("no matches found: %s",ostr,0); X free(matchbuf); X return; X } X else X { X *matchptr++ = strdup(ostr); X matchct = 1; X } X qsort(&matchbuf[0],matchct,sizeof(char *),notstrcmp); X matchptr = matchbuf; X while (matchct--) /* insert matches in the arg list */ X insnode(list,node,*matchptr++); X free(matchbuf); X *np = (next) ? prevnode(next) : lastnode(list); X} X X/* get number after qualifier */ X Xlong qgetnum(s) /**/ Xchar **s; X{ Xlong v = 0; X X if (!idigit(**s)) X { X zerr("number expected",NULL,0); X return 0; X } X while (idigit(**s)) X v = v*10+*(*s)++-'0'; X return v; X} X Xint notstrcmp(a,b) /**/ Xchar **a;char **b; X{ Xchar *c = *b,*d = *a; SHAR_EOF true || echo 'restore of zsh2.00/src/glob.c failed' fi echo 'End of zsh2.00.00 part 5' echo 'File zsh2.00/src/glob.c is continued in part 6' echo 6 > _shar_seq_.tmp exit 0 -- Paul Falstad pfalstad@phoenix.princeton.edu And on the roads, too, vicious gangs of KEEP LEFT signs! If Princeton knew my opinions, they'd have expelled me long ago. exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.