1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
24 * jobs [-lnp] [job...]
40 #include "variables.h"
49 #define DOTMAX MAXDEPTH /* maximum level of . nesting */
51 static void noexport(Namval_t
*,void*);
60 int b_exec(int argc
,char *argv
[], void *extra
)
66 logdata
.sh
= ((Shbltin_t
*)extra
)->shp
;
67 logdata
.sh
->st
.ioset
= 0;
68 while (n
= optget(argv
, sh_optexec
)) switch (n
)
71 logdata
.arg0
= opt_info
.arg
;
78 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
81 errormsg(SH_DICT
,ERROR_usage(0), "%s", opt_info
.arg
);
84 argv
+= opt_info
.index
;
86 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
88 B_login(0,argv
,(void*)&logdata
);
92 static void noexport(register Namval_t
* np
, void *data
)
95 nv_offattr(np
,NV_EXPORT
);
98 int B_login(int argc
,char *argv
[],void *extra
)
101 register struct login
*logp
=0;
102 register Shell_t
*shp
;
105 shp
= ((Shbltin_t
*)extra
)->shp
;
108 logp
= (struct login
*)extra
;
111 pp
= (struct checkpt
*)shp
->jmplist
;
112 if(sh_isoption(SH_RESTRICTED
))
113 errormsg(SH_DICT
,ERROR_exit(1),e_restricted
,argv
[0]);
116 register struct argnod
*arg
=shp
->envlist
;
117 register Namval_t
* np
;
119 if(shp
->subshell
&& !shp
->subshare
)
121 if(logp
&& logp
->clear
)
125 shp
->env
= env_open((char**)0,3);
127 nv_scan(shp
->var_tree
,noexport
,0,NV_EXPORT
,NV_EXPORT
);
132 if((cp
=strchr(arg
->argval
,'=')) &&
133 (*cp
=0,np
=nv_search(arg
->argval
,shp
->var_tree
,0)))
135 nv_onattr(np
,NV_EXPORT
);
136 sh_envput(shp
->env
,np
);
143 if(logp
&& logp
->arg0
)
144 argv
[0] = logp
->arg0
;
146 if(job_close(shp
) < 0)
149 /* force bad exec to terminate shell */
150 pp
->mode
= SH_JMPEXIT
;
153 path_exec(pname
,argv
,NIL(struct argnod
*));
159 int b_let(int argc
,char *argv
[],void *extra
)
165 while (r
= optget(argv
,sh_optlet
)) switch (r
)
168 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
171 errormsg(SH_DICT
,ERROR_usage(2), "%s", opt_info
.arg
);
174 argv
+= opt_info
.index
;
175 if(error_info
.errors
|| !*argv
)
176 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
182 int b_eval(int argc
,char *argv
[], void *extra
)
185 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
187 while (r
= optget(argv
,sh_opteval
)) switch (r
)
190 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
193 errormsg(SH_DICT
,ERROR_usage(0), "%s",opt_info
.arg
);
196 if(error_info
.errors
)
197 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
198 argv
+= opt_info
.index
;
201 sh_offstate(SH_MONITOR
);
202 sh_eval(sh_sfeval(argv
),0);
204 return(shp
->exitval
);
207 int b_dot_cmd(register int n
,char *argv
[],void* extra
)
209 register char *script
;
210 register Namval_t
*np
;
212 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
213 struct sh_scoped savst
, *prevscope
= shp
->st
.self
;
216 struct dolnod
*argsave
=0, *saveargfor
;
220 while (n
= optget(argv
,sh_optdot
)) switch (n
)
223 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
226 errormsg(SH_DICT
,ERROR_usage(0), "%s",opt_info
.arg
);
229 argv
+= opt_info
.index
;
231 if(error_info
.errors
|| !script
)
232 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
233 if(shp
->dot_depth
+1 > DOTMAX
)
234 errormsg(SH_DICT
,ERROR_exit(1),e_toodeep
,script
);
235 if(!(np
=shp
->posix_fun
))
237 /* check for KornShell style function first */
238 np
= nv_search(script
,shp
->fun_tree
,0);
239 if(np
&& is_afunction(np
) && !nv_isattr(np
,NV_FPOSIX
))
243 path_search(script
,NIL(Pathcomp_t
**),0);
246 if(nv_isattr(np
,NV_FPOSIX
))
250 errormsg(SH_DICT
,ERROR_exit(1),e_found
,script
);
257 if((fd
=path_open(script
,path_get(script
))) < 0)
258 errormsg(SH_DICT
,ERROR_system(1),e_open
,script
);
259 filename
= path_fullname(stkptr(shp
->stk
,PATH_OFFSET
));
262 *prevscope
= shp
->st
;
263 shp
->st
.lineno
= np
?((struct functnod
*)nv_funtree(np
))->functline
:1;
264 shp
->st
.var_local
= shp
->st
.save_tree
= shp
->var_tree
;
267 shp
->st
.filename
= filename
;
270 level
= shp
->fn_depth
+shp
->dot_depth
+1;
271 nv_putval(SH_LEVELNOD
,(char*)&level
,NV_INT16
);
272 shp
->st
.prevst
= prevscope
;
273 shp
->st
.self
= &savst
;
274 shp
->topscope
= (Shscope_t
*)shp
->st
.self
;
275 prevscope
->save_tree
= shp
->var_tree
;
276 shp
->st
.cmdname
= argv
[0];
278 shp
->st
.filename
= np
->nvalue
.rp
->fname
;
279 nv_putval(SH_PATHNAMENOD
, shp
->st
.filename
,NV_NOFREE
);
282 argsave
= sh_argnew(shp
,argv
,&saveargfor
);
283 sh_pushcontext(&buff
,SH_JMPDOT
);
284 jmpval
= sigsetjmp(buff
.buff
,0);
289 sh_exec((Shnode_t
*)(nv_funtree(np
)),sh_isstate(SH_ERREXIT
));
292 char buff
[IOBSIZE
+1];
293 iop
= sfnew(NIL(Sfio_t
*),buff
,IOBSIZE
,fd
,SF_READ
);
297 sh_popcontext(&buff
);
299 free((void*)shp
->st
.filename
);
301 if((np
|| argv
[1]) && jmpval
!=SH_JMPSCRIPT
)
302 sh_argreset(shp
,argsave
,saveargfor
);
305 prevscope
->dolc
= shp
->st
.dolc
;
306 prevscope
->dolv
= shp
->st
.dolv
;
308 if (shp
->st
.self
!= &savst
)
309 *shp
->st
.self
= shp
->st
;
310 /* only restore the top Shscope_t portion for posix functions */
311 memcpy((void*)&shp
->st
, (void*)prevscope
, sizeof(Shscope_t
));
312 shp
->topscope
= (Shscope_t
*)prevscope
;
313 nv_putval(SH_PATHNAMENOD
, shp
->st
.filename
,NV_NOFREE
);
314 if(shp
->exitval
> SH_EXITSIG
)
315 sh_fault(shp
->exitval
&SH_EXITMASK
);
316 if(jmpval
&& jmpval
!=SH_JMPFUN
)
317 siglongjmp(*shp
->jmplist
,jmpval
);
318 return(shp
->exitval
);
324 int b_true(int argc
,register char *argv
[],void *extra
)
335 int b_false(int argc
,register char *argv
[], void *extra
)
343 int b_shift(register int n
, register char *argv
[], void *extra
)
346 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
347 while((n
= optget(argv
,sh_optshift
))) switch(n
)
350 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
353 errormsg(SH_DICT
,ERROR_usage(0), "%s",opt_info
.arg
);
356 if(error_info
.errors
)
357 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
358 argv
+= opt_info
.index
;
359 n
= ((arg
= *argv
)?(int)sh_arith(arg
):1);
360 if(n
<0 || shp
->st
.dolc
<n
)
361 errormsg(SH_DICT
,ERROR_exit(1),e_number
,arg
);
370 int b_wait(int n
,register char *argv
[],void *extra
)
372 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
373 while((n
= optget(argv
,sh_optwait
))) switch(n
)
376 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
379 errormsg(SH_DICT
,ERROR_usage(2), "%s",opt_info
.arg
);
382 if(error_info
.errors
)
383 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
384 argv
+= opt_info
.index
;
386 return(shp
->exitval
);
391 /* for the dictionary generator */
392 int b_fg(int n
,char *argv
[],void *extra
){}
393 int b_disown(int n
,char *argv
[],void *extra
){}
395 int b_bg(register int n
,register char *argv
[],void *extra
)
397 register int flag
= **argv
;
398 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
399 register const char *optstr
= sh_optbg
;
402 else if(*argv
[0]=='d')
403 optstr
= sh_optdisown
;
404 while((n
= optget(argv
,optstr
))) switch(n
)
407 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
410 errormsg(SH_DICT
,ERROR_usage(2), "%s",opt_info
.arg
);
413 if(error_info
.errors
)
414 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
415 argv
+= opt_info
.index
;
416 if(!sh_isoption(SH_MONITOR
) || !job
.jobcontrol
)
418 if(sh_isstate(SH_INTERACTIVE
))
419 errormsg(SH_DICT
,ERROR_exit(1),e_no_jctl
);
422 if(flag
=='d' && *argv
==0)
424 if(job_walk(sfstdout
,job_switch
,flag
,argv
))
425 errormsg(SH_DICT
,ERROR_exit(1),e_no_job
);
426 return(shp
->exitval
);
429 int b_jobs(register int n
,char *argv
[],void *extra
)
431 register int flag
= 0;
432 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
433 while((n
= optget(argv
,sh_optjobs
))) switch(n
)
445 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
448 errormsg(SH_DICT
,ERROR_usage(2), "%s",opt_info
.arg
);
451 argv
+= opt_info
.index
;
452 if(error_info
.errors
)
453 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
456 if(job_walk(sfstdout
,job_list
,flag
,argv
))
457 errormsg(SH_DICT
,ERROR_exit(1),e_no_job
);
459 return(shp
->exitval
);
465 * There are several universe styles that are masked by the getuniv(),
468 int b_universe(int argc
, char *argv
[],void *extra
)
473 while((n
= optget(argv
,sh_optuniverse
))) switch(n
)
476 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
479 errormsg(SH_DICT
,ERROR_usage(2), "%s",opt_info
.arg
);
482 argv
+= opt_info
.index
;
483 argc
-= opt_info
.index
;
484 if(error_info
.errors
|| argc
>1)
485 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
488 if(!astconf("UNIVERSE",0,arg
))
489 errormsg(SH_DICT
,ERROR_exit(1), e_badname
,arg
);
493 if(!(arg
=astconf("UNIVERSE",0,0)))
494 errormsg(SH_DICT
,ERROR_exit(1),e_nouniverse
);
496 sfputr(sfstdout
,arg
,'\n');
500 #endif /* cmd_universe */
504 /* for the dictionary generator */
505 int b_vmap(int argc
,char *argv
[], void *extra
){}
507 int b_vpath(register int argc
,char *argv
[], void *extra
)
509 register int flag
, n
;
510 register const char *optstr
;
512 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
515 optstr
= sh_optvpath
;
523 while(n
= optget(argv
, optstr
)) switch(n
)
526 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
529 errormsg(SH_DICT
,ERROR_usage(2), "%s",opt_info
.arg
);
532 if(error_info
.errors
)
533 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
536 argv
+= opt_info
.index
;
537 argc
-= opt_info
.index
;
543 if((n
= mount(*argv
,(char*)0,flag
,0)) >= 0)
545 vend
= stkalloc(shp
->stk
,++n
);
546 n
= mount(*argv
,vend
,flag
|FS3D_SIZE(n
),0);
552 sfprintf(sfstdout
,"%s\n",vend
);
556 while(flag
= *vend
++)
560 flag
= e_sptbnl
[n
+1];
563 sfputc(sfstdout
,flag
);
566 sfputc(sfstdout
,'\n');
570 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage((char*)0));
575 if(shp
->subshell
&& !shp
->subshare
)
579 if(mount(argv
[n
+1],argv
[n
],flag
,0)<0)
586 errormsg(SH_DICT
,ERROR_exit(1),e_cantset
,flag
==2?e_mapping
:e_versions
);
588 errormsg(SH_DICT
,ERROR_exit(1),e_cantget
,flag
==2?e_mapping
:e_versions
);
591 #endif /* SHOPT_FS_3D */