xec.c revision 7c2fbfb345896881c631598ee3852ce9ce33fb07
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Copyright (c) 1982-2008 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * UNIX shell parse tree executer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "name.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shnodes.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "jobs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "test.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/time"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/externs"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/locale"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "streval.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_std_malloc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <vmalloc.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _lib_vfork
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# include <ast_vfork.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define vfork() fork()
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SH_NTFORK SH_TIMING
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_nice
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern int nice(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_nice */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_lib_spawnveg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define spawnveg(a,b,c,d) spawnve(a,b,c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !_lib_spawnveg */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_SPAWN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static pid_t sh_ntfork(Shell_t*,const Shnode_t*,char*[],int*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_SPAWN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void sh_funct(Shell_t *,Namval_t*, int, char*[], struct argnod*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int trim_eq(const char*, const char*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void coproc_init(Shell_t*, int pipes[]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void *timeout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char pipejob;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct funenv
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *node;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *env;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ======== command execution ========*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print time <t> in h:m:s format with precision <p>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void l_time(Sfio_t *outfile,register clock_t t,int p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int min, sec, frac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int hr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin frac = t%sh.lim.clk_tck;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin frac = (frac*100)/sh.lim.clk_tck;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t /= sh.lim.clk_tck;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sec = t%60;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t /= 60;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin min = t%60;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(hr=t/60)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%dh",hr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%dm%d%c%0*ds",min,sec,GETDECIMAL(0),p,frac);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%dm%ds",min,sec);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int p_time(Shell_t *shp, Sfio_t *out, const char *format, clock_t *tm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int c,p,l,n,offset = staktell();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin const char *first;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin double d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(first=format ; c= *format; format++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp, first, format-first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = l = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c= *++format) == '%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = format;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c>='0' && c <='9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = (c>'3')?3:(c-'0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *++format;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='P')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(d=tm[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = 100.*(((double)(tm[1]+tm[2]))/d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='l')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *++format;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='U')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='S')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c!='R')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(0),e_badtformat,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (double)tm[n]/sh.lim.clk_tck;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(l)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin l_time(stkp, tm[n], p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(stkp,"%.*f",p, d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = format+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(format>first)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first, format-first);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = stktell(stkp)-offset;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(out,stkptr(stkp,offset),n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * clear argument pointers that point into the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int p_arg(struct argnod*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int p_switch(struct regnod*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int p_comarg(register struct comnod *com)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np=com->comnamp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = p_arg(com->comset,ARG_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comarg && (com->comtyp&COMSCAN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+= p_arg(com->comarg,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comstate && np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* call builtin to cleanup state */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shbltin_t *bp = &sh.bltindata;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void *save_ptr = bp->ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void *save_data = bp->data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->bnode = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->vnode = com->comnamq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->ptr = nv_context(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->data = com->comstate;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->flags = SH_END_OPTIM;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (*funptr(np))(0,(char**)0, bp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->ptr = save_ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->data = save_data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com->comstate = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comarg && !np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void sh_optclear(Shell_t*, void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int sh_tclear(register Shnode_t *t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(t->tre.tretyp&COMMSK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TTIME:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TPAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_tclear(t->par.partre));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TCOM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(p_comarg((struct comnod*)t));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TSETIO:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFORK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_tclear(t->fork.forktre));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=sh_tclear(t->if_.iftre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=sh_tclear(t->if_.thtre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=sh_tclear(t->if_.eltre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TWH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->wh.whinc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=sh_tclear((Shnode_t*)(t->wh.whinc));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=sh_tclear(t->wh.whtre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=sh_tclear(t->wh.dotre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TLST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TAND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TORF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFIL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=sh_tclear(t->lst.lstlef);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n+sh_tclear(t->lst.lstrit));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TARITH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(p_arg(t->ar.arexpr,ARG_ARITH));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFOR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=sh_tclear(t->for_.fortre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n+sh_tclear((Shnode_t*)t->for_.forlst));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TSW:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=p_arg(t->sw.swarg,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n+p_switch(t->sw.swlst));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFUN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=sh_tclear(t->funct.functtre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n+sh_tclear((Shnode_t*)t->funct.functargs));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TTST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((t->tre.tretyp&TPAREN)==TPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_tclear(t->lst.lstlef));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=p_arg(&(t->lst.lstlef->arg),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&TBINARY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=p_arg(&(t->lst.lstrit->arg),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int p_arg(register struct argnod *arg,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(arg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strlen(arg->argval) || (arg->argflag==ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg->argchn.ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flag==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear((Shnode_t*)arg->argchn.ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(((struct fornod*)arg->argchn.ap)->fortre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg = arg->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int p_switch(register struct regnod *reg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(reg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=p_arg(reg->regptr,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n+=sh_tclear(reg->regcom);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg = reg->regnxt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define OPTIMIZE_FLAG (ARG_OPTIMIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define OPTIMIZE (flags&OPTIMIZE_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define OPTIMIZE_FLAG (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define OPTIMIZE (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define sh_tclear(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void out_pattern(Sfio_t *iop, register const char *cp, int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(c= *cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(iop,"$'\\n",'\'');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = *++cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ' ':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<': case '>': case ';':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$': case '`': case '\t':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(iop,'\\');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(iop,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void out_string(Sfio_t *iop, register const char *cp, int c, int quoted)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(quoted)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n = stktell(stkstd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sh_fmtq(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop==stkstd && cp==stkptr(stkstd,n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *stkptr(stkstd,stktell(stkstd)-1) = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(iop,cp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct Level
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short maxlevel;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this is for a debugger but it hasn't been tested yet
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if a debug script sets .sh.level it should set up the scope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * as if you were executing in that level
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_level(Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shscope_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Level *lp = (struct Level*)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int16_t level, oldlevel = (int16_t)nv_getnum(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!val)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level = nv_getnum(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(level<0 || level > lp->maxlevel)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putv(np, (char*)&oldlevel, NV_INT16, fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* perhaps this should be an error */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(level==oldlevel)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp = sh_getscope(level,SEEK_SET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_setscope(sp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.id = sp->cmdname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t level_disc = { sizeof(struct Level), put_level };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic struct Level *init_level(int level)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Level *lp = newof(NiL,struct Level,1,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->maxlevel = level;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(SH_LEVELNOD,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(SH_LEVELNOD,NV_INT16|NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_LEVELNOD,(char*)&lp->maxlevel,NV_INT16);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->hdr.disc = &level_disc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_disc(SH_LEVELNOD,&lp->hdr,NV_FIRST);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * write the current common on the stack and make it available as .sh.command
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subscript, char *const argv[], int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp=shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct sh_scoped savst;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np = SH_COMMANDNOD;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *sav = stkptr(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n=4, offset=stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *cp = "+=( ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *iop = stkstd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short level;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->indebug)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->indebug = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(iop,name,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(subscript)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(iop,'[');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out_string(iop,subscript,']',1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flags&ARG_APPEND))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp+=1, n-=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flags&ARG_ASSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(iop,cp,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flags&ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out_string(iop, *argv++,' ', 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (flags&ARG_ARITH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp = *argv++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flags&ARG_EXP) && argv[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out_pattern(iop, cp,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out_string(iop, cp,' ',n?0: (flags&(ARG_RAW|ARG_NOGLOB))||*argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&ARG_ASSIGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(iop,')');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iop==stkstd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *stkptr(stkp,stktell(stkp)-1) = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.cp = stkfreeze(stkp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* now setup .sh.level variable */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.lineno = error_info.line;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin level = shp->fn_depth+shp->dot_depth;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!SH_LEVELNOD->nvfun || !SH_LEVELNOD->nvfun->disc || nv_isattr(SH_LEVELNOD,NV_INT16|NV_NOFREE)!=(NV_INT16|NV_NOFREE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin init_level(level);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_LEVELNOD,(char*)&level,NV_INT16);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savst = shp->st;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.trap[SH_DEBUGTRAP] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sh_trap(trap,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->indebug = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.cmdname)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.id = shp->st.cmdname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st = savst;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sav != stkptr(stkp,0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,sav,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Given stream <iop> compile and execute
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_eval(register Sfio_t *iop, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = sh_getinterp();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct slnod *saveslp = shp->st.staklist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int jmpval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt *pp = (struct checkpt*)shp->jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static Sfio_t *io_save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int traceon=0, lineno=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_save = iop; /* preserve correct value across longjmp */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define SH_TOPFUN 0x8000 /* this is a temporary tksh hack */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (mode & SH_TOPFUN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode ^= SH_TOPFUN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fn_reset = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPEVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buff.olist = pp->olist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode&SH_READEVAL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lineno = shp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(traceon=sh_isoption(SH_XTRACE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_offoption(SH_XTRACE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = (Shnode_t*)sh_parse(shp,iop,(mode&SH_READEVAL)?0:SH_NL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode&SH_READEVAL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode &= SH_READEVAL;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfclose(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_save = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_VERBOSE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode && shp->hist_ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hist_flush(shp->hist_ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = sh_state(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t,sh_isstate(SH_ERREXIT)|mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(traceon)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_onoption(SH_XTRACE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lineno)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->inlineno = lineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io_save)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(io_save);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_freeup(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.staklist = saveslp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fn_reset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPEVAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(*shp->jmplist,jmpval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(shp->exitval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FASTPIPE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int pipe_exec(Shell_t* shp,int pv[], Shnode_t *t, int errorflg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *tchild = t->fork.forktre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile Sfio_t *iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tchild->tre.tretyp&COMMSK)!=TCOM || !(np=(Namval_t*)(tchild->com.comnamp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pipe(pv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_exec(t,errorflg));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pv[0] = shp->lim.open_max;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[pv[0]] = IOREAD|IODUP|IOSEEK;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pv[1] = shp->lim.open_max+1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[pv[1]] = IOWRITE|IOSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sftmp(IOBSIZE+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[shp->lim.open_max+1] = iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPIO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&FPIN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,0,shp->topfd,(char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,1,shp->topfd,(char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&FPIN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,shp->inpipe[0],0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,shp->lim.open_max+1,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = sh_exec(tchild,errorflg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sffileno(sfstdout)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pv[0] = sfsetfd(sfstdout,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sfswap(sfstdout,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[pv[0]] = iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[pv[0]] = IOREAD|IODUP|IOSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(iop,SF_WRITE,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(iop,0L,SEEK_SET);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,buff.topfd,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPIO)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FASTPIPE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 1 when option -<c> is specified
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int checkopt(char *argv[], int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp = *++argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp!='-' || cp[1]=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(strchr(++cp,c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*cp=='h' && cp[1]==0 && *++argv==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void free_list(struct openlist *olist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct openlist *item,*next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(item=olist;item;item=next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = item->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)item);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * set ${.sh.name} and ${.sh.subscript}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * set _ to reference for ${.sh.name}[$.sh.subscript]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int set_instance(Namval_t *nq, Namval_t *node, struct Namref *nr)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp = nv_name(nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namarr_t *ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset(nr,0,sizeof(*nr));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr->np = nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr->root = sh.var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr->table = sh.last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh.var_tree!=sh.var_base && !nv_open(cp,nr->root,NV_VARNAME|NV_NOREF|NV_NOSCOPE|NV_NOADD|NV_NOFAIL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr->root = sh.var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_NAMENOD, cp, NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(node,L_ARGNOD,sizeof(*node));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvalue.nrp = nr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvflag = NV_REF|NV_NOFREE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvfun = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvenv = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((ap=nv_arrayptr(nq)) && (cp = nv_getsub(nq)) && (cp = strdup(cp)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_SUBSCRNOD,nr->sub=cp,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(ap->nelem&ARRAY_SCAN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void unset_instance(Namval_t *nq, Namval_t *node, struct Namref *nr,long mode)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvalue.nrp = node->nvalue.nrp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvflag = node->nvflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvfun = node->nvfun;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nr->sub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(nq, nr->sub, mode);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)nr->sub);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(SH_NAMENOD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(SH_SUBSCRNOD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_exec(register const Shnode_t *t, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(t && !shp->st.execbrk && !sh_isoption(SH_NOEXEC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int type = flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *com0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int errorflg = (type&sh_state(SH_ERREXIT))|OPTIMIZE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int execflg = (type&sh_state(SH_NOFORK));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mainloop = (type&sh_state(SH_INTERACTIVE));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_AMP || SHOPT_SPAWN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ntflag = (type&sh_state(SH_NTFORK));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int topfd = shp->topfd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *sav=stkptr(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp=0, **com=0, *comn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int argn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int skipexitset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_interactive = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_errexit = sh_isstate(SH_ERREXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_monitor = sh_isstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int echeck = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&sh_state(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pipejob = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~sh_state(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_ERREXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_DEFPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_errexit&flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_ERREXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_monitor&flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = t->tre.tretyp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->intrap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->oldexit=shp->exitval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastpath = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(type&COMMSK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TCOM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np, *nq, *last_table;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ionod *io;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int command=0, flgs=NV_ASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->bltindata.invariant = type>>(COMBITS+2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type &= (COMMSK|COMSCAN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_SCMDS);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->com.comline-shp->st.firstline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin com = sh_argbuild(shp,&argn,&(t->com),OPTIMIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin echeck = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = t->com.comarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argp && *com && !(argp->argflag&ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = (Namval_t*)(t->com.comnamp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nq = (Namval_t*)(t->com.comnamq);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com0 = com[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargexit = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(np==SYSCOMMAND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int n = b_command(0,com,&shp->bltindata);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin command += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(com0= *(com+=n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_bfsearch(com0, shp->bltin_tree, &nq, &cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->xargexit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargmin -= command;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargmax -= command;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargmin = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argn -= command;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!command && np && is_abuiltin(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = dtsearch(shp->fun_tree,np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(com0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np && !strchr(com0,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *root = command?shp->bltin_tree:shp->fun_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_bfsearch(com0, root, &nq, &cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_NAMESPACE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->namespace && !nq && !cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,nv_name(shp->namespace),-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'.');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,com0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_bfsearch(stkptr(stkp,offset), root, &nq, &cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comn = com[argn-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io = t->tre.treio;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->envlist = argp = t->com.comset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argn==0 || (np && nv_isattr(np,BLT_SPC)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argn)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(checkopt(com,'A'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flgs |= NV_ARRAY;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(checkopt(com,'a'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flgs |= NV_IARRAY;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==SYSLOCAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_getval(SH_FUNNAMENOD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),"%s: can only be used in a function",com0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->st.var_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_scope(shp,(struct argnod*)0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.var_local = shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==SYSTYPESET || np==SYSLOCAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np==SYSTYPESET || (np && np->nvalue.bfp==SYSTYPESET->nvalue.bfp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np!=SYSTYPESET)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->typeinit = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(checkopt(com,'C'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flgs |= NV_COMVAR;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(checkopt(com,'S'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flgs |= NV_STATIC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(checkopt(com,'n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flgs |= NV_NOREF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(argn>=3 && checkopt(com,'T'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = NV_CLASS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flgs |= NV_TYPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((shp->fn_depth && !shp->prefix) || np==SYSLOCAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flgs |= NV_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(np==SYSEXPORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flgs |= NV_EXPORT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flgs&(NV_EXPORT|NV_NOREF))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flgs |= NV_IDENT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flgs |= NV_VARNAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(OPTIMIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flgs |= NV_TAGGED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setlist(argp,flgs);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np==shp->typeinit)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->typeinit = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->envlist = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = NULL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin last_table = shp->last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((io||argn))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shbltin_t *bp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *argv[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int tflags = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np && nv_isattr(np,BLT_DCL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tflags |= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argn==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* fake 'true' built-in */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = SYSTRUE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argv = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com = argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set +x doesn't echo */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((np!=SYSSET) && sh_isoption(SH_XTRACE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_trace(com-command,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((t->tre.tretyp&FSHOWME) && sh_isoption(SH_SHOWME))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ison = sh_isoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ison)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_XTRACE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_trace(com-command,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_redirect(shp,io,SH_SHOWME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ison)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap=shp->st.trap[SH_DEBUGTRAP])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n = sh_debug(shp,trap,(char*)0,(char*)0, com, ARG_RAW);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n==255 && shp->fn_depth+shp->dot_depth)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = SYSRETURN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argn = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin com[0] = np->nvname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin com[1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n==2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync(shp->outpool);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastpath = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np && !strchr(com0,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(path_search(com0,NIL(Pathcomp_t**),1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->com.comline-shp->st.firstline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((np=nv_search(com0,shp->fun_tree,0)) && !np->nvalue.ip)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *mp=nv_search(com0,shp->bltin_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((np=nv_search(com0,shp->track_tree,0)) && !nv_isattr(np,NV_NOALIAS) && np->nvalue.cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np=nv_search(nv_getval(np),shp->bltin_tree,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for builtins */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np && is_abuiltin(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int scope=0, share=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile void *save_ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile void *save_data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval, save_prompt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long was_vi=0, was_emacs=0, was_gmacs=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp = &shp->bltindata;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin save_ptr = bp->ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin save_data = bp->data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset(&statb, 0, sizeof(struct stat));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strchr(nv_name(np),'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * disable editors for built-in
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * versions of commands on PATH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin was_vi = sh_isoption(SH_VI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin was_emacs = sh_isoption(SH_EMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin was_gmacs = sh_isoption(SH_GMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_VI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_EMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_GMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPCMD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(nv_isattr(np,BLT_ENV)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.flags |= ERROR_SILENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errorpush(&buff.err,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct openlist *item;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==SYSLOGIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(np==SYSEXEC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type=1+!com[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = (execflg && !shp->subshell && !shp->st.trapcom[0]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_redirect(shp,io,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(item=buff.olist;item;item=item->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin item->strm=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(nv_isattr(np,BLT_ENV)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(bp->nosfio)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->pwd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin path_pwd(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->pwd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stat(".",&statb);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync(NULL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin share = sfset(sfstdin,SF_SHARE,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_STOPOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpool(sfstderr,NIL(Sfio_t*),SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstderr,SF_LINE,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin save_prompt = shp->nextprompt;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->nextprompt = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin scope++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_scope(shp,argp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index = opt_info.offset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.disc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = *com;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argn)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->bltinfun = funptr(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->bnode = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->vnode = nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->ptr = nv_context(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->data = t->com.comstate;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->sigset = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->notify = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->flags = (OPTIMIZE!=0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell && nv_isattr(np,BLT_NOSFIO))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_subtmpfile(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(execflg && !shp->subshell &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin !shp->st.trapcom[0] && !shp->st.trap[SH_ERRTRAP] && shp->fn_depth==0 && !nv_isattr(np,BLT_ENV))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* do close-on-exec */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(fd=0; fd < shp->lim.open_max; fd++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((shp->fdstatus[fd]&IOCLEX)&&fd!=shp->infd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argn)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = (*shp->bltinfun)(argn,com,(void*)bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.flags&ERROR_INTERACTIVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tty_check(ERRIO);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((Shnode_t*)t)->com.comstate = shp->bltindata.data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->data = (void*)save_data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isattr(np,BLT_EXIT) && shp->exitval!=SH_RUNPROG)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval &= SH_EXITMASK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct openlist *item;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(item=buff.olist;item;item=item->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(item->strm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclrlock(item->strm);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->hist_ptr && item->strm == shp->hist_ptr->histfp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hist_close(shp->hist_ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(item->strm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->bltinfun && (error_info.flags&ERROR_NOTIFY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (*shp->bltinfun)(-2,com,(void*)bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* failure on special built-ins fatal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval<=SH_JMPCMD && (!nv_isattr(np,BLT_SPC) || command))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(bp && bp->ptr!= nv_context(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvfun = (Namfun_t*)bp->ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(nv_isattr(np,BLT_ENV)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(bp->nosfio && shp->pwd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat stata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stat(".",&stata);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore directory changed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin chdir(shp->pwd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_STOPOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(share&SF_SHARE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstdin,SF_PUBLIC|SF_SHARE,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstderr,SF_LINE,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfpool(sfstderr,shp->outpool,SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpool(sfstdin,NIL(Sfio_t*),SF_WRITE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->nextprompt = save_prompt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errorpop(&buff.err);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.flags &= ~ERROR_SILENT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->bltinfun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff.olist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free_list(buff.olist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_vi)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_VI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(was_emacs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_EMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(was_gmacs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_GMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(scope)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_unscope(shp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->ptr = (void*)save_ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->data = (void*)save_data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't restore for subshell exec */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((shp->topfd>topfd) && !(shp->subshell && np==SYSEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,topfd,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flgs&NV_STATIC)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((Shnode_t*)t)->com.comset = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->exitval >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto setexit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for functions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!command && np && nv_isattr(np,NV_FUNCTION))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int indx;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Namref nr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin long mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct slnod *slp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np->nvalue.ip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin indx = path_search(com0,NIL(Pathcomp_t**),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(indx==1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_search(com0,shp->fun_tree,HASH_NOSCOPE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np->nvalue.ip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(indx==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(0),e_defined,com0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = ERROR_NOEXEC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(0),e_found,"function");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = ERROR_NOENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto setexit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* increase refcnt for unset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp = (struct slnod*)np->nvenv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_funstaks(slp->slchild,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin staklink(slp->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = set_instance(nq,&node,&nr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin indx = shp->topfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPCMD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin indx = sh_redirect(shp,io,execflg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_funct(shp,np,argn,com,t->com.comset,(flags&~OPTIMIZE_FLAG));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff.olist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free_list(buff.olist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,indx,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unset_instance(nq,&node,&nr,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_funstaks(slp->slchild,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakdelete(slp->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval > SH_JMPFUN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto setexit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!io)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setexit:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitset();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFORK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register pid_t parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int no_fork,jobid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pipes[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin no_fork = (execflg && !(type&(FAMP|FPOU)) &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_AMP || SHOPT_SPAWN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin !ntflag &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin !shp->subshell && !shp->st.trapcom[0] &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin !shp->st.trap[SH_ERRTRAP] && shp->fn_depth==0 &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin !(pipejob && sh_isoption(SH_PIPEFAIL)));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_subtmpfile(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_isstate(SH_PROFILE) || shp->dot_depth)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* disable foreground job monitor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(type&FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_DEVFD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(type&FINT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_DEVFD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(no_fork)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.parent=parent=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FCOOP)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin coproc_init(shp,pipes);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_getval(RANDNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_AMP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&(FAMP|FINT)) == (FAMP|FINT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin parent = sh_ntfork(shp,t,com,&jobid,ntflag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin parent = sh_fork(type,&jobid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(parent<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_SPAWN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef _lib_fork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin parent = sh_ntfork(shp,t,com,&jobid,ntflag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin parent = sh_fork(type,&jobid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((parent = sh_ntfork(shp,t,com,&jobid,ntflag))<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* _lib_fork */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(parent<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin parent = sh_fork(type,&jobid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_SPAWN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.parent=parent)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This is the parent branch of fork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * It may or may not wait for the child
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPCL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_close(shp->inpipe[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&(FCOOP|FAMP))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->bckpid = parent;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!(type&(FAMP|FPOU)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->topfd > topfd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,topfd,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sh_isoption(SH_MONITOR))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(shp->sigflag[SIGINT]&(SH_SIGFAULT|SH_SIGOFF)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_sigtrap(SIGINT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote |= SH_SIGIGNORE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(execflg && shp->subshell)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->spid = parent;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job.pwlist->p_env--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job_wait(parent);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sh_isoption(SH_MONITOR))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote &= ~SH_SIGIGNORE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->exitval == (SH_EXITSIG|SIGINT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_fault(SIGINT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FAMP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_PROFILE) || sh_isstate(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* print job number */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"[%d]\t%d\n",jobid,parent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"%d\n",parent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this is the FORKED branch (child) of execute
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int jmpval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(no_fork)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigreset(2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPEXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&FINT) && !sh_isstate(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* default std input for & */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGINT,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGQUIT,SIG_IGN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->st.ioset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_close(0)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_chkopen(e_devnull);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* pipe in or out */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _lib_nice
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&FAMP) && sh_isoption(SH_BGNICE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nice(4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_nice */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,shp->inpipe[0],0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(type&FPOU) || (type&FCOOP))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_close(shp->inpipe[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPOU)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,shp->outpipe[1],1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_pclose(shp->outpipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&COMMSK)!=TCOM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->fork.forkline-shp->st.firstline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->topfd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iounsave(shp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin topfd = shp->topfd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_redirect(shp,t->tre.treio,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->topfd > topfd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((parent = vfork()) < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _sh_fork(parent, 0, (int*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(parent)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job_clear();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job_post(parent,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job_wait(parent);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,topfd,SH_JMPCMD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,(shp->exitval&SH_EXITSIG)?(shp->exitval&SH_EXITMASK):0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&COMMSK)!=TCOM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't clear job table for out
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pipes so that jobs comand can
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin be used in a pipeline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!no_fork && !(type&FPOU))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_clear();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->fork.forktre,flags|sh_state(SH_NOFORK));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(com0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_ERREXIT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_freeup(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_exec(com0,com,t->com.comset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPEXIT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TSETIO:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * don't create a new process, just
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * save and restore io-streams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int jmpval, waitall;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin execflg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPIO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin was_interactive = sh_isstate(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!execflg)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,0,shp->topfd,(char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,shp->inpipe[0],0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if read end of pipe is a simple command
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * treat as non-sharable to improve performance
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((t->fork.forktre->tre.tretyp&COMMSK)==TCOM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstdin,SF_PUBLIC|SF_SHARE,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin waitall = job.waitall;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitall = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = job.parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->fork.forkline-shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_redirect(shp,t->fork.forkio,execflg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->fork.forktre)->tre.tretyp |= t->tre.tretyp&FSHOWME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->fork.forktre,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync(shp->outpool);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,buff.topfd,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff.olist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free_list(buff.olist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitall = waitall;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(type&SH_EXITSIG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* wait for remainder of pipline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_wait(waitall?pid:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type || !sh_isoption(SH_PIPEFAIL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.ioset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPIO)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TPAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin echeck = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~OPTIMIZE_FLAG;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->subshell && !shp->st.trapcom[0] && !shp->st.trap[SH_ERRTRAP] && (flags&sh_state(SH_NOFORK)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int jmpval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPEXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->par.partre,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval > SH_JMPEXIT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_subshell(t->par.partre,flags,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFIL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This code sets up a pipe.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * All elements of the pipe are started by the parent.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The last element executes in current environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pvo[2]; /* old pipe for multi-stage */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pvn[2]; /* current set up pipe */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int savepipe = pipejob;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int showme = t->tre.tretyp&FSHOWME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t savepgid = job.curpgid;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job.curpgid = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_subtmpfile(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->inpipe = pvo;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->outpipe = pvn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pvo[1] = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_PIPEFAIL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitall = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitall |= !pipejob && sh_isstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FASTPIPE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = pipe_exec(shp,pvn,t->lst.lstlef, errorflg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* create the pipe */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pipe(pvn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* execute out part of pipe no wait */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->lst.lstlef)->tre.tretyp |= showme;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = sh_exec(t->lst.lstlef, errorflg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FASTPIPE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pipejob=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save the pipe stream-ids */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pvo[0] = pvn[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* close out-part of pipe */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(pvn[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* pipeline all in one process group */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = t->lst.lstrit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* repeat until end of pipeline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(!type && t->tre.tretyp==TFIL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->inpipe = pvn;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->outpipe = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * execute last element of pipeline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * in the current process
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((Shnode_t*)t)->tre.tretyp |= showme;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* execution failure, close pipe */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pclose(pvn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pipejob = savepipe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pipejob && sh_isstate(SH_MONITOR))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tcsetpgrp(JOBTTY,shp->pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = savepgid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TLST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* a list of commands are executed here */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->lst.lstlef,errorflg|OPTIMIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = t->lst.lstrit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(t->tre.tretyp == TLST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TAND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&TTEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skipexitset++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_exec(t->lst.lstlef,OPTIMIZE)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->lst.lstrit,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TORF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&TTEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skipexitset++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_exec(t->lst.lstlef,OPTIMIZE)!=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->lst.lstrit,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFOR: /* for and select */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **args;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int nargs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flag = errorflg|OPTIMIZE_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct dolnod *argsav=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct comnod *tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp, *trap, *nullptr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nameref, refresh=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *av[5];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval = ((struct checkpt*)shp->jmplist)->mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void *optlist = shp->optlist;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->optlist = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(t->for_.fortre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto endfor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->for_.forline-shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(tp=t->for_.forlst))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin args=shp->st.dolv+1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nargs = shp->st.dolc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argsav=sh_arguse(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin args=sh_argbuild(shp,&argn,tp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nargs = argn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(t->for_.fornam, shp->var_tree,NV_NOASSIGN|NV_NOARRAY|NV_VARNAME|NV_NOREF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nameref = nv_isref(np)!=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = *args;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(cp && shp->st.execbrk==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int save_prompt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* reuse register */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(refresh)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_menu(sfstderr,nargs,args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin refresh = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin save_prompt = shp->nextprompt;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->nextprompt = 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->timeout = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval=sh_readline(shp,&nullptr,0,1,1000*shp->st.tmout);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->nextprompt = save_prompt;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->exitval||sfeof(sfstdin)||sferror(sfstdin))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(val=nv_getval(sh_scoped(shp,REPLYNOD))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*(cp=val) == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin refresh++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto check;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(type = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type < '0' && type > '9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = nargs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = (int)strtol(val, (char**)0, 10)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type<0 || type >= nargs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = args[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nameref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_REF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np, NV_ARRAY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),0L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np,cp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nameref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setref(np,(Dt_t*)0,NV_VARNAME);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap=shp->st.trap[SH_DEBUGTRAP])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[0] = (t->tre.tretyp&COMSCAN)?"select":"for";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[1] = t->for_.fornam;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin av[2] = "in";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[3] = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin av[4] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,(char*)0,(char*)0,av,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->for_.fortre,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= ~OPTIMIZE_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((cp=nv_getval(sh_scoped(shp,REPLYNOD))) && *cp==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin refresh++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = *++args;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin check:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.breakcnt<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.execbrk = (++shp->st.breakcnt !=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endfor:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(t->for_.fortre);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_optclear(shp,optlist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_OPTIMIZE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.breakcnt>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.execbrk = (--shp->st.breakcnt !=0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_argfree(shp,argsav,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TWH: /* while and until */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int r=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int first = OPTIMIZE_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shnode_t *tt = t->wh.whtre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *iop=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int savein,fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_FILESCAN*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval = ((struct checkpt*)shp->jmplist)->mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void *optlist = shp->optlist;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->optlist = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(t->wh.whtre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(t->wh.dotre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto endwhile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==TWH && tt->tre.tretyp==TCOM && !tt->com.comarg && tt->com.comio)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = sh_redirect(shp,tt->com.comio,3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savein = dup(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = savein;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sfnew(NULL,NULL,SF_UNBOUND,fd,SF_READ);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin open("/dev/null",O_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->offsets[0] = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->offsets[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tt->com.comset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setlist(tt->com.comset,NV_IDENT|NV_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_FILESCAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(shp->st.execbrk==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(shp->cur_line=sfgetr(iop,'\n',SF_STRING)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_FILESCAN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sh_exec(tt,first)==0)!=(type==TWH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = sh_exec(t->wh.dotre,first|errorflg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.breakcnt<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.execbrk = (++shp->st.breakcnt !=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This is for the arithmetic for */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.execbrk==0 && t->wh.whinc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec((Shnode_t*)t->wh.whinc,first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errorflg &= ~OPTIMIZE_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->offsets[0] = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->offsets[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_FILESCAN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endwhile:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(t->wh.whtre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_tclear(t->wh.dotre);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_optclear(shp,optlist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_OPTIMIZE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.breakcnt>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.execbrk = (--shp->st.breakcnt !=0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval= r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dup(savein);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->cur_line = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_FILESCAN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TARITH: /* (( expression )) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *arg[4];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->ar.arline-shp->st.firstline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arg[0] = "((";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(t->ar.arexpr->argflag&ARG_RAW))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arg[1] = sh_macpat(shp,t->ar.arexpr,OPTIMIZE|ARG_ARITH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg[1] = t->ar.arexpr->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arg[2] = "))";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arg[3] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap=shp->st.trap[SH_DEBUGTRAP])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,(char*)0, (char*)0, arg, ARG_ARITH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_XTRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trace(NIL(char**),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"((%s))\n",arg[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->ar.arcomp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = !arith_exec((Arith_t*)t->ar.arcomp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = !sh_arith(arg[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_exec(t->if_.iftre,OPTIMIZE)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->if_.thtre,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(t->if_.eltre)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->if_.eltre, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval=0; /* force zero exit for if-then-fi */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TSW:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shnode_t *tt = (Shnode_t*)t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *trap, *r = sh_macpat(shp,tt->sw.swarg,OPTIMIZE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->sw.swline-shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t= (Shnode_t*)(tt->sw.swlst);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap=shp->st.trap[SH_DEBUGTRAP])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *av[4];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin av[0] = "case";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[1] = r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin av[2] = "in";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin av[3] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap, (char*)0, (char*)0, av, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *rex=(struct argnod*)t->reg.regptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(rex)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rex->argflag&ARG_MAC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s = sh_macpat(shp,rex,OPTIMIZE|ARG_EXP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*s=='\\' && s[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s+=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = rex->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = (rex->argflag&ARG_RAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type && strcmp(r,s)==0) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (!type && (strmatch(r,s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || trim_eq(r,s))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do sh_exec(t->reg.regcom,(t->reg.regflag?0:flags));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(t->reg.regflag &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t=(Shnode_t*)t->reg.regnxt));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rex=rex->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t=(Shnode_t*)t->reg.regnxt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TTIME:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* time the command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tms before,after;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *format = e_timeformat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock_t at, tm[3];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef timeofday
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct timeval tb,ta;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock_t bt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* timeofday */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=TTIME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->par.partre,OPTIMIZE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = !shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->par.partre)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long timer_on;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timer_on = sh_isstate(SH_TIMING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef timeofday
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeofday(&tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&before);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bt = times(&before);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* timeofday */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitall = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_TIMING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->par.partre,OPTIMIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!timer_on)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_TIMING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitall = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef timeofday
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bt = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* timeofday */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin before.tms_utime = before.tms_cutime = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin before.tms_stime = before.tms_cstime = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef timeofday
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&after);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeofday(&ta);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin at = shp->lim.clk_tck*(ta.tv_sec-tb.tv_sec);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin at += ((shp->lim.clk_tck*(((1000000L/2)/shp->lim.clk_tck)+(ta.tv_usec-tb.tv_usec)))/1000000L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin at = times(&after) - bt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* timeofday */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm[0] = at;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->par.partre)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *np = nv_open("TIMEFORMAT",shp->var_tree,NV_NOADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = e_timeformat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = strchr(format+1,'\n')+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm[1] = after.tms_utime - before.tms_utime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm[1] += after.tms_cutime - before.tms_cutime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm[2] = after.tms_stime - before.tms_stime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm[2] += after.tms_cstime - before.tms_cstime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(format && *format)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin p_time(shp,sfstderr,sh_translate(format),tm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFUN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct slnod *slp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *fname = ((struct functnod*)t)->functnam;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = strrchr(fname,'.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *npv=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_NAMESPACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp==TNSPACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *root,*oldroot, *top=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *oldnspace = shp->namespace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin long optindex = shp->st.optindex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_ident,fname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'.');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,fname,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(stkptr(stkp,offset),shp->var_base,NV_NOASSIGN|NV_NOARRAY|NV_VARNAME);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->namespace = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(root=nv_dict(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = dtopen(&_Nvdisc,Dtoset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np,(char*)root,NV_TABLE|NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.optindex = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(oldnspace && dtvnext(dtvnext(shp->var_tree)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin top = dtview(shp->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(dtvnext(shp->var_tree))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin top = dtview(shp->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin oldroot = shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(root,shp->var_base);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(top)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(shp->var_tree,top);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->for_.fortre,flags);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(dtvnext(shp->var_tree))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin top = dtview(shp->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = oldroot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(top)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(top,shp->var_tree);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->namespace = oldnspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.optindex = optindex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* look for discipline functions */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->funct.functline-shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Function names cannot be special builtin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp || shp->prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = shp->prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin npv = nv_open(cp,shp->var_tree,NV_NOASSIGN|NV_NOARRAY|NV_VARNAME);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,fname,cp++-fname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin npv = nv_open(stkptr(stkp,offset),shp->var_tree,NV_NOASSIGN|NV_NOARRAY|NV_VARNAME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(stkp,"%s.%s%c",nv_name(npv),cp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fname = stkptr(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((np=nv_search(fname,shp->bltin_tree,0)) && nv_isattr(np,BLT_SPC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_badfun,fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_NAMESPACE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(shp->namespace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,nv_name(shp->namespace),-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'.');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,fname,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fname = stkptr(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(fname,sh_subfuntree(1),NV_NOASSIGN|NV_NOARRAY|NV_VARNAME|NV_NOSCOPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(npv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *tp = npv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->mktype)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->typeinit)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp=nv_open(shp->typeinit->nvname,shp->typedict,NV_IDENT|NV_NOFAIL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_close(npv);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tp = npv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = nv_setdisc(tp,cp,np,(Namfun_t*)tp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_close(tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_baddisc,fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np->nvalue.rp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp = (struct slnod*)np->nvenv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_funstaks(slp->slchild,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakdelete(slp->slptr);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->funload)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)np->nvalue.rp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.rp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np->nvalue.rp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.rp = new_of(struct Ufunction,shp->funload?sizeof(Dtlink_t):0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset((void*)np->nvalue.rp,0,sizeof(struct Ufunction));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->funct.functstak)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static Dtdisc_t _Rpdisc =
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offsetof(struct Ufunction,fname), -1, sizeof(struct Ufunction)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct functnod *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp = t->funct.functstak;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_funstaks(slp->slchild,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin staklink(slp->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvenv = (char*)slp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_funtree(np) = (int*)(t->funct.functtre);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.rp->hoffset = t->funct.functloc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.rp->lineno = t->funct.functline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.rp->nspace = shp->namespace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.rp->fname = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.rp->fdict = shp->fun_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = (struct functnod*)(slp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->functtyp==(TFUN|FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.rp->fname = fp->functnam;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,fp->functline);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_FPOSIX);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->funload)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Ufunction *rp = np->nvalue.rp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rp->np = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->fpathdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fpathdict = dtopen(&_Rpdisc,Dtbag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fpathdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtinsert(shp->fpathdict,rp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPOSIX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_FUNCTION|NV_FPOSIX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_FUNCTION);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&FPIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_FTMP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type&FOPTGET)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(np,NV_OPTGET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* new test compound command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TTST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int negate = (type&TNEGATE)!=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&TTEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skipexitset++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = t->tst.tstline-shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin echeck = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&TPAREN)==TPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(t->lst.lstlef,OPTIMIZE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = !shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int traceon=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *argv[6];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = type>>TSHIFT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin left = sh_macpat(shp,&(t->lst.lstlef->arg),OPTIMIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&TBINARY)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin right = sh_macpat(shp,&(t->lst.lstrit->arg),((n==TEST_PEQ||n==TEST_PNE)?ARG_EXP:0)|OPTIMIZE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap=shp->st.trap[SH_DEBUGTRAP])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = (type&TNEGATE)?((char*)e_tstbegin):"[[";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_XTRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin traceon = sh_trace(NIL(char**),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr,e_tstbegin,(type&TNEGATE?5:3));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type&TUNARY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"-%c %s",n,sh_fmtq(left));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char unop[3];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unop[0] = '-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unop[1] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unop[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[1] = unop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[2] = left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[3] = "]]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[4] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,(char*)0,(char*)0,argv, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = test_unop(n,left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type&TBINARY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pattern = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap || traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op = (char*)(shtab_testops+(n&037)-1)->sh_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type >>= TSHIFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==TEST_PEQ || type==TEST_PNE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pattern=ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[1] = left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[2] = op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[3] = right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[4] = "]]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[5] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,(char*)0,(char*)0,argv, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = test_binop(n,left,right);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"%s %s ",sh_fmtq(left),op);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out_pattern(sfstderr,right,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,sh_fmtq(right),-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr,e_tstend,4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = ((!n)^negate);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!skipexitset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitset();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->trapnote || (shp->exitval && sh_isstate(SH_ERREXIT)) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t && echeck)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_chktrap();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set $_ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mainloop && com0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* store last argument here if it fits */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char lastarg[32];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_FORKED))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->lastarg!= lastarg && shp->lastarg)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free(shp->lastarg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(strlen(comn) < sizeof(lastarg))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(L_ARGNOD,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastarg = strcpy(lastarg,comn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(L_ARGNOD,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastarg = strdup(comn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!skipexitset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitset();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(OPTIMIZE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sav != stkptr(stkp,0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,sav,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(stktell(stkp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->trapnote&SH_SIGSET)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_exit(SH_EXITSIG|shp->lastsig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_interactive)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_monitor && sh_isoption(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_errexit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_ERREXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(shp->exitval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_run(int argn, char *argv[])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct dolnod *dp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct comnod *t = (struct comnod*)stakalloc(sizeof(struct comnod));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savtop = staktell();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *savptr = stakfreeze(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Opt_t *op, *np = optctx(0, 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shbltin_t bltindata;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bltindata = sh.bltindata;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin op = optctx(np, 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset(t, 0, sizeof(struct comnod));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp = (struct dolnod*)stakalloc((unsigned)sizeof(struct dolnod) + ARG_SPARE*sizeof(char*) + argn*sizeof(char*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->dolnum = argn;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->dolbot = ARG_SPARE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(dp->dolval+ARG_SPARE, argv, (argn+1)*sizeof(char*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->comarg = (struct argnod*)dp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!strchr(argv[0],'/'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->comnamp = (void*)nv_bfsearch(argv[0],sh.fun_tree,(Namval_t**)&t->comnamq,(char**)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argn=sh_exec((Shnode_t*)t,sh_isstate(SH_ERREXIT));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin optctx(op,np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.bltindata = bltindata;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(savptr!=stakptr(0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakset(savptr,savtop);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakseek(savtop);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(argn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * test for equality with second argument trimmed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 1 if r == trim(s) otherwise 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int trim_eq(register const char *r,register const char *s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c && c != *r++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*r==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print out the command line if set -x is on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_trace(register char *argv[], register int nl)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int bracket = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int decl = (nl&2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nl &= ~2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_XTRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make this trace atomic */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstderr,SF_SHARE|SF_PUBLIC,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(cp=nv_getval(sh_scoped(shp,PS4NOD))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "+ ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XTRACE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = sh_mactry(shp,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,cp,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *argv0 = *argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nl = (nl?'\n':-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't quote [ and [[ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*(cp=argv[0])=='[' && (!cp[1] || !cp[2]&&cp[1]=='['))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,cp,*++argv?' ':nl);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bracket = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp = *argv++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bracket==0 || *argv || *cp!=']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sh_fmtq(cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(decl && shp->prefix && cp!=argv0 && *cp!='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='.' && cp[1]==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = shp->prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(sfstderr,shp->prefix,'.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,cp,*argv?' ':nl);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstderr,SF_SHARE|SF_PUBLIC,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine creates a subshell by calling fork() or vfork()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If ((flags&COMASK)==TCOM), then vfork() is permitted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If fork fails, the shell sleeps for exponentially longer periods
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and tries again until a limit is reached.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * SH_FORKLIM is the max period between forks - power of 2 usually.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Currently shell tries after 2,4,8,16, and 32 seconds and then quits
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Failures cause the routine to error exit.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Parent links to here-documents are removed by the child
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Traps are reset by the child
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The process-id of the child is returned to the parent, 0 to the child.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void timed_out(void *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeout = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called by parent and child after fork by sh_fork()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t _sh_fork(register pid_t parent,int flags,int *jobid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static long forkcnt = 1000L;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t curpgid = job.curpgid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t postid = (flags&FAMP)?0:curpgid;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int sig,nochild;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(parent<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((forkcnt *= 2) > 1000L*SH_FORKLIM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin forkcnt=1000L;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_nofork);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeout = (void*)sh_timeradd(forkcnt, 0, timed_out, NIL(void*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nochild = job_wait((pid_t)1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(timeout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nochild)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pause();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(forkcnt>1000L)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin forkcnt /= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timerdel(timeout);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin timeout = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin forkcnt = 1000L;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(parent)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int myjob,waitall=job.waitall;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->nforks++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.toclear)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_clear();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job.waitall = waitall;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first process defines process group */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * errno==EPERM means that an earlier processes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * completed. Make parent the job group id.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(postid==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.jobcontrol || (flags&FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setpgid(parent,job.curpgid)<0 && errno==EPERM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setpgid(parent,parent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isstate(SH_MONITOR) && job.waitall && postid==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&FCOOP)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->cpid = parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin myjob = job_post(parent,postid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&FAMP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = curpgid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jobid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *jobid = myjob;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(parent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_std_malloc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmtrace(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This is the child process */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->trapnote&SH_SIGTERM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG|SIGTERM);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->nforks=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timerdel(NIL(void*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!job.jobcontrol && !(flags&FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin parent = getpid();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(postid==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(setpgid(0,job.curpgid)<0 && job.curpgid!=parent)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.curpgid==parent && !(flags&FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tcsetpgrp(job.fd,job.curpgid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.jobcontrol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTIN,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTOU,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTSTP,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.jobcontrol = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.toclear = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->login_sh = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_LOGIN_SHELL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_FORKED);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_NOLOG);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (shp->fn_reset)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fn_depth = shp->fn_reset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_ACCT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_accsusp();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Reset remaining signals to parent */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* except for those `lost' by trap */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigreset(2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->subshell = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&FAMP) && shp->coutpipe>1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_close(shp->coutpipe);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sig = shp->savesig;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->savesig = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fault(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t sh_fork(int flags, int *jobid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register pid_t parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int sig;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FASTPIPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sffileno(sfstdin)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_t current = sfseek(sfstdin,(off_t)0,SEEK_CUR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(sfstdin,(off_t)0,SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(sfstdin,SF_POPDISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(sffileno(sfstdin),F_SETFD,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_iostream(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(sfstdin,current,SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FASTPIPE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh.pathlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_get("");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote &= ~SH_SIGTERM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_fork(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.savesig = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(_sh_fork(parent=fork(),flags,jobid) < 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_FORKS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sig = sh.savesig;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.savesig = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fault(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_fork(parent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(parent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add exports from previous scope to the new scope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void local_exports(register Namval_t *np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp = nv_getval(np)) && (mp = nv_search(nv_name(np), sh.var_tree, NV_ADD|HASH_NOSCOPE)) && nv_isnull(mp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(mp, cp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine is used to execute the given function <fun> in a new scope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <fun> is NULL, then arg points to a structure containing a pointer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * to a function that will be executed in the current environment.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_funscope(int argn, char *argv[],int(*fun)(void*),void *arg,int execflg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *trap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int nsig;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct dolnod *argsav=0,*saveargfor;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct sh_scoped savst, *prevscope = shp->st.self;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct argnod *envlist=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int r = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *savstak;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct funenv *fp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *nspace = shp->namespace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fn_depth==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->glob_options = shp->options;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->options = shp->glob_options;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.lineno = error_info.line;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *prevscope = shp->st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_ERREXIT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.prevst = prevscope;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.self = &savst;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->topscope = (Shscope_t*)shp->st.self;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.opterror = shp->st.optchar = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.optindex = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = (struct funenv*)arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.real_fun = (fp->node)->nvalue.rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envlist = fp->env;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin prevscope->save_tree = shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_scope(shp,envlist,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(dtvnext(prevscope->save_tree)!= (shp->namespace?shp->var_base:0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* eliminate parent scope */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_scan(prevscope->save_tree, local_exports,(void*)0, NV_EXPORT, NV_EXPORT|NV_NOSCOPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.save_tree = shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(fp->node,NV_TAGGED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_NAMESPACE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((np=(fp->node)->nvalue.rp->nspace) && np!=shp->namespace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *dt = shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtview(dt,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtview(dt,nv_dict(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = nv_dict(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->namespace = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.cmdname = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save trap table */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((nsig=shp->st.trapmax*sizeof(char*))>0 || shp->st.trapcom[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nsig += sizeof(char*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(savstak=stakalloc(nsig),(char*)&shp->st.trapcom[0],nsig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigreset(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argsav = sh_argnew(shp,argv,&saveargfor);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPFUN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errorpush(&buff.err,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = argv[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.var_local = shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.filename = fp->node->nvalue.rp->fname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.funname = nv_name(fp->node);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fn_depth++ > MAXDEPTH)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,SH_JMPERRFN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r= (*fun)(arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec((Shnode_t*)(nv_funtree((fp->node))),execflg|SH_ERREXIT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(--shp->fn_depth==1 && jmpval==SH_JMPERRFN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_toodeep,argv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (shp->st.self != &savst)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = (Dt_t*)savst.save_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_unscope(shp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->namespace = nspace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = (Dt_t*)prevscope->save_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->topscope != (Shscope_t*)shp->st.self)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_setscope(shp->topscope);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_argreset(shp,argsav,saveargfor);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin trap = shp->st.trapcom[0];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.trapcom[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigreset(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (shp->st.self != &savst)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *shp->st.self = shp->st;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st = *prevscope;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->topscope = (Shscope_t*)prevscope;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_getval(sh_scoped(shp,IFSNOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nsig)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy((char*)&shp->st.trapcom[0],savstak,nsig);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nsig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(savstak,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->options = shp->glob_options;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trap(trap,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(trap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->exitval > SH_EXITSIG)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_fault(shp->exitval&SH_EXITMASK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval > SH_JMPFUN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_chktrap();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void sh_funct(Shell_t *shp,Namval_t *np,int argn, char *argv[],struct argnod *envlist,int execflg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct funenv fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *fname = nv_getval(SH_FUNNAMENOD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Level *lp =(struct Level*)(SH_LEVELNOD->nvfun);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int level;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_FUNCT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->hdr.disc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp = init_level(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((struct sh_scoped*)shp->topscope != shp->st.self)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_setscope(shp->topscope);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin level = lp->maxlevel = shp->dot_depth + shp->fn_depth+1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SH_LEVELNOD->nvalue.s = lp->maxlevel;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.lineno = error_info.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_FPOSIX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int loopcnt = shp->st.loopcnt;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->posix_fun = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin save = argv[-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[-1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.funname = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(SH_FUNNAMENOD, nv_name(np),NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin opt_info.index = opt_info.offset = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.errors = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin b_dot_cmd(argn+1,argv-1,&shp->bltindata);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.loopcnt = loopcnt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[-1] = save;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fun.env = envlist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fun.node = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_funscope(argn,argv,0,&fun,execflg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(level-- != nv_getnum(SH_LEVELNOD))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shscope_t *sp = sh_getscope(0,SEEK_END);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_setscope(sp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->maxlevel = level;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SH_LEVELNOD->nvalue.s = lp->maxlevel;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(SH_FUNNAMENOD,fname,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * external interface to execute a function without arguments
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <np> is the function node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <nq> is not-null, then sh.name and sh.subscript will be set
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_fun(Namval_t *np, Namval_t *nq, char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Namref nr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin long mode;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *prefix = shp->prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *av[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t save;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((offset=staktell())>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base=stakfreeze(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv = av;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[1]=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argv[n])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = set_instance(nq,&node, &nr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_abuiltin(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int jmpval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shbltin_t *bp = &sh.bltindata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPCMD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->bnode = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp->ptr = nv_context(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errorpush(&buff.err,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index = opt_info.offset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.disc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.exitval = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.exitval = (*funptr(np))(n,argv,(void*)bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPCMD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(*sh.jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_funct(shp,np,n,argv,(struct argnod*)0,sh_isstate(SH_ERREXIT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unset_instance(nq, &node, &nr, mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(base,offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh.exitval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This dummy routine is called by built-ins that do recursion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * on the file system (chmod, chgrp, chown). It causes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the shell to invoke the non-builtin version in this case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint cmdrecurse(int argc, char* argv[], int ac, char* av[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(argc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(argv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(ac);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(av[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(SH_RUNPROG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set up pipe for cooperating process
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void coproc_init(Shell_t *shp, int pipes[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int outfd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->coutpipe>=0 && shp->cpid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_pexists);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->cpid = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->cpipe[0]<=0 || shp->cpipe[1]<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first co-process */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_pclose(shp->cpipe);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_pipe(shp->cpipe);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((outfd=shp->cpipe[1]) < 10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int fd=fcntl(shp->cpipe[1],F_DUPFD,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(outfd);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[outfd] = IOCLOSE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->cpipe[1] = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcntl(*shp->cpipe,F_SETFD,FD_CLOEXEC)>=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[shp->cpipe[0]] |= IOCLEX;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdptrs[shp->cpipe[0]] = shp->cpipe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcntl(shp->cpipe[1],F_SETFD,FD_CLOEXEC) >=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[shp->cpipe[1]] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->outpipe = shp->cpipe;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_pipe(shp->inpipe=pipes);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->coutpipe = shp->inpipe[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdptrs[shp->coutpipe] = &shp->coutpipe;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[shp->outpipe[0]] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_SPAWN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_AMP || !defined(_lib_fork)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print out function definition
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void print_fun(register Namval_t* np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *format;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!is_afunction(np) || !np->nvalue.ip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_FPOSIX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format="%s()\n{ ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format="function %s\n{ ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,format,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_deparse(sfstdout,(Shnode_t*)(nv_funtree(np)),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstdout,"}\n",2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create a shell script consisting of t->fork.forktre and execute it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int run_subshell(const Shnode_t *t,pid_t grp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static const char prolog[] = "(print $(typeset +A);set; typeset -p; print .sh.dollar=$$;set +o)";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i, fd, trace = sh_isoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pin,pout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *arglist[2], *envlist[2], devfd[12], *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp = sftmp(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envlist[0] = "_=" SH_ID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envlist[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arglist[0] = error_info.id?error_info.id:sh.shname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*arglist[0]=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arglist[0]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arglist[1] = devfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncpy(devfd,e_devfdNN,sizeof(devfd));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arglist[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstack(sfstdout,sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstdout,"typeset -A -- ",14);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trap(prolog,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_scan(sh.fun_tree, print_fun, (void*)0,0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.st.dolc>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* pass the positional parameters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **argv = sh.st.dolv+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstdout,"set --",6);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout," %s",sh_fmtq(*argv++));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstdout,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pin = (sh.inpipe?sh.inpipe[1]:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pout = (sh.outpipe?sh.outpipe[0]:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=3; i < 10; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.fdstatus[i]&IOCLEX && i!=pin && i!=pout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"exec %d<&%d\n",i,i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(i,F_SETFD,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"LINENO=%d\n",t->fork.forkline);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstdout,"set -x\n",7);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstack(sfstdout,NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_deparse(sp,t->fork.forktre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(sp,(Sfoff_t)0,SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sh_dup(sffileno(sp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = devfd+8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>9)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp++ = '0' + (fd/10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp++ = '0' + fd%10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh.shpath)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.shpath = pathshell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = spawnveg(sh.shpath,arglist,envlist,grp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=3; i < 10; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.fdstatus[i]&IOCLEX && i!=pin && i!=pout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(i,F_SETFD,FD_CLOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pid <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,arglist[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !_lib_fork */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void sigreset(int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int sig=sh.st.trapmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sig-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((trap=sh.st.trapcom[sig]) && *trap==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(sig,mode?sh_fault:SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A combined fork/exec for systems with slow or non-existent fork()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic pid_t sh_ntfork(Shell_t *shp,const Shnode_t *t,char *argv[],int *jobid,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static pid_t spawnpid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int savetype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int savejobid;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int otype=0, jmpval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile int jobwasset=0, scope=0, sigwasset=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char **arge, *path;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin volatile pid_t grp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Pathcomp_t *pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin otype = savetype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savetype=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if SHOPT_AMP || !defined(_lib_fork)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *tchild = t->fork.forktre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int optimize=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin otype = t->tre.tretyp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savetype = otype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin spawnpid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef _lib_fork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tchild->tre.tretyp&COMMSK)==TCOM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np = (Namval_t*)(tchild->com.comnamp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,BLT_ENV))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(strcmp(path,"echo")==0 || memcmp(path,"print",5)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!tchild->com.comarg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin optimize=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(tchild->com.comtyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tchild->com.comarg->argflag&ARG_RAW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = tchild->com.comarg->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = ((struct dolnod*)tchild->com.comarg)->dolval[ARG_SPARE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np && path && !nv_search(path,shp->fun_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin optimize=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPIO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((otype&FINT) && !sh_isstate(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGQUIT,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGINT,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!shp->st.ioset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,0,buff.topfd,(char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,sh_chkopen(e_devnull),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(otype&FPIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd = shp->inpipe[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,0,buff.topfd,(char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,shp->inpipe[0],0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=0 && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(fd,F_SETFD,FD_CLOEXEC)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->fdstatus[fd] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(otype&FPOU)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,1,buff.topfd,(char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorenumber(shp,sh_dup(shp->outpipe[1]),1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->fdstatus[shp->outpipe[0]] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->fork.forkio)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_redirect(shp,t->fork.forkio,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(optimize==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.jobcontrol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTIN,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTOU,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_MONITOR) && (job.jobcontrol || (otype&FAMP)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((otype&FAMP) || job.curpgid==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin grp = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin grp = job.curpgid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin spawnpid = run_subshell(t,grp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(tchild,SH_NTFORK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jobid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *jobid = savejobid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((otype&FINT) && !sh_isstate(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGQUIT,sh_fault);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGINT,sh_fault);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((otype&FPIN) && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(shp->inpipe[1],F_SETFD,FD_CLOEXEC)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->fdstatus[shp->inpipe[1]] &= ~IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->fork.forkio || otype)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,buff.topfd,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(optimize==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.jobcontrol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTIN,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTOU,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawnpid>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _sh_fork(spawnpid,otype,jobid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(grp>0 && !(otype&FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(tcsetpgrp(job.fd,job.curpgid)<0 && job.curpgid!=spawnpid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = spawnpid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savetype=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPIO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawnpid<0 && (otype&FCOOP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(shp->coutpipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(shp->cpipe[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->cpipe[1] = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->coutpipe = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->exitval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(spawnpid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* !_lib_fork */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPCMD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errorpush(&buff.err,ERROR_SILENT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((otype&FINT) && !sh_isstate(SH_MONITOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGQUIT,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGINT,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin spawnpid = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->com.comio)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_redirect(shp,t->com.comio,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = *argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->com.comset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin scope++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_scope(shp,t->com.comset,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!strchr(path=argv[0],'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((np=nv_search(path,shp->track_tree,0)) && !nv_isattr(np,NV_NOALIAS) && np->nvalue.cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(path_absolute(path,NIL(Pathcomp_t*)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin path = stkptr(shp->stk,PATH_OFFSET);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkfreeze(shp->stk,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp=path_get(path);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(pp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pp->len==1 && *pp->name=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp = pp->next;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!pp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin path = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(sh_isoption(SH_RESTRICTED))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,path);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!path)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin spawnpid = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto fail;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arge = sh_envgen();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(job.jobcontrol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTIN,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTOU,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jobwasset++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_MONITOR) && (job.jobcontrol || (otype&FAMP)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((otype&FAMP) || job.curpgid==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin grp = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin grp = job.curpgid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigreset(0); /* set signals to ignore */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigwasset++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* find first path that has a library component */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(pp=path_get(argv[0]); pp && !pp->lib ; pp=pp->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin spawnpid = path_spawn(path,argv,arge,pp,(grp<<1)|1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawnpid < 0 && errno==ENOEXEC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *devfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd = open(path,O_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[-1] = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"/dev/fd/%d",fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat(devfd=sfstruse(sh.strbuf),&statb)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = devfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!shp->shpath)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->shpath = pathshell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin spawnpid = path_spawn(shp->shpath,&argv[-1],arge,pp,(grp<<1)|1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = argv[-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fail:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawnpid < 0) switch(errno=shp->path_err)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENOENT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOENT),e_found+4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec+4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitset();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff.olist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free_list(buff.olist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jobwasset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTIN,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGTTOU,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sigwasset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigreset(1); /* restore ignored signals */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(scope)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_unscope(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==SH_JMPSCRIPT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setlist(t->com.comset,NV_EXPORT|NV_IDENT|NV_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->com.comio)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iorestore(shp,buff.topfd,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval>SH_JMPCMD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawnpid>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _sh_fork(spawnpid,otype,jobid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(grp==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = spawnpid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(grp>0 && !(otype&FAMP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(tcsetpgrp(job.fd,job.curpgid)<0 && job.curpgid!=spawnpid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = spawnpid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savejobid = *jobid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(otype)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(spawnpid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef _was_lib_fork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define _lib_fork 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef _lib_fork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t fork(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(3),e_notimp,"fork");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* _lib_fork */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_SPAWN */