1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
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 __unused,char * argv[],Shbltin_t * context)60*b30d1939SAndy Fiddaman int    b_exec(int argc __unused, char *argv[], Shbltin_t *context)
61da2e3ebdSchin {
62da2e3ebdSchin 	struct login logdata;
63da2e3ebdSchin 	register int n;
64da2e3ebdSchin 	logdata.clear = 0;
65da2e3ebdSchin 	logdata.arg0 = 0;
66*b30d1939SAndy Fiddaman 	logdata.sh = context->shp;
67da2e3ebdSchin         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)
88*b30d1939SAndy Fiddaman                 B_login(0,argv,(Shbltin_t*)&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[],Shbltin_t * context)98*b30d1939SAndy Fiddaman int    B_login(int argc,char *argv[],Shbltin_t *context)
99da2e3ebdSchin {
100da2e3ebdSchin 	struct checkpt *pp;
101da2e3ebdSchin 	register struct login *logp=0;
102da2e3ebdSchin 	register Shell_t *shp;
103da2e3ebdSchin 	const char *pname;
104da2e3ebdSchin 	if(argc)
105*b30d1939SAndy Fiddaman 		shp = context->shp;
106da2e3ebdSchin 	else
107da2e3ebdSchin 	{
108*b30d1939SAndy Fiddaman 		logp = (struct login*)context;
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;
11934f9b3eeSRoland Mainz 		if(shp->subshell && !shp->subshare)
120da2e3ebdSchin 			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
1467c2fbfb3SApril Chin 		if(job_close(shp) < 0)
147da2e3ebdSchin 			return(1);
148da2e3ebdSchin #endif /* JOBS */
149da2e3ebdSchin 		/* force bad exec to terminate shell */
150da2e3ebdSchin 		pp->mode = SH_JMPEXIT;
151da2e3ebdSchin 		sh_sigreset(2);
1527c2fbfb3SApril Chin 		sh_freeup(shp);
153*b30d1939SAndy Fiddaman 		path_exec(shp,pname,argv,NIL(struct argnod*));
1547c2fbfb3SApril Chin 		sh_done(shp,0);
155da2e3ebdSchin         }
156da2e3ebdSchin 	return(1);
157da2e3ebdSchin }
158da2e3ebdSchin 
b_let(int argc,char * argv[],Shbltin_t * context)159*b30d1939SAndy Fiddaman int    b_let(int argc,char *argv[],Shbltin_t *context)
160da2e3ebdSchin {
161da2e3ebdSchin 	register int r;
162da2e3ebdSchin 	register char *arg;
163*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
164da2e3ebdSchin 	NOT_USED(argc);
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++)
178*b30d1939SAndy Fiddaman 		r = !sh_arith(shp,arg);
179da2e3ebdSchin 	return(r);
180da2e3ebdSchin }
181da2e3ebdSchin 
b_eval(int argc,char * argv[],Shbltin_t * context)182*b30d1939SAndy Fiddaman int    b_eval(int argc,char *argv[], Shbltin_t *context)
183da2e3ebdSchin {
184da2e3ebdSchin 	register int r;
185*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
186da2e3ebdSchin 	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[],Shbltin_t * context)207*b30d1939SAndy Fiddaman int    b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
208da2e3ebdSchin {
209da2e3ebdSchin 	register char *script;
210da2e3ebdSchin 	register Namval_t *np;
211da2e3ebdSchin 	register int jmpval;
212*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
213da2e3ebdSchin 	struct sh_scoped savst, *prevscope = shp->st.self;
214*b30d1939SAndy Fiddaman 	char *filename=0, *buffer=0;
215da2e3ebdSchin 	int	fd;
216*b30d1939SAndy Fiddaman 	struct dolnod   *saveargfor;
217*b30d1939SAndy Fiddaman 	volatile struct dolnod   *argsave=0;
218da2e3ebdSchin 	struct checkpt buff;
219da2e3ebdSchin 	Sfio_t *iop=0;
2207c2fbfb3SApril Chin 	short level;
221da2e3ebdSchin 	while (n = optget(argv,sh_optdot)) switch (n)
222da2e3ebdSchin 	{
223da2e3ebdSchin 	    case ':':
224da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
225da2e3ebdSchin 		break;
226da2e3ebdSchin 	    case '?':
227da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
228da2e3ebdSchin 		return(2);
229da2e3ebdSchin 	}
230da2e3ebdSchin 	argv += opt_info.index;
231da2e3ebdSchin 	script = *argv;
232da2e3ebdSchin 	if(error_info.errors || !script)
233da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
2347c2fbfb3SApril Chin 	if(shp->dot_depth+1 > DOTMAX)
235da2e3ebdSchin 		errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
236da2e3ebdSchin 	if(!(np=shp->posix_fun))
237da2e3ebdSchin 	{
238da2e3ebdSchin 		/* check for KornShell style function first */
239da2e3ebdSchin 		np = nv_search(script,shp->fun_tree,0);
240da2e3ebdSchin 		if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX))
241da2e3ebdSchin 		{
242da2e3ebdSchin 			if(!np->nvalue.ip)
243da2e3ebdSchin 			{
244*b30d1939SAndy Fiddaman 				path_search(shp,script,NIL(Pathcomp_t**),0);
245da2e3ebdSchin 				if(np->nvalue.ip)
246da2e3ebdSchin 				{
247da2e3ebdSchin 					if(nv_isattr(np,NV_FPOSIX))
248da2e3ebdSchin 						np = 0;
249da2e3ebdSchin 				}
250da2e3ebdSchin 				else
251da2e3ebdSchin 					errormsg(SH_DICT,ERROR_exit(1),e_found,script);
252da2e3ebdSchin 			}
253da2e3ebdSchin 		}
254da2e3ebdSchin 		else
255da2e3ebdSchin 			np = 0;
256da2e3ebdSchin 		if(!np)
257da2e3ebdSchin 		{
258*b30d1939SAndy Fiddaman 			if((fd=path_open(shp,script,path_get(shp,script))) < 0)
259da2e3ebdSchin 				errormsg(SH_DICT,ERROR_system(1),e_open,script);
260*b30d1939SAndy Fiddaman 			filename = path_fullname(shp,stkptr(shp->stk,PATH_OFFSET));
261da2e3ebdSchin 		}
262da2e3ebdSchin 	}
263da2e3ebdSchin 	*prevscope = shp->st;
2647c2fbfb3SApril Chin 	shp->st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
2657c2fbfb3SApril Chin 	shp->st.var_local = shp->st.save_tree = shp->var_tree;
266da2e3ebdSchin 	if(filename)
2677c2fbfb3SApril Chin 	{
268da2e3ebdSchin 		shp->st.filename = filename;
2697c2fbfb3SApril Chin 		shp->st.lineno = 1;
2707c2fbfb3SApril Chin 	}
2717c2fbfb3SApril Chin 	level  = shp->fn_depth+shp->dot_depth+1;
2727c2fbfb3SApril Chin 	nv_putval(SH_LEVELNOD,(char*)&level,NV_INT16);
273da2e3ebdSchin 	shp->st.prevst = prevscope;
274da2e3ebdSchin 	shp->st.self = &savst;
275da2e3ebdSchin 	shp->topscope = (Shscope_t*)shp->st.self;
276da2e3ebdSchin 	prevscope->save_tree = shp->var_tree;
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])
2827c2fbfb3SApril Chin 		argsave = sh_argnew(shp,argv,&saveargfor);
283*b30d1939SAndy Fiddaman 	sh_pushcontext(shp,&buff,SH_JMPDOT);
284da2e3ebdSchin 	jmpval = sigsetjmp(buff.buff,0);
285da2e3ebdSchin 	if(jmpval == 0)
286da2e3ebdSchin 	{
2877c2fbfb3SApril Chin 		shp->dot_depth++;
288da2e3ebdSchin 		if(np)
289da2e3ebdSchin 			sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
290da2e3ebdSchin 		else
291da2e3ebdSchin 		{
292*b30d1939SAndy Fiddaman 			buffer = malloc(IOBSIZE+1);
293*b30d1939SAndy Fiddaman 			iop = sfnew(NIL(Sfio_t*),buffer,IOBSIZE,fd,SF_READ);
294*b30d1939SAndy Fiddaman 			sh_offstate(SH_NOFORK);
295*b30d1939SAndy Fiddaman 			sh_eval(iop,sh_isstate(SH_PROFILE)?SH_FUNEVAL:0);
296da2e3ebdSchin 		}
297da2e3ebdSchin 	}
298*b30d1939SAndy Fiddaman 	sh_popcontext(shp,&buff);
299*b30d1939SAndy Fiddaman 	if(buffer)
300*b30d1939SAndy Fiddaman 		free(buffer);
301da2e3ebdSchin 	if(!np)
302da2e3ebdSchin 		free((void*)shp->st.filename);
303da2e3ebdSchin 	shp->dot_depth--;
304da2e3ebdSchin 	if((np || argv[1]) && jmpval!=SH_JMPSCRIPT)
305*b30d1939SAndy Fiddaman 		sh_argreset(shp,(struct dolnod*)argsave,saveargfor);
306da2e3ebdSchin 	else
307da2e3ebdSchin 	{
308da2e3ebdSchin 		prevscope->dolc = shp->st.dolc;
309da2e3ebdSchin 		prevscope->dolv = shp->st.dolv;
310da2e3ebdSchin 	}
311da2e3ebdSchin 	if (shp->st.self != &savst)
312da2e3ebdSchin 		*shp->st.self = shp->st;
313da2e3ebdSchin 	/* only restore the top Shscope_t portion for posix functions */
314da2e3ebdSchin 	memcpy((void*)&shp->st, (void*)prevscope, sizeof(Shscope_t));
315da2e3ebdSchin 	shp->topscope = (Shscope_t*)prevscope;
316da2e3ebdSchin 	nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
317da2e3ebdSchin 	if(jmpval && jmpval!=SH_JMPFUN)
318da2e3ebdSchin 		siglongjmp(*shp->jmplist,jmpval);
319da2e3ebdSchin 	return(shp->exitval);
320da2e3ebdSchin }
321da2e3ebdSchin 
322da2e3ebdSchin /*
323da2e3ebdSchin  * null, true  command
324da2e3ebdSchin  */
b_true(int argc,register char * argv[],Shbltin_t * context)325*b30d1939SAndy Fiddaman int    b_true(int argc,register char *argv[],Shbltin_t *context)
326da2e3ebdSchin {
327da2e3ebdSchin 	NOT_USED(argc);
328da2e3ebdSchin 	NOT_USED(argv[0]);
329*b30d1939SAndy Fiddaman 	NOT_USED(context);
330da2e3ebdSchin 	return(0);
331da2e3ebdSchin }
332da2e3ebdSchin 
333da2e3ebdSchin /*
334da2e3ebdSchin  * false  command
335da2e3ebdSchin  */
b_false(int argc,register char * argv[],Shbltin_t * context)336*b30d1939SAndy Fiddaman int    b_false(int argc,register char *argv[], Shbltin_t *context)
337da2e3ebdSchin {
338da2e3ebdSchin 	NOT_USED(argc);
339da2e3ebdSchin 	NOT_USED(argv[0]);
340*b30d1939SAndy Fiddaman 	NOT_USED(context);
341da2e3ebdSchin 	return(1);
342da2e3ebdSchin }
343da2e3ebdSchin 
b_shift(register int n,register char * argv[],Shbltin_t * context)344*b30d1939SAndy Fiddaman int    b_shift(register int n, register char *argv[], Shbltin_t *context)
345da2e3ebdSchin {
346da2e3ebdSchin 	register char *arg;
347*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
348da2e3ebdSchin 	while((n = optget(argv,sh_optshift))) switch(n)
349da2e3ebdSchin 	{
350da2e3ebdSchin 		case ':':
351da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
352da2e3ebdSchin 			break;
353da2e3ebdSchin 		case '?':
354da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
355da2e3ebdSchin 			return(2);
356da2e3ebdSchin 	}
357da2e3ebdSchin 	if(error_info.errors)
358da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
359da2e3ebdSchin 	argv += opt_info.index;
360*b30d1939SAndy Fiddaman 	n = ((arg= *argv)?(int)sh_arith(shp,arg):1);
361da2e3ebdSchin 	if(n<0 || shp->st.dolc<n)
362da2e3ebdSchin 		errormsg(SH_DICT,ERROR_exit(1),e_number,arg);
363da2e3ebdSchin 	else
364da2e3ebdSchin 	{
365da2e3ebdSchin 		shp->st.dolv += n;
366da2e3ebdSchin 		shp->st.dolc -= n;
367da2e3ebdSchin 	}
368da2e3ebdSchin 	return(0);
369da2e3ebdSchin }
370da2e3ebdSchin 
b_wait(int n,register char * argv[],Shbltin_t * context)371*b30d1939SAndy Fiddaman int    b_wait(int n,register char *argv[],Shbltin_t *context)
372da2e3ebdSchin {
373*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
374da2e3ebdSchin 	while((n = optget(argv,sh_optwait))) switch(n)
375da2e3ebdSchin 	{
376da2e3ebdSchin 		case ':':
377da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
378da2e3ebdSchin 			break;
379da2e3ebdSchin 		case '?':
380da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
381da2e3ebdSchin 			break;
382da2e3ebdSchin 	}
383da2e3ebdSchin 	if(error_info.errors)
384da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
385da2e3ebdSchin 	argv += opt_info.index;
386da2e3ebdSchin 	job_bwait(argv);
387da2e3ebdSchin 	return(shp->exitval);
388da2e3ebdSchin }
389da2e3ebdSchin 
390da2e3ebdSchin #ifdef JOBS
391da2e3ebdSchin #   if 0
392da2e3ebdSchin     /* for the dictionary generator */
393*b30d1939SAndy Fiddaman 	int    b_fg(int n,char *argv[],Shbltin_t *context){}
394*b30d1939SAndy Fiddaman 	int    b_disown(int n,char *argv[],Shbltin_t *context){}
395da2e3ebdSchin #   endif
b_bg(register int n,register char * argv[],Shbltin_t * context)396*b30d1939SAndy Fiddaman int    b_bg(register int n,register char *argv[],Shbltin_t *context)
397da2e3ebdSchin {
398da2e3ebdSchin 	register int flag = **argv;
399*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
400da2e3ebdSchin 	register const char *optstr = sh_optbg;
401da2e3ebdSchin 	if(*argv[0]=='f')
402da2e3ebdSchin 		optstr = sh_optfg;
403da2e3ebdSchin 	else if(*argv[0]=='d')
404da2e3ebdSchin 		optstr = sh_optdisown;
405da2e3ebdSchin 	while((n = optget(argv,optstr))) switch(n)
406da2e3ebdSchin 	{
407da2e3ebdSchin 	    case ':':
408da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
409da2e3ebdSchin 		break;
410da2e3ebdSchin 	    case '?':
411da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
412da2e3ebdSchin 		break;
413da2e3ebdSchin 	}
414da2e3ebdSchin 	if(error_info.errors)
415da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
416da2e3ebdSchin 	argv += opt_info.index;
417da2e3ebdSchin 	if(!sh_isoption(SH_MONITOR) || !job.jobcontrol)
418da2e3ebdSchin 	{
419da2e3ebdSchin 		if(sh_isstate(SH_INTERACTIVE))
420da2e3ebdSchin 			errormsg(SH_DICT,ERROR_exit(1),e_no_jctl);
421da2e3ebdSchin 		return(1);
422da2e3ebdSchin 	}
423da2e3ebdSchin 	if(flag=='d' && *argv==0)
424da2e3ebdSchin 		argv = (char**)0;
425da2e3ebdSchin 	if(job_walk(sfstdout,job_switch,flag,argv))
426da2e3ebdSchin 		errormsg(SH_DICT,ERROR_exit(1),e_no_job);
427da2e3ebdSchin 	return(shp->exitval);
428da2e3ebdSchin }
429da2e3ebdSchin 
b_jobs(register int n,char * argv[],Shbltin_t * context)430*b30d1939SAndy Fiddaman int    b_jobs(register int n,char *argv[],Shbltin_t *context)
431da2e3ebdSchin {
432da2e3ebdSchin 	register int flag = 0;
433*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
434da2e3ebdSchin 	while((n = optget(argv,sh_optjobs))) switch(n)
435da2e3ebdSchin 	{
436da2e3ebdSchin 	    case 'l':
437da2e3ebdSchin 		flag = JOB_LFLAG;
438da2e3ebdSchin 		break;
439da2e3ebdSchin 	    case 'n':
440da2e3ebdSchin 		flag = JOB_NFLAG;
441da2e3ebdSchin 		break;
442da2e3ebdSchin 	    case 'p':
443da2e3ebdSchin 		flag = JOB_PFLAG;
444da2e3ebdSchin 		break;
445da2e3ebdSchin 	    case ':':
446da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
447da2e3ebdSchin 		break;
448da2e3ebdSchin 	    case '?':
449da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
450da2e3ebdSchin 		break;
451da2e3ebdSchin 	}
452da2e3ebdSchin 	argv += opt_info.index;
453da2e3ebdSchin 	if(error_info.errors)
454da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
455da2e3ebdSchin 	if(*argv==0)
456da2e3ebdSchin 		argv = (char**)0;
457da2e3ebdSchin 	if(job_walk(sfstdout,job_list,flag,argv))
458da2e3ebdSchin 		errormsg(SH_DICT,ERROR_exit(1),e_no_job);
459da2e3ebdSchin 	job_wait((pid_t)0);
460da2e3ebdSchin 	return(shp->exitval);
461da2e3ebdSchin }
462da2e3ebdSchin #endif
463da2e3ebdSchin 
464da2e3ebdSchin #ifdef _cmd_universe
465da2e3ebdSchin /*
466da2e3ebdSchin  * There are several universe styles that are masked by the getuniv(),
467da2e3ebdSchin  * setuniv() calls.
468da2e3ebdSchin  */
b_universe(int argc,char * argv[],Shbltin_t * context)469*b30d1939SAndy Fiddaman int	b_universe(int argc, char *argv[],Shbltin_t *context)
470da2e3ebdSchin {
471da2e3ebdSchin 	register char *arg;
472da2e3ebdSchin 	register int n;
473*b30d1939SAndy Fiddaman 	NOT_USED(context);
474da2e3ebdSchin 	while((n = optget(argv,sh_optuniverse))) switch(n)
475da2e3ebdSchin 	{
476da2e3ebdSchin 	    case ':':
477da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
478da2e3ebdSchin 		break;
479da2e3ebdSchin 	    case '?':
480da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
481da2e3ebdSchin 		break;
482da2e3ebdSchin 	}
483da2e3ebdSchin 	argv += opt_info.index;
484da2e3ebdSchin 	argc -= opt_info.index;
485da2e3ebdSchin 	if(error_info.errors || argc>1)
486da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
487da2e3ebdSchin 	if(arg = argv[0])
488da2e3ebdSchin 	{
489da2e3ebdSchin 		if(!astconf("UNIVERSE",0,arg))
490da2e3ebdSchin 			errormsg(SH_DICT,ERROR_exit(1), e_badname,arg);
491da2e3ebdSchin 	}
492da2e3ebdSchin 	else
493da2e3ebdSchin 	{
494da2e3ebdSchin 		if(!(arg=astconf("UNIVERSE",0,0)))
495da2e3ebdSchin 			errormsg(SH_DICT,ERROR_exit(1),e_nouniverse);
496da2e3ebdSchin 		else
497da2e3ebdSchin 			sfputr(sfstdout,arg,'\n');
498da2e3ebdSchin 	}
499da2e3ebdSchin 	return(0);
500da2e3ebdSchin }
501da2e3ebdSchin #endif /* cmd_universe */
502da2e3ebdSchin 
503da2e3ebdSchin #if SHOPT_FS_3D
504*b30d1939SAndy Fiddaman #if _UWIN
505*b30d1939SAndy Fiddaman #include <sys/mount.h>
506*b30d1939SAndy Fiddaman #endif
507da2e3ebdSchin #   if 0
508da2e3ebdSchin     /* for the dictionary generator */
509*b30d1939SAndy Fiddaman     int	b_vmap(int argc,char *argv[], Shbltin_t *context){}
510da2e3ebdSchin #   endif
b_vpath(register int argc,char * argv[],Shbltin_t * context)511*b30d1939SAndy Fiddaman     int	b_vpath(register int argc,char *argv[], Shbltin_t *context)
512da2e3ebdSchin     {
513da2e3ebdSchin 	register int flag, n;
514da2e3ebdSchin 	register const char *optstr;
515da2e3ebdSchin 	register char *vend;
516*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
517da2e3ebdSchin 	if(argv[0][1]=='p')
518da2e3ebdSchin 	{
519da2e3ebdSchin 		optstr = sh_optvpath;
520da2e3ebdSchin 		flag = FS3D_VIEW;
521da2e3ebdSchin 	}
522da2e3ebdSchin 	else
523da2e3ebdSchin 	{
524da2e3ebdSchin 		optstr = sh_optvmap;
525da2e3ebdSchin 		flag = FS3D_VERSION;
526da2e3ebdSchin 	}
527da2e3ebdSchin 	while(n = optget(argv, optstr)) switch(n)
528da2e3ebdSchin 	{
529da2e3ebdSchin 	    case ':':
530da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
531da2e3ebdSchin 		break;
532da2e3ebdSchin 	    case '?':
533da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
534da2e3ebdSchin 		break;
535da2e3ebdSchin 	}
536da2e3ebdSchin 	if(error_info.errors)
537da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
538*b30d1939SAndy Fiddaman #ifdef MS_3D
539*b30d1939SAndy Fiddaman 	flag |= MS_3D;
540*b30d1939SAndy Fiddaman #else
541*b30d1939SAndy Fiddaman 	if(!shp->gd->lim.fs3d)
542da2e3ebdSchin 		goto failed;
543*b30d1939SAndy Fiddaman #endif
544da2e3ebdSchin 	argv += opt_info.index;
545da2e3ebdSchin 	argc -= opt_info.index;
546da2e3ebdSchin 	switch(argc)
547da2e3ebdSchin 	{
548da2e3ebdSchin 	    case 0:
549da2e3ebdSchin 	    case 1:
550da2e3ebdSchin 		flag |= FS3D_GET;
551da2e3ebdSchin 		if((n = mount(*argv,(char*)0,flag,0)) >= 0)
552da2e3ebdSchin 		{
5537c2fbfb3SApril Chin 			vend = stkalloc(shp->stk,++n);
554da2e3ebdSchin 			n = mount(*argv,vend,flag|FS3D_SIZE(n),0);
555da2e3ebdSchin 		}
556da2e3ebdSchin 		if(n < 0)
557da2e3ebdSchin 			goto failed;
558da2e3ebdSchin 		if(argc==1)
559da2e3ebdSchin 		{
560da2e3ebdSchin 			sfprintf(sfstdout,"%s\n",vend);
561da2e3ebdSchin 			break;
562da2e3ebdSchin 		}
563da2e3ebdSchin 		n = 0;
564da2e3ebdSchin 		while(flag = *vend++)
565da2e3ebdSchin 		{
566da2e3ebdSchin 			if(flag==' ')
567da2e3ebdSchin 			{
568da2e3ebdSchin 				flag  = e_sptbnl[n+1];
569da2e3ebdSchin 				n = !n;
570da2e3ebdSchin 			}
571da2e3ebdSchin 			sfputc(sfstdout,flag);
572da2e3ebdSchin 		}
573da2e3ebdSchin 		if(n)
574da2e3ebdSchin 			sfputc(sfstdout,'\n');
575da2e3ebdSchin 		break;
576da2e3ebdSchin 	     default:
577da2e3ebdSchin 		if((argc&1))
578da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
579da2e3ebdSchin 		/*FALLTHROUGH*/
580da2e3ebdSchin 	     case 2:
58134f9b3eeSRoland Mainz 		if(shp->subshell && !shp->subshare)
582da2e3ebdSchin 			sh_subfork();
583da2e3ebdSchin  		for(n=0;n<argc;n+=2)
584da2e3ebdSchin 			if(mount(argv[n+1],argv[n],flag,0)<0)
585da2e3ebdSchin 				goto failed;
586da2e3ebdSchin 	}
587da2e3ebdSchin 	return(0);
588da2e3ebdSchin failed:
589*b30d1939SAndy Fiddaman 	errormsg(SH_DICT,ERROR_exit(1),(argc>1)?e_cantset:e_cantget,(flag&FS3D_VIEW)?e_mapping:e_versions);
590da2e3ebdSchin 	return(1);
591da2e3ebdSchin     }
592da2e3ebdSchin #endif /* SHOPT_FS_3D */
593da2e3ebdSchin 
594