8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sh / bltin.c
blob0c15261df9c99ccf07b81f6d058b3d592f90803a
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
33 * UNIX shell
38 #include "defs.h"
39 #include <errno.h>
40 #include "sym.h"
41 #include "hash.h"
42 #include <sys/types.h>
43 #include <sys/times.h>
45 void
46 builtin(int type, int argc, unsigned char **argv, struct trenod *t)
48 short index = initio(t->treio, (type != SYSEXEC));
49 unsigned char *a1 = argv[1];
51 switch (type)
54 case SYSSUSP:
55 syssusp(argc,argv);
56 break;
58 case SYSSTOP:
59 sysstop(argc,argv);
60 break;
62 case SYSKILL:
63 syskill(argc,argv);
64 break;
66 case SYSFGBG:
67 sysfgbg(argc,argv);
68 break;
70 case SYSJOBS:
71 sysjobs(argc,argv);
72 break;
74 case SYSDOT:
75 if (a1)
77 int f;
79 if ((f = pathopen(getpath(a1), a1)) < 0)
80 failed(a1, notfound);
81 else
82 execexp(0, f);
84 break;
86 case SYSTIMES:
88 struct tms tms;
90 times(&tms);
91 prt(tms.tms_cutime);
92 prc_buff(SPACE);
93 prt(tms.tms_cstime);
94 prc_buff(NL);
96 break;
98 case SYSEXIT:
99 if ( tried_to_exit++ || endjobs(JOB_STOPPED) ){
100 flags |= forcexit; /* force exit */
101 exitsh(a1 ? stoi(a1) : retval);
103 break;
105 case SYSNULL:
106 t->treio = 0;
107 break;
109 case SYSCONT:
110 if (loopcnt)
112 execbrk = breakcnt = 1;
113 if (a1)
114 breakcnt = stoi(a1);
115 if (breakcnt > loopcnt)
116 breakcnt = loopcnt;
117 else
118 breakcnt = -breakcnt;
120 break;
122 case SYSBREAK:
123 if (loopcnt)
125 execbrk = breakcnt = 1;
126 if (a1)
127 breakcnt = stoi(a1);
128 if (breakcnt > loopcnt)
129 breakcnt = loopcnt;
131 break;
133 case SYSTRAP:
134 systrap(argc,argv);
135 break;
137 case SYSEXEC:
138 argv++;
139 ioset = 0;
140 if (a1 == 0) {
141 setmode(0);
142 break;
144 /* FALLTHROUGH */
146 #ifdef RES /* Research includes login as part of the shell */
148 case SYSLOGIN:
149 if (!endjobs(JOB_STOPPED|JOB_RUNNING))
150 break;
151 oldsigs();
152 execa(argv, -1);
153 done(0);
154 #else
156 case SYSNEWGRP:
157 if (flags & rshflg)
158 failed(argv[0], restricted);
159 else if (!endjobs(JOB_STOPPED|JOB_RUNNING))
160 break;
161 else
163 flags |= forcexit; /* bad exec will terminate shell */
164 oldsigs();
165 rmtemp(0);
166 rmfunctmp();
167 #ifdef ACCT
168 doacct();
169 #endif
170 execa(argv, -1);
171 done(0);
174 #endif
176 case SYSCD:
177 if (flags & rshflg)
178 failed(argv[0], restricted);
179 else if ((a1 && *a1) || (a1 == 0 && (a1 = homenod.namval)))
181 unsigned char *cdpath;
182 unsigned char *dir;
183 int f;
185 if ((cdpath = cdpnod.namval) == 0 ||
186 *a1 == '/' ||
187 cf(a1, ".") == 0 ||
188 cf(a1, "..") == 0 ||
189 (*a1 == '.' && (*(a1+1) == '/' || *(a1+1) == '.' && *(a1+2) == '/')))
190 cdpath = (unsigned char *)nullstr;
194 dir = cdpath;
195 cdpath = catpath(cdpath,a1);
197 while ((f = (chdir((const char *) curstak()) < 0)) &&
198 cdpath);
200 if (f) {
201 switch(errno) {
202 case EMULTIHOP:
203 failed(a1, emultihop);
204 break;
205 case ENOTDIR:
206 failed(a1, enotdir);
207 break;
208 case ENOENT:
209 failed(a1, enoent);
210 break;
211 case EACCES:
212 failed(a1, eacces);
213 break;
214 case ENOLINK:
215 failed(a1, enolink);
216 break;
217 default:
218 failed(a1, baddir);
219 break;
222 else
224 cwd(curstak());
225 if (cf(nullstr, dir) &&
226 *dir != ':' &&
227 any('/', curstak()) &&
228 flags & prompt)
230 prs_buff(cwdget());
231 prc_buff(NL);
234 zapcd();
236 else
238 if (a1)
239 error(nulldir);
240 else
241 error(nohome);
244 break;
246 case SYSSHFT:
248 int places;
250 places = a1 ? stoi(a1) : 1;
252 if ((dolc -= places) < 0)
254 dolc = 0;
255 error(badshift);
257 else
258 dolv += places;
261 break;
263 case SYSWAIT:
264 syswait(argc,argv);
265 break;
267 case SYSREAD:
268 if(argc < 2)
269 failed(argv[0],mssgargn);
270 rwait = 1;
271 exitval = readvar(&argv[1]);
272 rwait = 0;
273 break;
275 case SYSSET:
276 if (a1)
278 int cnt;
280 cnt = options(argc, argv);
281 if (cnt > 1)
282 setargs(argv + argc - cnt);
284 else if (comptr(t)->comset == 0)
287 * scan name chain and print
289 namscan(printnam);
291 break;
293 case SYSRDONLY:
294 exitval = 0;
295 if (a1)
297 while (*++argv)
298 attrib(lookup(*argv), N_RDONLY);
300 else
301 namscan(printro);
303 break;
305 case SYSXPORT:
307 struct namnod *n;
309 exitval = 0;
310 if (a1)
312 while (*++argv)
314 n = lookup(*argv);
315 if (n->namflg & N_FUNCTN)
316 error(badexport);
317 else
318 attrib(n, N_EXPORT);
321 else
322 namscan(printexp);
324 break;
326 case SYSEVAL:
327 if (a1)
328 execexp(a1, &argv[2]);
329 break;
331 #ifndef RES
332 case SYSULIMIT:
333 sysulimit(argc, argv);
334 break;
336 case SYSUMASK:
337 if (a1)
339 int c;
340 mode_t i;
342 i = 0;
343 while ((c = *a1++) >= '0' && c <= '7')
344 i = (i << 3) + c - '0';
345 umask(i);
347 else
349 mode_t i;
350 int j;
352 umask(i = umask(0));
353 prc_buff('0');
354 for (j = 6; j >= 0; j -= 3)
355 prc_buff(((i >> j) & 07) +'0');
356 prc_buff(NL);
358 break;
360 #endif
362 case SYSTST:
363 exitval = test(argc, argv);
364 break;
366 case SYSECHO:
367 exitval = echo(argc, argv);
368 break;
370 case SYSHASH:
371 exitval = 0;
373 if (a1)
375 if (a1[0] == '-')
377 if (a1[1] == 'r')
378 zaphash();
379 else
380 error(badopt);
382 else
384 while (*++argv)
386 if (hashtype(hash_cmd(*argv)) == NOTFOUND)
387 failed(*argv, notfound);
391 else
392 hashpr();
394 break;
396 case SYSPWD:
398 exitval = 0;
399 cwdprint();
401 break;
403 case SYSRETURN:
404 if (funcnt == 0)
405 error(badreturn);
407 execbrk = 1;
408 exitval = (a1 ? stoi(a1) : retval);
409 break;
411 case SYSTYPE:
412 exitval = 0;
413 if (a1)
415 /* return success only if all names are found */
416 while (*++argv)
417 exitval |= what_is_path(*argv);
419 break;
421 case SYSUNS:
422 exitval = 0;
423 if (a1)
425 while (*++argv)
426 unset_name(*argv);
428 break;
430 case SYSGETOPT: {
431 int getoptval;
432 struct namnod *n;
433 extern unsigned char numbuf[];
434 unsigned char *varnam = argv[2];
435 unsigned char c[2];
436 if(argc < 3) {
437 failure(argv[0],mssgargn);
438 break;
440 exitval = 0;
441 n = lookup("OPTIND");
442 optind = stoi(n->namval);
443 if(argc > 3) {
444 argv[2] = dolv[0];
445 getoptval = getopt(argc-2, (char **)&argv[2], (char *)argv[1]);
447 else
448 getoptval = getopt(dolc+1, (char **)dolv, (char *)argv[1]);
449 if(getoptval == -1) {
450 itos(optind);
451 assign(n, numbuf);
452 n = lookup(varnam);
453 assign(n, (unsigned char *)nullstr);
454 exitval = 1;
455 break;
457 argv[2] = varnam;
458 itos(optind);
459 assign(n, numbuf);
460 c[0] = getoptval;
461 c[1] = 0;
462 n = lookup(varnam);
463 assign(n, c);
464 n = lookup("OPTARG");
465 assign(n, (unsigned char *)optarg);
467 break;
469 default:
470 prs_buff(_gettext("unknown builtin\n"));
474 flushb();
475 restore(index);
476 chktrap();