Skip to content

Commit

Permalink
cleanup: remove legacy code for systems without fork(2)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
McDutchie committed Mar 21, 2021
1 parent 38f2b94 commit 7b0e077
Show file tree
Hide file tree
Showing 7 changed files with 7 additions and 269 deletions.
10 changes: 0 additions & 10 deletions src/cmd/ksh93/features/externs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,6 @@ tst note{ determining extra bytes per argument for arguments list }end output{
/* Standard includes */
#include <errno.h>

#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;
Expand Down
3 changes: 3 additions & 0 deletions src/cmd/ksh93/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/sh/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 0 additions & 4 deletions src/cmd/ksh93/sh/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
235 changes: 1 addition & 234 deletions src/cmd/ksh93/sh/xec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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 */
Expand Down Expand Up @@ -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 */
20 changes: 1 addition & 19 deletions src/lib/libast/man/spawnveg.3
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)

0 comments on commit 7b0e077

Please sign in to comment.