diff options
Diffstat (limited to 'usr/src/cmd/sh/bltin.c')
| -rw-r--r-- | usr/src/cmd/sh/bltin.c | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/usr/src/cmd/sh/bltin.c b/usr/src/cmd/sh/bltin.c new file mode 100644 index 0000000000..ec84f7cf06 --- /dev/null +++ b/usr/src/cmd/sh/bltin.c @@ -0,0 +1,480 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + +/* + * Copyright (c) 1996, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.3.8.1 */ +/* + * + * UNIX shell + * + */ + + +#include "defs.h" +#include <errno.h> +#include "sym.h" +#include "hash.h" +#include <sys/types.h> +#include <sys/times.h> + +builtin(type, argc, argv, t) +int type, argc; +unsigned char **argv; +struct trenod *t; +{ + short index = initio(t->treio, (type != SYSEXEC)); + unsigned char *a1 = argv[1]; + + switch (type) + { + + case SYSSUSP: + syssusp(argc,argv); + break; + + case SYSSTOP: + sysstop(argc,argv); + break; + + case SYSKILL: + syskill(argc,argv); + break; + + case SYSFGBG: + sysfgbg(argc,argv); + break; + + case SYSJOBS: + sysjobs(argc,argv); + break; + + case SYSDOT: + if (a1) + { + register int f; + + if ((f = pathopen(getpath(a1), a1)) < 0) + failed(a1, notfound); + else + execexp(0, f); + } + break; + + case SYSTIMES: + { + struct tms tms; + + times(&tms); + prt(tms.tms_cutime); + prc_buff(SPACE); + prt(tms.tms_cstime); + prc_buff(NL); + } + break; + + case SYSEXIT: + if ( tried_to_exit++ || endjobs(JOB_STOPPED) ){ + flags |= forcexit; /* force exit */ + exitsh(a1 ? stoi(a1) : retval); + } + break; + + case SYSNULL: + t->treio = 0; + break; + + case SYSCONT: + if (loopcnt) + { + execbrk = breakcnt = 1; + if (a1) + breakcnt = stoi(a1); + if (breakcnt > loopcnt) + breakcnt = loopcnt; + else + breakcnt = -breakcnt; + } + break; + + case SYSBREAK: + if (loopcnt) + { + execbrk = breakcnt = 1; + if (a1) + breakcnt = stoi(a1); + if (breakcnt > loopcnt) + breakcnt = loopcnt; + } + break; + + case SYSTRAP: + systrap(argc,argv); + break; + + case SYSEXEC: + argv++; + ioset = 0; + if (a1 == 0) { + setmode(0); + break; + } + /* FALLTHROUGH */ + +#ifdef RES /* Research includes login as part of the shell */ + + case SYSLOGIN: + if (!endjobs(JOB_STOPPED|JOB_RUNNING)) + break; + oldsigs(); + execa(argv, -1); + done(0); +#else + + case SYSNEWGRP: + if (flags & rshflg) + failed(argv[0], restricted); + else if (!endjobs(JOB_STOPPED|JOB_RUNNING)) + break; + else + { + flags |= forcexit; /* bad exec will terminate shell */ + oldsigs(); + rmtemp(0); + rmfunctmp(); +#ifdef ACCT + doacct(); +#endif + execa(argv, -1); + done(0); + } + +#endif + + case SYSCD: + if (flags & rshflg) + failed(argv[0], restricted); + else if ((a1 && *a1) || (a1 == 0 && (a1 = homenod.namval))) + { + unsigned char *cdpath; + unsigned char *dir; + int f; + + if ((cdpath = cdpnod.namval) == 0 || + *a1 == '/' || + cf(a1, ".") == 0 || + cf(a1, "..") == 0 || + (*a1 == '.' && (*(a1+1) == '/' || *(a1+1) == '.' && *(a1+2) == '/'))) + cdpath = (unsigned char *)nullstr; + + do + { + dir = cdpath; + cdpath = catpath(cdpath,a1); + } + while ((f = (chdir((const char *) curstak()) < 0)) && + cdpath); + + if (f) { + switch(errno) { + case EMULTIHOP: + failed(a1, emultihop); + break; + case ENOTDIR: + failed(a1, enotdir); + break; + case ENOENT: + failed(a1, enoent); + break; + case EACCES: + failed(a1, eacces); + break; + case ENOLINK: + failed(a1, enolink); + break; + default: + failed(a1, baddir); + break; + } + } + else + { + cwd(curstak()); + if (cf(nullstr, dir) && + *dir != ':' && + any('/', curstak()) && + flags & prompt) + { + prs_buff(cwdget()); + prc_buff(NL); + } + } + zapcd(); + } + else + { + if (a1) + error(nulldir); + else + error(nohome); + } + + break; + + case SYSSHFT: + { + int places; + + places = a1 ? stoi(a1) : 1; + + if ((dolc -= places) < 0) + { + dolc = 0; + error(badshift); + } + else + dolv += places; + } + + break; + + case SYSWAIT: + syswait(argc,argv); + break; + + case SYSREAD: + if(argc < 2) + failed(argv[0],mssgargn); + rwait = 1; + exitval = readvar(&argv[1]); + rwait = 0; + break; + + case SYSSET: + if (a1) + { + int cnt; + + cnt = options(argc, argv); + if (cnt > 1) + setargs(argv + argc - cnt); + } + else if (comptr(t)->comset == 0) + { + /* + * scan name chain and print + */ + namscan(printnam); + } + break; + + case SYSRDONLY: + exitval = 0; + if (a1) + { + while (*++argv) + attrib(lookup(*argv), N_RDONLY); + } + else + namscan(printro); + + break; + + case SYSXPORT: + { + struct namnod *n; + + exitval = 0; + if (a1) + { + while (*++argv) + { + n = lookup(*argv); + if (n->namflg & N_FUNCTN) + error(badexport); + else + attrib(n, N_EXPORT); + } + } + else + namscan(printexp); + } + break; + + case SYSEVAL: + if (a1) + execexp(a1, &argv[2]); + break; + +#ifndef RES + case SYSULIMIT: + sysulimit(argc, argv); + break; + + case SYSUMASK: + if (a1) + { + int c; + mode_t i; + + i = 0; + while ((c = *a1++) >= '0' && c <= '7') + i = (i << 3) + c - '0'; + umask(i); + } + else + { + mode_t i; + int j; + + umask(i = umask(0)); + prc_buff('0'); + for (j = 6; j >= 0; j -= 3) + prc_buff(((i >> j) & 07) +'0'); + prc_buff(NL); + } + break; + +#endif + + case SYSTST: + exitval = test(argc, argv); + break; + + case SYSECHO: + exitval = echo(argc, argv); + break; + + case SYSHASH: + exitval = 0; + + if (a1) + { + if (a1[0] == '-') + { + if (a1[1] == 'r') + zaphash(); + else + error(badopt); + } + else + { + while (*++argv) + { + if (hashtype(hash_cmd(*argv)) == NOTFOUND) + failed(*argv, notfound); + } + } + } + else + hashpr(); + + break; + + case SYSPWD: + { + exitval = 0; + cwdprint(); + } + break; + + case SYSRETURN: + if (funcnt == 0) + error(badreturn); + + execbrk = 1; + exitval = (a1 ? stoi(a1) : retval); + break; + + case SYSTYPE: + exitval = 0; + if (a1) + { + /* return success only if all names are found */ + while (*++argv) + exitval |= what_is_path(*argv); + } + break; + + case SYSUNS: + exitval = 0; + if (a1) + { + while (*++argv) + unset_name(*argv); + } + break; + + case SYSGETOPT: { + int getoptval; + struct namnod *n; + extern unsigned char numbuf[]; + unsigned char *varnam = argv[2]; + unsigned char c[2]; + if(argc < 3) { + failure(argv[0],mssgargn); + break; + } + exitval = 0; + n = lookup("OPTIND"); + optind = stoi(n->namval); + if(argc > 3) { + argv[2] = dolv[0]; + getoptval = getopt(argc-2, (char **)&argv[2], (char *)argv[1]); + } + else + getoptval = getopt(dolc+1, (char **)dolv, (char *)argv[1]); + if(getoptval == -1) { + itos(optind); + assign(n, numbuf); + n = lookup(varnam); + assign(n, nullstr); + exitval = 1; + break; + } + argv[2] = varnam; + itos(optind); + assign(n, numbuf); + c[0] = getoptval; + c[1] = 0; + n = lookup(varnam); + assign(n, c); + n = lookup("OPTARG"); + assign(n, optarg); + } + break; + + default: + prs_buff("unknown builtin\n"); + } + + + flushb(); + restore(index); + chktrap(); +} |
