1*35173Smarc /*
2*35173Smarc
3*35173Smarc * Copyright (c) 1984, 1985, 1986 AT&T
4*35173Smarc * All Rights Reserved
5*35173Smarc
6*35173Smarc * THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35173Smarc * CODE OF AT&T.
8*35173Smarc * The copyright notice above does not
9*35173Smarc * evidence any actual or intended
10*35173Smarc * publication of such source code.
11*35173Smarc
12*35173Smarc */
13*35173Smarc /* @(#)vfork.c 1.1 */
14*35173Smarc /*
15*35173Smarc * UNIX shell
16*35173Smarc *
17*35173Smarc * S. R. Bourne
18*35173Smarc * Rewritten by David Korn
19*35173Smarc * Bell Telephone Laboratories
20*35173Smarc *
21*35173Smarc */
22*35173Smarc
23*35173Smarc #include "flags.h"
24*35173Smarc #include "defs.h"
25*35173Smarc #include "sym.h"
26*35173Smarc #include "name.h"
27*35173Smarc #include "io.h"
28*35173Smarc #include "stak.h"
29*35173Smarc #include "jobs.h"
30*35173Smarc #include "builtins.h"
31*35173Smarc #include "brkincr.h"
32*35173Smarc #include "mode.h"
33*35173Smarc
34*35173Smarc /*
35*35173Smarc * This module is provided to allow the Shell to work with vfork instead
36*35173Smarc * of fork. With vfork the data area is shared by parent and child.
37*35173Smarc * Save state variables at fork and make Shell variables copy on write.
38*35173Smarc * Restore everything to previous state when fork_exit is called and
39*35173Smarc * terminate process.
40*35173Smarc */
41*35173Smarc
42*35173Smarc /* The following structure contains the variables that must be saved */
43*35173Smarc struct f_save
44*35173Smarc {
45*35173Smarc struct f_save *f_save_fork;
46*35173Smarc DOLPTR f_savearg;
47*35173Smarc STKPTR f_staksave;
48*35173Smarc struct State f_st;
49*35173Smarc char f_trapflg[MAXTRAP+1];
50*35173Smarc char *f_trapcom[MAXTRAP+1];
51*35173Smarc FILE f_save_iob[FCIO+1];
52*35173Smarc struct jobs f_jobstat;
53*35173Smarc };
54*35173Smarc
55*35173Smarc /* The following routines are defined by this module */
56*35173Smarc int vfork_check();
57*35173Smarc void vfork_restore();
58*35173Smarc int vfork_save();
59*35173Smarc
60*35173Smarc /* The following external routines are referenced by this module */
61*35173Smarc extern DOLPTR arg_use();
62*35173Smarc extern void arg_free();
63*35173Smarc extern NAMPTR checkfor();
64*35173Smarc extern unsigned chkid();
65*35173Smarc extern void free();
66*35173Smarc extern char *malloc();
67*35173Smarc extern struct Amemory *namep;
68*35173Smarc extern char *simple();
69*35173Smarc extern char trapflg[];
70*35173Smarc extern char *valup();
71*35173Smarc
72*35173Smarc static struct f_save *save_fork; /* most recently saved data */
73*35173Smarc
74*35173Smarc /*
75*35173Smarc * Save state on fork
76*35173Smarc */
77*35173Smarc
vfork_save()78*35173Smarc int vfork_save()
79*35173Smarc {
80*35173Smarc register struct f_save *fp = (struct f_save*)malloc(sizeof(struct f_save));
81*35173Smarc if(fp==NULL)
82*35173Smarc return(-1);
83*35173Smarc locstak();
84*35173Smarc fp->f_save_fork = save_fork;
85*35173Smarc save_fork = fp;
86*35173Smarc fp->f_staksave = savstak();
87*35173Smarc fp->f_st = st;
88*35173Smarc fp->f_jobstat = jobstat;
89*35173Smarc jobstat.p_pwlist = 0;
90*35173Smarc fp->f_savearg = arg_use();
91*35173Smarc bcopy(trapflg,fp->f_trapflg,MAXTRAP+1);
92*35173Smarc bcopy((char*)trapcom,(char*)fp->f_trapcom,(MAXTRAP+1)*sizeof(char*));
93*35173Smarc #ifdef _N_STATIC_IOBS
94*35173Smarc bcopy((char*)_iob,(char*)fp->f_save_iob,(_N_STATIC_IOBS)*sizeof(FILE));
95*35173Smarc bcopy((char*)_myiob,(char*)(fp->f_save_iob+_N_STATIC_IOBS),
96*35173Smarc (FCIO+1-_N_STATIC_IOBS)*sizeof(FILE));
97*35173Smarc #else
98*35173Smarc bcopy((char*)_iob,(char*)fp->f_save_iob,(FCIO+1)*sizeof(FILE));
99*35173Smarc #endif /* _N_STATIC_IOBS */
100*35173Smarc states |= VFORKED;
101*35173Smarc return(0);
102*35173Smarc }
103*35173Smarc
104*35173Smarc /*
105*35173Smarc * Restore state and exit
106*35173Smarc */
107*35173Smarc
vfork_restore()108*35173Smarc void vfork_restore()
109*35173Smarc {
110*35173Smarc register struct f_save *fp = save_fork;
111*35173Smarc if((states&VFORKED)==0)
112*35173Smarc return;
113*35173Smarc #ifdef _N_STATIC_IOBS
114*35173Smarc bcopy((char*)fp->f_save_iob,(char*)_iob,(_N_STATIC_IOBS)*sizeof(FILE));
115*35173Smarc bcopy((char*)(fp->f_save_iob+_N_STATIC_IOBS),(char*)_myiob,
116*35173Smarc (FCIO+1-_N_STATIC_IOBS)*sizeof(FILE));
117*35173Smarc #else
118*35173Smarc bcopy((char*)fp->f_save_iob,(char*)_iob,(FCIO+1)*sizeof(FILE));
119*35173Smarc #endif /* _N_STATIC_IOBS */
120*35173Smarc bcopy(fp->f_trapflg,trapflg,MAXTRAP+1);
121*35173Smarc bcopy((char*)fp->f_trapcom,(char*)trapcom,(MAXTRAP+1)*sizeof(char*));
122*35173Smarc st = fp->f_st;
123*35173Smarc jobstat = fp->f_jobstat;
124*35173Smarc arg_free(fp->f_savearg,0);
125*35173Smarc save_fork = fp->f_save_fork;
126*35173Smarc free(fp);
127*35173Smarc tdystak(fp->f_staksave);
128*35173Smarc }
129*35173Smarc
130*35173Smarc
131*35173Smarc /*
132*35173Smarc * Get the interpreter name given a script file
133*35173Smarc * The first line must be of the form #! <iname>.
134*35173Smarc * Returns 1 if <iname> is found, 0 otherwise
135*35173Smarc */
get_shell(name,iname)136*35173Smarc int get_shell(name,iname)
137*35173Smarc char *name;
138*35173Smarc char *iname;
139*35173Smarc {
140*35173Smarc register int c;
141*35173Smarc register int state = 0;
142*35173Smarc register int fd;
143*35173Smarc int n;
144*35173Smarc char *cp;
145*35173Smarc int rval = 0;
146*35173Smarc char buffer[256];
147*35173Smarc cp = valup(SHELLNOD);
148*35173Smarc /* don't use csh */
149*35173Smarc if(strcmp(simple(cp),"csh")==0)
150*35173Smarc cp = 0;
151*35173Smarc strcpy(iname,cp?cp:"/bin/sh");
152*35173Smarc if((fd=open(name,0))<0)
153*35173Smarc return(-1);
154*35173Smarc n = read(fd,buffer,sizeof(buffer));
155*35173Smarc cp = buffer;
156*35173Smarc while(n-- > 0)
157*35173Smarc {
158*35173Smarc c = *cp++;
159*35173Smarc switch(state)
160*35173Smarc {
161*35173Smarc case 0:
162*35173Smarc if(c!='#')
163*35173Smarc goto out;
164*35173Smarc break;
165*35173Smarc
166*35173Smarc case 1:
167*35173Smarc if(c!='!')
168*35173Smarc goto out;
169*35173Smarc break;
170*35173Smarc
171*35173Smarc case 2:
172*35173Smarc if(c==' ' || c =='\t')
173*35173Smarc continue;
174*35173Smarc default:
175*35173Smarc if(c=='\n')
176*35173Smarc {
177*35173Smarc *iname = 0;
178*35173Smarc rval = 1;
179*35173Smarc goto out;
180*35173Smarc }
181*35173Smarc *iname++ = c;
182*35173Smarc }
183*35173Smarc state++;
184*35173Smarc }
185*35173Smarc out:
186*35173Smarc close(fd);
187*35173Smarc return(rval);
188*35173Smarc }
189*35173Smarc
190*35173Smarc /*
191*35173Smarc * returns non-zero if process should vfork, 0 otherwise
192*35173Smarc * we do not vfork for functions and built-ins in the background
193*35173Smarc */
vfork_check(t)194*35173Smarc int vfork_check(t)
195*35173Smarc TREPTR t;
196*35173Smarc {
197*35173Smarc register COMPTR tf;
198*35173Smarc register ARGPTR arg;
199*35173Smarc register char *arg0 = NIL;
200*35173Smarc NAMPTR np;
201*35173Smarc int bltno;
202*35173Smarc /* simple command */
203*35173Smarc if((t->tretyp&COMMSK)==TCOM)
204*35173Smarc return(1);
205*35173Smarc tf = (COMPTR)(((FORKPTR)t)->forktre);
206*35173Smarc if((tf->comtyp&COMMSK)!=TCOM)
207*35173Smarc return(0);
208*35173Smarc /* background command */
209*35173Smarc arg = tf->comarg;
210*35173Smarc bltno = tf->comtyp>>(COMBITS+1);
211*35173Smarc /* can't vfork assignments or most built-ins */
212*35173Smarc if(arg==0 || bltno > SYSLOGIN)
213*35173Smarc return(0);
214*35173Smarc if(tf->comtyp&COMSCAN)
215*35173Smarc {
216*35173Smarc if(arg->argflag&A_RAW)
217*35173Smarc arg0 = arg->argval;
218*35173Smarc }
219*35173Smarc else
220*35173Smarc arg0 = *(((DOLPTR)arg)->dolarg+1);
221*35173Smarc /* no vfork if not sure */
222*35173Smarc if(arg0==NIL)
223*35173Smarc return(0);
224*35173Smarc /* eliminate functions */
225*35173Smarc if(chkid(arg0) && (np=checkfor(arg0,prnames))&& np->value.namval.ip)
226*35173Smarc return(0);
227*35173Smarc /* command substitution with i/o redirection use fork */
228*35173Smarc if((t->tretyp&FCOMSUB) && t->treio==(IOPTR)0)
229*35173Smarc return(0);
230*35173Smarc return(2);
231*35173Smarc }
232*35173Smarc
233*35173Smarc #ifndef BSD_4_2
234*35173Smarc /*
235*35173Smarc * copy <n> bytes from <sp> to <dp>
236*35173Smarc */
237*35173Smarc
bcopy(sp,dp,n)238*35173Smarc int bcopy(sp,dp,n)
239*35173Smarc register char *sp, *dp;
240*35173Smarc register int n;
241*35173Smarc {
242*35173Smarc while(n-- >0)
243*35173Smarc *dp++ = *sp++;
244*35173Smarc }
245*35173Smarc #endif BSD_4_2
246