From 7b0e0776e238293be967922075ef9a8269396076 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sun, 21 Mar 2021 06:33:00 +0000 Subject: [PATCH] cleanup: remove legacy code for systems without fork(2) In 2021, it seems like it's about time to join the 21st century and officially require fork(2). In practice this was already the case as the legacy code was unmaintained and didn't compile. --- src/cmd/ksh93/features/externs | 10 -- src/cmd/ksh93/include/defs.h | 3 + src/cmd/ksh93/include/path.h | 2 +- src/cmd/ksh93/sh/main.c | 2 +- src/cmd/ksh93/sh/path.c | 4 - src/cmd/ksh93/sh/xec.c | 235 +-------------------------------- src/lib/libast/man/spawnveg.3 | 20 +-- 7 files changed, 7 insertions(+), 269 deletions(-) diff --git a/src/cmd/ksh93/features/externs b/src/cmd/ksh93/features/externs index ee0e16463..f503564ff 100644 --- a/src/cmd/ksh93/features/externs +++ b/src/cmd/ksh93/features/externs @@ -31,16 +31,6 @@ tst note{ determining extra bytes per argument for arguments list }end output{ /* Standard includes */ #include - #ifndef _lib_fork - #error requires fork(2) - #endif - #ifndef _lib_execve - #error requires execve(2) - #endif - #ifndef _lib_waitpid - #error requires waitpid(2) - #endif - int main(int argc,char *argv[]) { int extra_bytes = 0, envlen, argmax, i; diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h index b9bd06212..244bfb8f7 100644 --- a/src/cmd/ksh93/include/defs.h +++ b/src/cmd/ksh93/include/defs.h @@ -32,6 +32,9 @@ #if !defined(AST_VERSION) || AST_VERSION < 20111111L #error libast version 20111111 or later is required #endif +#if !_lib_fork +#error In 2021, ksh joined the 21st century and started requiring fork(2). +#endif #if !SHOPT_MULTIBYTE /* * Disable multibyte without need for excessive '#if SHOPT_MULTIBYTE' peprocessor conditionals. diff --git a/src/cmd/ksh93/include/path.h b/src/cmd/ksh93/include/path.h index c7167d431..bc5847531 100644 --- a/src/cmd/ksh93/include/path.h +++ b/src/cmd/ksh93/include/path.h @@ -31,7 +31,7 @@ #include "defs.h" #if !defined(SHOPT_SPAWN) -# if _UWIN || _use_spawnveg || !_lib_fork +# if _UWIN || _use_spawnveg # define SHOPT_SPAWN 1 # endif #endif /* !SHOPT_SPAWN */ diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 91e724cac..1681e98c1 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -53,7 +53,7 @@ /* These routines are referenced by this module */ static void exfile(Shell_t*, Sfio_t*,int); static void chkmail(Shell_t *shp, char*); -#if defined(_lib_fork) && !defined(_NEXT_SOURCE) && !defined(__sun) +#if !defined(_NEXT_SOURCE) && !defined(__sun) static void fixargs(char**,int); #else # define fixargs(a,b) diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c index af38df146..f809e3915 100644 --- a/src/cmd/ksh93/sh/path.c +++ b/src/cmd/ksh93/sh/path.c @@ -1194,7 +1194,6 @@ pid_t path_spawn(Shell_t *shp,const char *opath,register char **argv, char **env errno = ENOEXEC; if(spawn) { -#ifdef _lib_fork if(shp->subshell) return(-1); do @@ -1204,9 +1203,6 @@ pid_t path_spawn(Shell_t *shp,const char *opath,register char **argv, char **env } while(_sh_fork(shp,pid,0,(int*)0) < 0); ((struct checkpt*)shp->jmplist)->mode = SH_JMPEXIT; -#else - return(-1); -#endif } exscript(shp,path,argv,envp); case EACCES: diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index a5e9e50c4..a40adf5c2 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -1617,15 +1617,10 @@ int sh_exec(register const Shnode_t *t, int flags) fifo_save_ppid = shgd->current_pid; #endif #if SHOPT_SPAWN -# ifdef _lib_fork if(com && !job.jobcontrol) parent = sh_ntfork(shp,t,com,&jobid,ntflag); else parent = sh_fork(shp,type,&jobid); -# else - if((parent = sh_ntfork(shp,t,com,&jobid,ntflag))<=0) - break; -# endif /* _lib_fork */ if(parent<0) { /* prevent a file descriptor leak from a 'not found' error */ @@ -3458,85 +3453,6 @@ static void coproc_init(Shell_t *shp, int pipes[]) #if SHOPT_SPAWN - -#if !defined(_lib_fork) - -/* - * create a shell script consisting of t->fork.forktre and execute it - */ -static int run_subshell(Shell_t *shp,const Shnode_t *t,pid_t grp) -{ - static const char prolog[] = "(print $(typeset +A);set; typeset -p; print .sh.dollar=$$;set +o)"; - register int i, fd, trace = sh_isoption(SH_XTRACE); - int pin,pout; - pid_t pid; - char *arglist[3], *envlist[2], devfd[12], *cp; - Sfio_t *sp = sftmp(0); - envlist[0] = "_=" SH_ID; - envlist[1] = 0; - arglist[0] = error_info.id?error_info.id:shp->shname; - if(*arglist[0]=='-') - arglist[0]++; - arglist[1] = devfd; - strncpy(devfd,e_devfdNN,sizeof(devfd)); - arglist[2] = 0; - sfstack(sfstdout,sp); - if(trace) - sh_offoption(SH_XTRACE); - sfwrite(sfstdout,"typeset -A -- ",14); - sh_trap(prolog,0); - nv_scan(shp->fun_tree, print_fun, (void*)0,0, 0); - if(shp->st.dolc>0) - { - /* pass the positional parameters */ - char **argv = shp->st.dolv+1; - sfwrite(sfstdout,"set --",6); - while(*argv) - sfprintf(sfstdout," %s",sh_fmtq(*argv++)); - sfputc(sfstdout,'\n'); - } - pin = (shp->inpipe?shp->inpipe[1]:0); - pout = (shp->outpipe?shp->outpipe[0]:0); - for(i=3; i < 10; i++) - { - if(shp->fdstatus[i]&IOCLEX && i!=pin && i!=pout) - { - sfprintf(sfstdout,"exec %d<&%d\n",i,i); - fcntl(i,F_SETFD,0); - } - } - sfprintf(sfstdout,"LINENO=%d\n",t->fork.forkline); - if(trace) - { - sfwrite(sfstdout,"set -x\n",7); - sh_onoption(SH_XTRACE); - } - sfstack(sfstdout,NIL(Sfio_t*)); - sh_deparse(sp,t->fork.forktre,0); - sfseek(sp,(Sfoff_t)0,SEEK_SET); - fd = sh_dup(sffileno(sp)); - cp = devfd+8; - if(fd>9) - *cp++ = '0' + (fd/10); - *cp++ = '0' + fd%10; - *cp = 0; - sfclose(sp); - sfsync(NIL(Sfio_t*)); - if(!shp->gd->shpath) - shp->gd->shpath = pathshell(); - pid = spawnveg(shp->shpath,arglist,envlist,grp); - close(fd); - for(i=3; i < 10; i++) - { - if(shp->fdstatus[i]&IOCLEX && i!=pin && i!=pout) - fcntl(i,F_SETFD,FD_CLOEXEC); - } - if(pid <=0) - errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,arglist[0]); - return(pid); -} -#endif /* !_lib_fork */ - static void sigreset(Shell_t *shp,int mode) { register char *trap; @@ -3551,7 +3467,7 @@ static void sigreset(Shell_t *shp,int mode) } /* - * A combined fork/exec for systems with slow or non-existent fork() + * A combined fork/exec for systems with slow fork(). * Note: Incompatible with job control. */ static pid_t sh_ntfork(Shell_t *shp,const Shnode_t *t,char *argv[],int *jobid,int flag) @@ -3570,145 +3486,6 @@ static pid_t sh_ntfork(Shell_t *shp,const Shnode_t *t,char *argv[],int *jobid,in otype = savetype; savetype=0; } -# if !defined(_lib_fork) - if(!argv) - { - register Shnode_t *tchild = t->fork.forktre; - int optimize=0; - otype = t->tre.tretyp; - savetype = otype; - spawnpid = 0; -# ifndef _lib_fork - if((tchild->tre.tretyp&COMMSK)==TCOM) - { - Namval_t *np = (Namval_t*)(tchild->com.comnamp); - if(np) - { - path = nv_name(np); - if(!nv_isattr(np,BLT_ENV)) - np=0; - else if(strcmp(path,"echo")==0 || memcmp(path,"print",5)==0) - np=0; - } - else if(!tchild->com.comarg) - optimize=1; - else if(tchild->com.comtyp&COMSCAN) - { - if(tchild->com.comarg->argflag&ARG_RAW) - path = tchild->com.comarg->argval; - else - path = 0; - } - else - path = ((struct dolnod*)tchild->com.comarg)->dolval[ARG_SPARE]; - if(!np && path && !nv_search(path,shp->fun_tree,0)) - optimize=1; - } -# endif - sh_pushcontext(shp,buffp,SH_JMPIO); - jmpval = sigsetjmp(buffp->buff,0); - { - if((otype&FINT) && !sh_isstate(SH_MONITOR)) - { - signal(SIGQUIT,SIG_IGN); - signal(SIGINT,SIG_IGN); - if(!shp->st.ioset) - { - sh_iosave(shp,0,buffp->topfd,(char*)0); - sh_iorenumber(shp,sh_chkopen(e_devnull),0); - } - } - if(otype&FPIN) - { - int fd = shp->inpipe[1]; - sh_iosave(shp,0,buffp->topfd,(char*)0); - sh_iorenumber(shp,shp->inpipe[0],0); - if(fd>=0 && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(fd,F_SETFD,FD_CLOEXEC)>=0) - shp->fdstatus[fd] |= IOCLEX; - } - if(otype&FPOU) - { - sh_iosave(shp,1,buffp->topfd,(char*)0); - sh_iorenumber(shp,sh_dup(shp->outpipe[1]),1); - if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0) - shp->fdstatus[shp->outpipe[0]] |= IOCLEX; - } - - if(t->fork.forkio) - sh_redirect(shp,t->fork.forkio,0); - if(optimize==0) - { -#ifdef SIGTSTP - if(job.jobcontrol) - { - signal(SIGTTIN,SIG_DFL); - signal(SIGTTOU,SIG_DFL); - signal(SIGTSTP,SIG_DFL); - } -#endif /* SIGTSTP */ -#ifdef JOBS - if(sh_isstate(SH_MONITOR) && (job.jobcontrol || (otype&FAMP))) - { - if((otype&FAMP) || job.curpgid==0) - grp = 1; - else - grp = job.curpgid; - } -#endif /* JOBS */ - spawnpid = run_subshell(shp,t,grp); - } - else - { - sh_exec(tchild,SH_NTFORK); - if(jobid) - *jobid = savejobid; - } - } - sh_popcontext(shp,buffp); - if((otype&FINT) && !sh_isstate(SH_MONITOR)) - { - signal(SIGQUIT,sh_fault); - signal(SIGINT,sh_fault); - } - if((otype&FPIN) && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(shp->inpipe[1],F_SETFD,FD_CLOEXEC)>=0) - shp->fdstatus[shp->inpipe[1]] &= ~IOCLEX; - if(t->fork.forkio || otype) - sh_iorestore(shp,buffp->topfd,jmpval); - if(optimize==0) - { -#ifdef SIGTSTP - if(job.jobcontrol) - { - signal(SIGTTIN,SIG_IGN); - signal(SIGTTOU,SIG_IGN); - if(sh_isstate(SH_INTERACTIVE)) - signal(SIGTSTP,SIG_IGN); - else - signal(SIGTSTP,SIG_DFL); - } -#endif /* SIGTSTP */ - if(spawnpid>0) - _sh_fork(shp,spawnpid,otype,jobid); - if(job.jobcontrol && grp>0 && !(otype&FAMP)) - { - while(tcsetpgrp(job.fd,job.curpgid)<0 && job.curpgid!=spawnpid) - job.curpgid = spawnpid; - } - } - savetype=0; - if(jmpval>SH_JMPIO) - siglongjmp(*shp->jmplist,jmpval); - if(spawnpid<0 && (otype&FCOOP)) - { - sh_close(shp->coutpipe); - sh_close(shp->cpipe[1]); - shp->cpipe[1] = -1; - shp->coutpipe = -1; - } - shp->exitval = 0; - return(spawnpid); - } -# endif /* !_lib_fork */ sh_pushcontext(shp,buffp,SH_JMPCMD); errorpush(&buffp->err,ERROR_SILENT); job_lock(); /* errormsg will unlock */ @@ -3874,14 +3651,4 @@ static pid_t sh_ntfork(Shell_t *shp,const Shnode_t *t,char *argv[],int *jobid,in return(spawnpid); } -# ifdef _was_lib_fork -# define _lib_fork 1 -# endif -# ifndef _lib_fork - pid_t fork(void) - { - errormsg(SH_DICT,ERROR_exit(3),e_notimp,"fork"); - return(-1); - } -# endif /* _lib_fork */ #endif /* SHOPT_SPAWN */ diff --git a/src/lib/libast/man/spawnveg.3 b/src/lib/libast/man/spawnveg.3 index 539e17d38..859af1b63 100644 --- a/src/lib/libast/man/spawnveg.3 +++ b/src/lib/libast/man/spawnveg.3 @@ -64,7 +64,7 @@ controls the new process group and session: .TP .L <0 The new process becomes a session leader. -is called in the child context. +It is called in the child context. .TP .L 0 The new process is in the callers process group. @@ -75,23 +75,5 @@ The new process becomes a process group leader. .L >1 The new process joins the process group .IR pgid . -.SH COMMENTS -It is possible to code all process creation (except for -.IR vfork (2) -hack like in -.IR csh (1)) -using -.LR spawnveg . -The -.IR proc (3) -routines and -.IR ksh (1) -do this on systems that don't support -.IR fork (2). -This makes porting to NT and Windows a snap: a simple -.IR iffe (1) -probe provides a -.L spawnveg -implementation using the NT or Windows process primitives. .SH "SEE ALSO" fork(2), exec(2), setpgid(2), setsid(2), spawnve(2)