* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
static char *sccsid
= "@(#)func.c 5.5 (Berkeley) %G%";
register char *cp
= t
->t_dcom
[0];
register struct biltins
*bp
, *bp1
, *bp2
;
int dolabel(), dofg1(), dobg1();
static struct biltins label
= { "", dolabel
, 0, 0 };
static struct biltins foregnd
= { "%job", dofg1
, 0, 0 };
static struct biltins backgnd
= { "%job &", dobg1
, 0, 0 };
if (lastchr(cp
) == ':') {
* Bp1 is the beginning of the current search range.
* Bp2 is one past the end.
for (bp1
= bfunc
, bp2
= bfunc
+ nbfunc
; bp1
< bp2
;) {
bp
= bp1
+ (bp2
- bp1
>> 1);
if ((i
= *cp
- *bp
->bname
) == 0 &&
(i
= strcmp(cp
, bp
->bname
)) == 0)
register struct command
*t
;
register struct biltins
*bp
;
i
= blklen(t
->t_dcom
) - 1;
bferr("Too few arguments");
bferr("Too many arguments");
(*bp
->bfunct
)(t
->t_dcom
, t
);
register char *vv
= v
[1];
bferr("Can't from terminal");
cp
= gointr
, gointr
= 0, xfree(cp
);
(void) sigblock(sigmask(SIGINT
));
(void) signal(SIGINT
, SIG_DFL
);
} else if (eq((vv
= strip(vv
)), "-")) {
(void) signal(SIGINT
, SIG_IGN
);
(void) signal(SIGINT
, pintr
);
bferr("Can't from terminal");
(void) signal(SIGHUP
, SIG_IGN
);
register struct varent
*vp
;
vp
= adrof1(strip(p
), &aliases
);
blkpr(vp
->vec
), printf("\n");
if (eq(p
, "alias") || eq(p
, "unalias")) {
bferr("Too dangerous to alias that");
set1(strip(p
), saveblk(v
), &aliases
);
(void) signal(SIGTERM
, parterm
);
execl("/bin/login", "login", v
[1], 0);
if (chkstop
== 0 && setintr
)
(void) signal(SIGTERM
, parterm
);
execl("/bin/newgrp", "newgrp", v
[1], 0);
execl("/usr/bin/newgrp", "newgrp", v
[1], 0);
if (chkstop
== 0 && setintr
)
error("Not login shell");
* If expression was zero, then scan to else,
* otherwise just fall into following code.
* Simple command attached to this if.
* Left shift the node in this tree, munging it
* so we can reexecute it.
lshift(kp
->t_dcom
, vv
- kp
->t_dcom
);
* Reexecute a command, being careful not
* to redo i/o redirection, which is already set up.
register struct command
*kp
;
* If tty is still ours to arbitrate, arbitrate it;
* otherwise dont even set pgrp's as the jobs would
* then have no way to get the tty (we can't give it
* to them, and our parent wouldn't know their pgrp, etc.
execute(kp
, tpgrp
> 0 ? tpgrp
: -1);
register struct whyle
*wp
;
* While we still can, locate any unknown ends of existing loops.
* This obscure code is the WORST result of the fact that we
for (wp
= whyles
; wp
; wp
= wp
->w_next
)
search(ZGOTO
, 0, lp
= globone(v
[1]));
* Eliminate loops which were exited.
if (!*v
|| *(*v
++) != '(')
cp
= **v
== ')' ? "" : *v
++;
search(ZSWITCH
, 0, lp
= globone(cp
));
bferr("Not in while/foreach");
* Don't DEMAND parentheses here either.
set("status", putn(exp(&v
)));
bferr("Expression syntax");
register struct whyle
*nwp
;
while (*cp
&& letter(*cp
))
if (*cp
|| strlen(*v
) >= 20)
bferr("Invalid variable");
if (v
[0][0] != '(' || v
[blklen(v
) - 1][0] != ')')
bferr("Words not ()'ed");
nwp
= (struct whyle
*) calloc(1, sizeof *nwp
);
nwp
->w_fe
= nwp
->w_fe0
= v
; gargv
= 0;
nwp
->w_fename
= savestr(cp
);
* Pre-read the loop so as to be more
* comprehensible to a terminal user.
register bool again
= whyles
!= 0 && whyles
->w_start
== lineloc
&&
* Implement prereading here also, taking care not to
* evaluate the expression before the loop has been read up
bferr("Expression syntax");
register struct whyle
*nwp
= (struct whyle
*) calloc(1, sizeof (*nwp
));
/* We ain't gonna loop no more, no more! */
(void) sigsetmask(sigblock(0L) & ~sigmask(SIGINT
));
(void) sigblock(sigmask(SIGINT
));
bferr("Not in while/foreach");
bferr("Not in while/foreach");
/* Repeating a while is simple */
if (whyles
->w_fename
== 0) {
* The foreach variable list actually has a spurious word
* ")" at the end of the w_fe list. Thus we are at the
* of the list if one word beyond this is 0.
set(whyles
->w_fename
, savestr(*whyles
->w_fe
++));
omask
= sigblock(sigmask(SIGINT
)) & ~sigmask(SIGINT
);
(void) sigsetmask(omask
);
(void) sigsetmask(omask
);
register struct srch
*sp
, *sp1
, *sp2
;
* Sp1 is the beginning of the current search range.
* Sp2 is one past the end.
for (sp1
= srchn
, sp2
= srchn
+ nsrchn
; sp1
< sp2
;) {
sp
= sp1
+ (sp2
- sp1
>> 1);
if ((i
= *cp
- *sp
->s_name
) == 0 &&
(i
= strcmp(cp
, sp
->s_name
)) == 0)
search(type
, level
, goal
)
register char *aword
= wordbuf
;
Stype
= type
; Sgoal
= goal
;
if (intty
&& fseekp
== feobp
)
if (level
== 0 && type
== ZIF
)
if ((type
== ZIF
|| type
== ZELSE
) && eq(aword
, "then"))
if (type
== ZIF
|| type
== ZELSE
)
if (type
== ZSWITCH
|| type
== ZBRKSW
)
if (type
== ZSWITCH
|| type
== ZBRKSW
)
if (type
== ZGOTO
&& getword(aword
) && eq(aword
, goal
))
if (type
!= ZGOTO
&& (type
!= ZSWITCH
|| level
!= 0))
if (lastchr(aword
) != ':')
aword
[strlen(aword
) - 1] = 0;
if (type
== ZGOTO
&& eq(aword
, goal
) || type
== ZSWITCH
&& eq(aword
, "default"))
if (type
!= ZSWITCH
|| level
!= 0)
if (lastchr(aword
) == ':')
aword
[strlen(aword
) - 1] = 0;
cp
= strip(Dfix1(aword
));
if (type
== ZSWITCH
&& level
== 0)
while (c
== ' ' || c
== '\t')
while (c
>= 0 && c
!= '\n');
if (c
== '\\' && (c
= readc(1)) == '\n')
if (c
== '\'' || c
== '"')
} while ((d
|| c
!= ' ' && c
!= '\t') && c
!= '\n');
bferr("then/endif not found");
bferr("endif not found");
bferr("endsw not found");
bferr("label not found");
if (whyles
->w_end
== 0) {
whyles
->w_end
= btell() - 1;
register struct whyle
*wp
= whyles
;
register struct whyle
*nwp
= wp
->w_next
;
if (o
>= wp
->w_start
&& (wp
->w_end
== 0 || o
< wp
->w_end
))
(void) sigsetmask(sigblock(0L) & ~sigmask(SIGINT
));
if (sep
== ' ' && *v
&& !strcmp(*v
, "-n"))
(void) sigblock(sigmask(SIGINT
));
blkfree(gargv
), gargv
= 0;
(void) sigsetmask(sigblock(0L) & ~ sigmask(SIGINT
));
for (ep
= environ
; *ep
; ep
++)
setenv(vp
, lp
= globone(lp
));
register char **ep
= environ
;
char *blk
[2], **oep
= ep
;
for (cp
= name
, dp
= *ep
; *cp
&& *cp
== *dp
; cp
++, dp
++)
if (*cp
!= 0 || *dp
!= '=')
blk
[0] = strspl(name
, "="); blk
[1] = 0;
environ
= blkspl(environ
, blk
);
register char **ep
= environ
;
for (cp
= name
, dp
= *ep
; *cp
&& *cp
== *dp
; cp
++, dp
++)
if (*cp
!= 0 || *dp
!= '=')
environ
= blkspl(environ
, ep
+1);
register char *cp
= v
[1];
while (digit(*cp
) && *cp
!= '8' && *cp
!= '9')
if (*cp
|| i
< 0 || i
> 0777)
RLIMIT_CPU
, "cputime", 1, "seconds",
RLIMIT_FSIZE
, "filesize", 1024, "kbytes",
RLIMIT_DATA
, "datasize", 1024, "kbytes",
RLIMIT_STACK
, "stacksize", 1024, "kbytes",
RLIMIT_CORE
, "coredumpsize", 1024, "kbytes",
RLIMIT_RSS
, "memoryuse", 1024, "kbytes",
register struct limits
*lp
, *res
;
for (lp
= limits
; lp
->limconst
>= 0; lp
++)
if (prefix(cp
, lp
->limname
)) {
register struct limits
*lp
;
if (*v
&& eq(*v
, "-h")) {
for (lp
= limits
; lp
->limconst
>= 0; lp
++)
if (setlim(lp
, hard
, limit
) < 0)
register struct limits
*lp
;
while (digit(*cp
) || *cp
== '.' || *cp
== 'e' || *cp
== 'E')
return ((int)(f
+0.5) * lp
->limdiv
);
if (lp
->limconst
!= RLIMIT_CPU
)
return ((int)(f
* 60.0 + atof(cp
+1)));
if (lp
->limconst
!= RLIMIT_CPU
)
if (lp
->limconst
== RLIMIT_CPU
) {
if (lp
->limconst
== RLIMIT_CPU
)
limtail(cp
, "megabytes");
if (lp
->limconst
!= RLIMIT_CPU
)
if (lp
->limconst
== RLIMIT_CPU
)
limtail(cp
, "unlimited");
bferr("Improper or unknown scale factor");
register char *str
= str0
;
while (*cp
&& *cp
== *str
)
error("Bad scaling; did you mean ``%s''?", str0
);
register struct limits
*lp
;
printf("%s \t", lp
->limname
);
(void) getrlimit(lp
->limconst
, &rlim
);
limit
= hard
? rlim
.rlim_max
: rlim
.rlim_cur
;
if (limit
== RLIM_INFINITY
)
else if (lp
->limconst
== RLIMIT_CPU
)
printf("%d %s", limit
/ lp
->limdiv
, lp
->limscale
);
register struct limits
*lp
;
if (*v
&& eq(*v
, "-h")) {
for (lp
= limits
; lp
->limconst
>= 0; lp
++)
if (setlim(lp
, hard
, (int)RLIM_INFINITY
) < 0)
if (setlim(lp
, hard
, (int)RLIM_INFINITY
) < 0)
register struct limits
*lp
;
(void) getrlimit(lp
->limconst
, &rlim
);
else if (limit
== RLIM_INFINITY
&& geteuid() != 0)
rlim
.rlim_cur
= rlim
.rlim_max
;
if (setrlimit(lp
->limconst
, &rlim
) < 0) {
printf("%s: %s: Can't %s%s limit\n", bname
, lp
->limname
,
limit
== RLIM_INFINITY
? "remove" : "set",
error("Can't suspend a login shell (yet)");
old
= signal(SIGTSTP
, SIG_DFL
);
/* the shell stops here */
(void) signal(SIGTSTP
, old
);
(void) ioctl(FSHTTY
, TIOCGPGRP
, (char *)&ctpgrp
);
old
= signal(SIGTTIN
, SIG_DFL
);
(void) signal(SIGTTIN
, old
);
(void) ioctl(FSHTTY
, TIOCSPGRP
, (char *)&shpgrp
);
(void) setpgrp(0, shpgrp
);
(void) ioctl(FSHTTY
, TIOCGETD
, (char *)&oldisc
);
if (oldisc
!= NTTYDISC
) {
printf("Switching to new tty driver...\n");
(void) ioctl(FSHTTY
, TIOCSETD
, (char *)&ldisc
);
char **oevalvec
= evalvec
;