1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
43e14f97fSRoger A. Faulkner * Copyright (c) 1982-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * David Korn <dgk@research.att.com> *
18da2e3ebdSchin * *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin * exec [arg...]
23da2e3ebdSchin * eval [arg...]
24da2e3ebdSchin * jobs [-lnp] [job...]
25da2e3ebdSchin * login [arg...]
26da2e3ebdSchin * let expr...
27da2e3ebdSchin * . file [arg...]
28da2e3ebdSchin * :, true, false
29da2e3ebdSchin * vpath [top] [base]
30da2e3ebdSchin * vmap [top] [base]
31da2e3ebdSchin * wait [job...]
32da2e3ebdSchin * shift [n]
33da2e3ebdSchin *
34da2e3ebdSchin * David Korn
35da2e3ebdSchin * AT&T Labs
36da2e3ebdSchin *
37da2e3ebdSchin */
38da2e3ebdSchin
39da2e3ebdSchin #include "defs.h"
40da2e3ebdSchin #include "variables.h"
41da2e3ebdSchin #include "shnodes.h"
42da2e3ebdSchin #include "path.h"
43da2e3ebdSchin #include "io.h"
44da2e3ebdSchin #include "name.h"
45da2e3ebdSchin #include "history.h"
46da2e3ebdSchin #include "builtins.h"
47da2e3ebdSchin #include "jobs.h"
48da2e3ebdSchin
49da2e3ebdSchin #define DOTMAX MAXDEPTH /* maximum level of . nesting */
50da2e3ebdSchin
51da2e3ebdSchin static void noexport(Namval_t*,void*);
52da2e3ebdSchin
53da2e3ebdSchin struct login
54da2e3ebdSchin {
55da2e3ebdSchin Shell_t *sh;
56da2e3ebdSchin int clear;
57da2e3ebdSchin char *arg0;
58da2e3ebdSchin };
59da2e3ebdSchin
b_exec(int argc,char * argv[],void * extra)60*8ddde5afSToomas Soome int b_exec(int argc,char *argv[], void *extra)
61*8ddde5afSToomas Soome {
62da2e3ebdSchin struct login logdata;
63da2e3ebdSchin register int n;
64da2e3ebdSchin logdata.clear = 0;
65da2e3ebdSchin logdata.arg0 = 0;
66da2e3ebdSchin logdata.sh = ((Shbltin_t*)extra)->shp;
677c2fbfb3SApril Chin logdata.sh->st.ioset = 0;
68da2e3ebdSchin while (n = optget(argv, sh_optexec)) switch (n)
69da2e3ebdSchin {
70da2e3ebdSchin case 'a':
71da2e3ebdSchin logdata.arg0 = opt_info.arg;
72da2e3ebdSchin argc = 0;
73da2e3ebdSchin break;
74da2e3ebdSchin case 'c':
75da2e3ebdSchin logdata.clear=1;
76da2e3ebdSchin break;
77da2e3ebdSchin case ':':
78da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
79da2e3ebdSchin break;
80da2e3ebdSchin case '?':
81da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
82da2e3ebdSchin return(2);
83da2e3ebdSchin }
84da2e3ebdSchin argv += opt_info.index;
85da2e3ebdSchin if(error_info.errors)
86da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
87da2e3ebdSchin if(*argv)
88da2e3ebdSchin B_login(0,argv,(void*)&logdata);
89da2e3ebdSchin return(0);
90da2e3ebdSchin }
91da2e3ebdSchin
noexport(register Namval_t * np,void * data)92da2e3ebdSchin static void noexport(register Namval_t* np, void *data)
93da2e3ebdSchin {
94da2e3ebdSchin NOT_USED(data);
95da2e3ebdSchin nv_offattr(np,NV_EXPORT);
96da2e3ebdSchin }
97da2e3ebdSchin
B_login(int argc,char * argv[],void * extra)98da2e3ebdSchin int B_login(int argc,char *argv[],void *extra)
99da2e3ebdSchin {
100da2e3ebdSchin struct checkpt *pp;
101da2e3ebdSchin register struct login *logp=0;
102da2e3ebdSchin register Shell_t *shp;
103da2e3ebdSchin const char *pname;
104da2e3ebdSchin if(argc)
105da2e3ebdSchin shp = ((Shbltin_t*)extra)->shp;
1067c2fbfb3SApril Chin else
107da2e3ebdSchin {
108da2e3ebdSchin logp = (struct login*)extra;
109da2e3ebdSchin shp = logp->sh;
110da2e3ebdSchin }
111da2e3ebdSchin pp = (struct checkpt*)shp->jmplist;
112da2e3ebdSchin if(sh_isoption(SH_RESTRICTED))
113da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_restricted,argv[0]);
114da2e3ebdSchin else
115da2e3ebdSchin {
116da2e3ebdSchin register struct argnod *arg=shp->envlist;
117da2e3ebdSchin register Namval_t* np;
118da2e3ebdSchin register char *cp;
119da2e3ebdSchin if(shp->subshell && !shp->subshare)
12034f9b3eeSRoland Mainz sh_subfork();
121da2e3ebdSchin if(logp && logp->clear)
122da2e3ebdSchin {
123da2e3ebdSchin #ifdef _ENV_H
124da2e3ebdSchin env_close(shp->env);
125da2e3ebdSchin shp->env = env_open((char**)0,3);
126da2e3ebdSchin #else
127da2e3ebdSchin nv_scan(shp->var_tree,noexport,0,NV_EXPORT,NV_EXPORT);
128da2e3ebdSchin #endif
129da2e3ebdSchin }
130da2e3ebdSchin while(arg)
131da2e3ebdSchin {
132da2e3ebdSchin if((cp=strchr(arg->argval,'=')) &&
133da2e3ebdSchin (*cp=0,np=nv_search(arg->argval,shp->var_tree,0)))
134da2e3ebdSchin {
135da2e3ebdSchin nv_onattr(np,NV_EXPORT);
136da2e3ebdSchin sh_envput(shp->env,np);
137da2e3ebdSchin }
138da2e3ebdSchin if(cp)
139da2e3ebdSchin *cp = '=';
140da2e3ebdSchin arg=arg->argnxt.ap;
141da2e3ebdSchin }
142da2e3ebdSchin pname = argv[0];
143da2e3ebdSchin if(logp && logp->arg0)
144da2e3ebdSchin argv[0] = logp->arg0;
145da2e3ebdSchin #ifdef JOBS
146da2e3ebdSchin if(job_close(shp) < 0)
1477c2fbfb3SApril Chin return(1);
148da2e3ebdSchin #endif /* JOBS */
149da2e3ebdSchin /* force bad exec to terminate shell */
150da2e3ebdSchin pp->mode = SH_JMPEXIT;
151da2e3ebdSchin sh_sigreset(2);
152da2e3ebdSchin sh_freeup(shp);
1537c2fbfb3SApril Chin path_exec(pname,argv,NIL(struct argnod*));
154da2e3ebdSchin sh_done(shp,0);
1557c2fbfb3SApril Chin }
156da2e3ebdSchin return(1);
157da2e3ebdSchin }
158da2e3ebdSchin
b_let(int argc,char * argv[],void * extra)159da2e3ebdSchin int b_let(int argc,char *argv[],void *extra)
160da2e3ebdSchin {
161da2e3ebdSchin register int r;
162da2e3ebdSchin register char *arg;
163da2e3ebdSchin NOT_USED(argc);
164da2e3ebdSchin NOT_USED(extra);
165da2e3ebdSchin while (r = optget(argv,sh_optlet)) switch (r)
166da2e3ebdSchin {
167da2e3ebdSchin case ':':
168da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
169da2e3ebdSchin break;
170da2e3ebdSchin case '?':
171da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
172da2e3ebdSchin break;
173da2e3ebdSchin }
174da2e3ebdSchin argv += opt_info.index;
175da2e3ebdSchin if(error_info.errors || !*argv)
176da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
177da2e3ebdSchin while(arg= *argv++)
178da2e3ebdSchin r = !sh_arith(arg);
179da2e3ebdSchin return(r);
180da2e3ebdSchin }
181da2e3ebdSchin
b_eval(int argc,char * argv[],void * extra)182da2e3ebdSchin int b_eval(int argc,char *argv[], void *extra)
183da2e3ebdSchin {
184da2e3ebdSchin register int r;
185da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
1867c2fbfb3SApril Chin NOT_USED(argc);
187da2e3ebdSchin while (r = optget(argv,sh_opteval)) switch (r)
188da2e3ebdSchin {
189da2e3ebdSchin case ':':
190da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
191da2e3ebdSchin break;
192da2e3ebdSchin case '?':
193da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
194da2e3ebdSchin return(2);
195da2e3ebdSchin }
196da2e3ebdSchin if(error_info.errors)
197da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
198da2e3ebdSchin argv += opt_info.index;
199da2e3ebdSchin if(*argv && **argv)
200da2e3ebdSchin {
201da2e3ebdSchin sh_offstate(SH_MONITOR);
202da2e3ebdSchin sh_eval(sh_sfeval(argv),0);
203da2e3ebdSchin }
204da2e3ebdSchin return(shp->exitval);
205da2e3ebdSchin }
206da2e3ebdSchin
b_dot_cmd(register int n,char * argv[],void * extra)207da2e3ebdSchin int b_dot_cmd(register int n,char *argv[],void* extra)
208da2e3ebdSchin {
209da2e3ebdSchin register char *script;
210da2e3ebdSchin register Namval_t *np;
211da2e3ebdSchin register int jmpval;
212da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
2137c2fbfb3SApril Chin struct sh_scoped savst, *prevscope = shp->st.self;
214da2e3ebdSchin char *filename=0;
215da2e3ebdSchin int fd;
216da2e3ebdSchin struct dolnod *argsave=0, *saveargfor;
217da2e3ebdSchin struct checkpt buff;
218da2e3ebdSchin Sfio_t *iop=0;
219da2e3ebdSchin short level;
2207c2fbfb3SApril Chin while (n = optget(argv,sh_optdot)) switch (n)
221da2e3ebdSchin {
222da2e3ebdSchin case ':':
223da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
224da2e3ebdSchin break;
225da2e3ebdSchin case '?':
226da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
227da2e3ebdSchin return(2);
228da2e3ebdSchin }
229da2e3ebdSchin argv += opt_info.index;
230da2e3ebdSchin script = *argv;
231da2e3ebdSchin if(error_info.errors || !script)
232da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
233da2e3ebdSchin if(shp->dot_depth+1 > DOTMAX)
2347c2fbfb3SApril Chin errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
235da2e3ebdSchin if(!(np=shp->posix_fun))
236da2e3ebdSchin {
237da2e3ebdSchin /* check for KornShell style function first */
238da2e3ebdSchin np = nv_search(script,shp->fun_tree,0);
239da2e3ebdSchin if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX))
240da2e3ebdSchin {
241da2e3ebdSchin if(!np->nvalue.ip)
242da2e3ebdSchin {
243da2e3ebdSchin path_search(script,NIL(Pathcomp_t**),0);
2447c2fbfb3SApril Chin if(np->nvalue.ip)
245da2e3ebdSchin {
246da2e3ebdSchin if(nv_isattr(np,NV_FPOSIX))
247da2e3ebdSchin np = 0;
248da2e3ebdSchin }
249da2e3ebdSchin else
250da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_found,script);
251da2e3ebdSchin }
252da2e3ebdSchin }
253da2e3ebdSchin else
254da2e3ebdSchin np = 0;
255da2e3ebdSchin if(!np)
256da2e3ebdSchin {
257da2e3ebdSchin if((fd=path_open(script,path_get(script))) < 0)
258da2e3ebdSchin errormsg(SH_DICT,ERROR_system(1),e_open,script);
259da2e3ebdSchin filename = path_fullname(stkptr(shp->stk,PATH_OFFSET));
2607c2fbfb3SApril Chin }
261da2e3ebdSchin }
262da2e3ebdSchin *prevscope = shp->st;
263da2e3ebdSchin shp->st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
2647c2fbfb3SApril Chin shp->st.var_local = shp->st.save_tree = shp->var_tree;
2657c2fbfb3SApril Chin if(filename)
266da2e3ebdSchin {
2677c2fbfb3SApril Chin shp->st.filename = filename;
268da2e3ebdSchin shp->st.lineno = 1;
2697c2fbfb3SApril Chin }
2707c2fbfb3SApril Chin level = shp->fn_depth+shp->dot_depth+1;
2717c2fbfb3SApril Chin nv_putval(SH_LEVELNOD,(char*)&level,NV_INT16);
2727c2fbfb3SApril Chin shp->st.prevst = prevscope;
273da2e3ebdSchin shp->st.self = &savst;
274da2e3ebdSchin shp->topscope = (Shscope_t*)shp->st.self;
275da2e3ebdSchin prevscope->save_tree = shp->var_tree;
276da2e3ebdSchin shp->st.cmdname = argv[0];
277da2e3ebdSchin if(np)
278da2e3ebdSchin shp->st.filename = np->nvalue.rp->fname;
279da2e3ebdSchin nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
280da2e3ebdSchin shp->posix_fun = 0;
281da2e3ebdSchin if(np || argv[1])
282da2e3ebdSchin argsave = sh_argnew(shp,argv,&saveargfor);
2837c2fbfb3SApril Chin sh_pushcontext(&buff,SH_JMPDOT);
284da2e3ebdSchin jmpval = sigsetjmp(buff.buff,0);
285da2e3ebdSchin if(jmpval == 0)
286da2e3ebdSchin {
287da2e3ebdSchin shp->dot_depth++;
2887c2fbfb3SApril Chin if(np)
289da2e3ebdSchin sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
290da2e3ebdSchin else
291da2e3ebdSchin {
292da2e3ebdSchin char buff[IOBSIZE+1];
293da2e3ebdSchin iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fd,SF_READ);
294da2e3ebdSchin sh_eval(iop,0);
295da2e3ebdSchin }
296da2e3ebdSchin }
297da2e3ebdSchin sh_popcontext(&buff);
298da2e3ebdSchin if(!np)
299da2e3ebdSchin free((void*)shp->st.filename);
300da2e3ebdSchin shp->dot_depth--;
301da2e3ebdSchin if((np || argv[1]) && jmpval!=SH_JMPSCRIPT)
302da2e3ebdSchin sh_argreset(shp,argsave,saveargfor);
3037c2fbfb3SApril Chin else
304da2e3ebdSchin {
305da2e3ebdSchin prevscope->dolc = shp->st.dolc;
306da2e3ebdSchin prevscope->dolv = shp->st.dolv;
307da2e3ebdSchin }
308da2e3ebdSchin if (shp->st.self != &savst)
309da2e3ebdSchin *shp->st.self = shp->st;
310da2e3ebdSchin /* only restore the top Shscope_t portion for posix functions */
311da2e3ebdSchin memcpy((void*)&shp->st, (void*)prevscope, sizeof(Shscope_t));
312da2e3ebdSchin shp->topscope = (Shscope_t*)prevscope;
313da2e3ebdSchin nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
314da2e3ebdSchin if(shp->exitval > SH_EXITSIG)
315da2e3ebdSchin sh_fault(shp->exitval&SH_EXITMASK);
316da2e3ebdSchin if(jmpval && jmpval!=SH_JMPFUN)
317da2e3ebdSchin siglongjmp(*shp->jmplist,jmpval);
318da2e3ebdSchin return(shp->exitval);
319da2e3ebdSchin }
320da2e3ebdSchin
321da2e3ebdSchin /*
322da2e3ebdSchin * null, true command
323da2e3ebdSchin */
b_true(int argc,register char * argv[],void * extra)324da2e3ebdSchin int b_true(int argc,register char *argv[],void *extra)
325da2e3ebdSchin {
326da2e3ebdSchin NOT_USED(argc);
327da2e3ebdSchin NOT_USED(argv[0]);
328da2e3ebdSchin NOT_USED(extra);
329da2e3ebdSchin return(0);
330da2e3ebdSchin }
331da2e3ebdSchin
332da2e3ebdSchin /*
333da2e3ebdSchin * false command
334da2e3ebdSchin */
b_false(int argc,register char * argv[],void * extra)335da2e3ebdSchin int b_false(int argc,register char *argv[], void *extra)
336da2e3ebdSchin {
337da2e3ebdSchin NOT_USED(argc);
338da2e3ebdSchin NOT_USED(argv[0]);
339da2e3ebdSchin NOT_USED(extra);
340da2e3ebdSchin return(1);
341da2e3ebdSchin }
342da2e3ebdSchin
b_shift(register int n,register char * argv[],void * extra)343da2e3ebdSchin int b_shift(register int n, register char *argv[], void *extra)
344da2e3ebdSchin {
345da2e3ebdSchin register char *arg;
346da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
3477c2fbfb3SApril Chin while((n = optget(argv,sh_optshift))) switch(n)
348da2e3ebdSchin {
349da2e3ebdSchin case ':':
350da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
351da2e3ebdSchin break;
352da2e3ebdSchin case '?':
353da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
354da2e3ebdSchin return(2);
355da2e3ebdSchin }
356da2e3ebdSchin if(error_info.errors)
357da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
358da2e3ebdSchin argv += opt_info.index;
359da2e3ebdSchin n = ((arg= *argv)?(int)sh_arith(arg):1);
360da2e3ebdSchin if(n<0 || shp->st.dolc<n)
361da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_number,arg);
362da2e3ebdSchin else
363da2e3ebdSchin {
364da2e3ebdSchin shp->st.dolv += n;
365da2e3ebdSchin shp->st.dolc -= n;
366da2e3ebdSchin }
367da2e3ebdSchin return(0);
368da2e3ebdSchin }
369da2e3ebdSchin
b_wait(int n,register char * argv[],void * extra)370da2e3ebdSchin int b_wait(int n,register char *argv[],void *extra)
371da2e3ebdSchin {
372da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
3737c2fbfb3SApril Chin while((n = optget(argv,sh_optwait))) switch(n)
374da2e3ebdSchin {
375da2e3ebdSchin case ':':
376da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
377da2e3ebdSchin break;
378da2e3ebdSchin case '?':
379da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
380da2e3ebdSchin break;
381da2e3ebdSchin }
382da2e3ebdSchin if(error_info.errors)
383da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
384da2e3ebdSchin argv += opt_info.index;
385da2e3ebdSchin job_bwait(argv);
386da2e3ebdSchin return(shp->exitval);
387da2e3ebdSchin }
388da2e3ebdSchin
389da2e3ebdSchin #ifdef JOBS
390da2e3ebdSchin # if 0
391da2e3ebdSchin /* for the dictionary generator */
392da2e3ebdSchin int b_fg(int n,char *argv[],void *extra){}
393da2e3ebdSchin int b_disown(int n,char *argv[],void *extra){}
394da2e3ebdSchin # endif
b_bg(register int n,register char * argv[],void * extra)395da2e3ebdSchin int b_bg(register int n,register char *argv[],void *extra)
396da2e3ebdSchin {
397da2e3ebdSchin register int flag = **argv;
398da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
3997c2fbfb3SApril Chin register const char *optstr = sh_optbg;
400da2e3ebdSchin if(*argv[0]=='f')
401da2e3ebdSchin optstr = sh_optfg;
402da2e3ebdSchin else if(*argv[0]=='d')
403da2e3ebdSchin optstr = sh_optdisown;
404da2e3ebdSchin while((n = optget(argv,optstr))) switch(n)
405da2e3ebdSchin {
406da2e3ebdSchin case ':':
407da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
408da2e3ebdSchin break;
409da2e3ebdSchin case '?':
410da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
411da2e3ebdSchin break;
412da2e3ebdSchin }
413da2e3ebdSchin if(error_info.errors)
414da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
415da2e3ebdSchin argv += opt_info.index;
416da2e3ebdSchin if(!sh_isoption(SH_MONITOR) || !job.jobcontrol)
417da2e3ebdSchin {
418da2e3ebdSchin if(sh_isstate(SH_INTERACTIVE))
419da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_no_jctl);
420da2e3ebdSchin return(1);
421da2e3ebdSchin }
422da2e3ebdSchin if(flag=='d' && *argv==0)
423da2e3ebdSchin argv = (char**)0;
424da2e3ebdSchin if(job_walk(sfstdout,job_switch,flag,argv))
425da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_no_job);
426da2e3ebdSchin return(shp->exitval);
427da2e3ebdSchin }
428da2e3ebdSchin
b_jobs(register int n,char * argv[],void * extra)429da2e3ebdSchin int b_jobs(register int n,char *argv[],void *extra)
430da2e3ebdSchin {
431da2e3ebdSchin register int flag = 0;
432da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
4337c2fbfb3SApril Chin while((n = optget(argv,sh_optjobs))) switch(n)
434da2e3ebdSchin {
435da2e3ebdSchin case 'l':
436da2e3ebdSchin flag = JOB_LFLAG;
437da2e3ebdSchin break;
438da2e3ebdSchin case 'n':
439da2e3ebdSchin flag = JOB_NFLAG;
440da2e3ebdSchin break;
441da2e3ebdSchin case 'p':
442da2e3ebdSchin flag = JOB_PFLAG;
443da2e3ebdSchin break;
444da2e3ebdSchin case ':':
445da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
446da2e3ebdSchin break;
447da2e3ebdSchin case '?':
448da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
449da2e3ebdSchin break;
450da2e3ebdSchin }
451da2e3ebdSchin argv += opt_info.index;
452da2e3ebdSchin if(error_info.errors)
453da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
454da2e3ebdSchin if(*argv==0)
455da2e3ebdSchin argv = (char**)0;
456da2e3ebdSchin if(job_walk(sfstdout,job_list,flag,argv))
457da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_no_job);
458da2e3ebdSchin job_wait((pid_t)0);
459da2e3ebdSchin return(shp->exitval);
460da2e3ebdSchin }
461da2e3ebdSchin #endif
462da2e3ebdSchin
463da2e3ebdSchin #ifdef _cmd_universe
464da2e3ebdSchin /*
465da2e3ebdSchin * There are several universe styles that are masked by the getuniv(),
466da2e3ebdSchin * setuniv() calls.
467da2e3ebdSchin */
b_universe(int argc,char * argv[],void * extra)468da2e3ebdSchin int b_universe(int argc, char *argv[],void *extra)
469da2e3ebdSchin {
470da2e3ebdSchin register char *arg;
471da2e3ebdSchin register int n;
472da2e3ebdSchin NOT_USED(extra);
473da2e3ebdSchin while((n = optget(argv,sh_optuniverse))) switch(n)
474da2e3ebdSchin {
475da2e3ebdSchin case ':':
476da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
477da2e3ebdSchin break;
478da2e3ebdSchin case '?':
479da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
480da2e3ebdSchin break;
481da2e3ebdSchin }
482da2e3ebdSchin argv += opt_info.index;
483da2e3ebdSchin argc -= opt_info.index;
484da2e3ebdSchin if(error_info.errors || argc>1)
485da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
486da2e3ebdSchin if(arg = argv[0])
487da2e3ebdSchin {
488da2e3ebdSchin if(!astconf("UNIVERSE",0,arg))
489da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1), e_badname,arg);
490da2e3ebdSchin }
491da2e3ebdSchin else
492da2e3ebdSchin {
493da2e3ebdSchin if(!(arg=astconf("UNIVERSE",0,0)))
494da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_nouniverse);
495da2e3ebdSchin else
496da2e3ebdSchin sfputr(sfstdout,arg,'\n');
497da2e3ebdSchin }
498da2e3ebdSchin return(0);
499da2e3ebdSchin }
500da2e3ebdSchin #endif /* cmd_universe */
501da2e3ebdSchin
502da2e3ebdSchin #if SHOPT_FS_3D
503da2e3ebdSchin # if 0
504da2e3ebdSchin /* for the dictionary generator */
505da2e3ebdSchin int b_vmap(int argc,char *argv[], void *extra){}
506da2e3ebdSchin # endif
b_vpath(register int argc,char * argv[],void * extra)507da2e3ebdSchin int b_vpath(register int argc,char *argv[], void *extra)
508da2e3ebdSchin {
509da2e3ebdSchin register int flag, n;
510da2e3ebdSchin register const char *optstr;
511da2e3ebdSchin register char *vend;
512da2e3ebdSchin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
5137c2fbfb3SApril Chin if(argv[0][1]=='p')
514da2e3ebdSchin {
515da2e3ebdSchin optstr = sh_optvpath;
516da2e3ebdSchin flag = FS3D_VIEW;
517da2e3ebdSchin }
518da2e3ebdSchin else
519da2e3ebdSchin {
520da2e3ebdSchin optstr = sh_optvmap;
521da2e3ebdSchin flag = FS3D_VERSION;
522da2e3ebdSchin }
523da2e3ebdSchin while(n = optget(argv, optstr)) switch(n)
524da2e3ebdSchin {
525da2e3ebdSchin case ':':
526da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
527da2e3ebdSchin break;
528da2e3ebdSchin case '?':
529da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
530da2e3ebdSchin break;
531da2e3ebdSchin }
532da2e3ebdSchin if(error_info.errors)
533da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
534da2e3ebdSchin if(!shp->lim.fs3d)
535da2e3ebdSchin goto failed;
536da2e3ebdSchin argv += opt_info.index;
537da2e3ebdSchin argc -= opt_info.index;
538da2e3ebdSchin switch(argc)
539da2e3ebdSchin {
540da2e3ebdSchin case 0:
541da2e3ebdSchin case 1:
542da2e3ebdSchin flag |= FS3D_GET;
543da2e3ebdSchin if((n = mount(*argv,(char*)0,flag,0)) >= 0)
544da2e3ebdSchin {
545da2e3ebdSchin vend = stkalloc(shp->stk,++n);
5467c2fbfb3SApril Chin n = mount(*argv,vend,flag|FS3D_SIZE(n),0);
547da2e3ebdSchin }
548da2e3ebdSchin if(n < 0)
549da2e3ebdSchin goto failed;
550da2e3ebdSchin if(argc==1)
551da2e3ebdSchin {
552da2e3ebdSchin sfprintf(sfstdout,"%s\n",vend);
553da2e3ebdSchin break;
554da2e3ebdSchin }
555da2e3ebdSchin n = 0;
556da2e3ebdSchin while(flag = *vend++)
557da2e3ebdSchin {
558da2e3ebdSchin if(flag==' ')
559da2e3ebdSchin {
560da2e3ebdSchin flag = e_sptbnl[n+1];
561da2e3ebdSchin n = !n;
562da2e3ebdSchin }
563da2e3ebdSchin sfputc(sfstdout,flag);
564da2e3ebdSchin }
565da2e3ebdSchin if(n)
566da2e3ebdSchin sfputc(sfstdout,'\n');
567da2e3ebdSchin break;
568da2e3ebdSchin default:
569da2e3ebdSchin if((argc&1))
570da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
571da2e3ebdSchin /*FALLTHROUGH*/
572da2e3ebdSchin case 2:
573da2e3ebdSchin if(!shp->lim.fs3d)
574da2e3ebdSchin goto failed;
575da2e3ebdSchin if(shp->subshell && !shp->subshare)
57634f9b3eeSRoland Mainz sh_subfork();
577da2e3ebdSchin for(n=0;n<argc;n+=2)
578da2e3ebdSchin {
579da2e3ebdSchin if(mount(argv[n+1],argv[n],flag,0)<0)
580da2e3ebdSchin goto failed;
581da2e3ebdSchin }
582da2e3ebdSchin }
583da2e3ebdSchin return(0);
584da2e3ebdSchin failed:
585da2e3ebdSchin if(argc>1)
586da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_cantset,flag==2?e_mapping:e_versions);
587da2e3ebdSchin else
588da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_cantget,flag==2?e_mapping:e_versions);
589da2e3ebdSchin return(1);
590da2e3ebdSchin }
591da2e3ebdSchin #endif /* SHOPT_FS_3D */
592da2e3ebdSchin
593da2e3ebdSchin