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