xref: /titanic_51/usr/src/lib/libshell/common/bltins/misc.c (revision 8ddde5afbc73594c66a4a0a32d45b9e7f0aae4e4)
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