summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/sh.func.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcsh/sh.func.c')
-rw-r--r--contrib/tcsh/sh.func.c944
1 files changed, 428 insertions, 516 deletions
diff --git a/contrib/tcsh/sh.func.c b/contrib/tcsh/sh.func.c
index b77dcca..92e2447 100644
--- a/contrib/tcsh/sh.func.c
+++ b/contrib/tcsh/sh.func.c
@@ -1,4 +1,4 @@
-/* $Header: /src/pub/tcsh/sh.func.c,v 3.126 2005/03/20 06:35:48 christos Exp $ */
+/* $Header: /p/tcsh/cvsroot/tcsh/sh.func.c,v 3.143 2006/08/24 20:56:31 christos Exp $ */
/*
* sh.func.c: csh builtin functions
*/
@@ -32,7 +32,7 @@
*/
#include "sh.h"
-RCSID("$Id: sh.func.c,v 3.126 2005/03/20 06:35:48 christos Exp $")
+RCSID("$tcsh: sh.func.c,v 3.143 2006/08/24 20:56:31 christos Exp $")
#include "ed.h"
#include "tw.h"
@@ -41,18 +41,14 @@ RCSID("$Id: sh.func.c,v 3.126 2005/03/20 06:35:48 christos Exp $")
#include "nt.const.h"
#endif /* WINNT_NATIVE */
-#ifdef NLS_CATALOGS
-#ifdef HAVE_ICONV
+#if defined (NLS_CATALOGS) && defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO)
#include <langinfo.h>
static iconv_t catgets_iconv; /* Or (iconv_t)-1 */
#endif
-#endif
/*
* C shell
*/
-extern int just_signaled;
-extern char **environ;
extern int MapsAreInited;
extern int NLSMapsAreInited;
@@ -60,23 +56,22 @@ extern int GotTermCaps;
static int zlast = -1;
-static void islogin __P((void));
-static void preread __P((void));
-static void doagain __P((void));
-static const char *isrchx __P((int));
-static void search __P((int, int, Char *));
-static int getword __P((Char *));
-static void toend __P((void));
-static void xecho __P((int, Char **));
-static int islocale_var __P((Char *));
-static void wpfree __P((struct whyle *));
-
-struct biltins *
-isbfunc(t)
- struct command *t;
+static void islogin (void);
+static void preread (void);
+static void doagain (void);
+static const char *isrchx (int);
+static void search (int, int, Char *);
+static int getword (struct Strbuf *);
+static void toend (void);
+static void xecho (int, Char **);
+static int islocale_var (Char *);
+static void wpfree (struct whyle *);
+
+const struct biltins *
+isbfunc(struct command *t)
{
Char *cp = t->t_dcom[0];
- struct biltins *bp, *bp1, *bp2;
+ const struct biltins *bp, *bp1, *bp2;
static struct biltins label = {"", dozip, 0, 0};
static struct biltins foregnd = {"%job", dofg1, 0, 0};
static struct biltins backgnd = {"%job &", dobg1, 0, 0};
@@ -136,9 +131,7 @@ isbfunc(t)
}
void
-func(t, bp)
- struct command *t;
- struct biltins *bp;
+func(struct command *t, const struct biltins *bp)
{
int i;
@@ -154,62 +147,39 @@ func(t, bp)
/*ARGSUSED*/
void
-doonintr(v, c)
- Char **v;
- struct command *c;
+doonintr(Char **v, struct command *c)
{
Char *cp;
Char *vv = v[1];
USE(c);
- if (parintr == SIG_IGN)
+ if (parintr.sa_handler == SIG_IGN)
return;
if (setintr && intty)
stderror(ERR_NAME | ERR_TERMINAL);
cp = gointr;
gointr = 0;
- xfree((ptr_t) cp);
+ xfree(cp);
if (vv == 0) {
-#ifdef BSDSIGS
- if (setintr) {
- (void) sigblock(sigmask(SIGINT));
- (void) signal(SIGINT, pintr);
- }
- else
- (void) signal(SIGINT, SIG_DFL);
-#else /* !BSDSIGS */
- if (setintr) {
- (void) sighold(SIGINT);
- (void) sigset(SIGINT, pintr);
- }
+ if (setintr)
+ sigset_interrupting(SIGINT, queue_pintr);
else
- (void) sigset(SIGINT, SIG_DFL);
-#endif /* BSDSIGS */
+ (void) signal(SIGINT, SIG_DFL);
gointr = 0;
}
else if (eq((vv = strip(vv)), STRminus)) {
-#ifdef BSDSIGS
(void) signal(SIGINT, SIG_IGN);
-#else /* !BSDSIGS */
- (void) sigset(SIGINT, SIG_IGN);
-#endif /* BSDSIGS */
gointr = Strsave(STRminus);
}
else {
gointr = Strsave(vv);
-#ifdef BSDSIGS
- (void) signal(SIGINT, pintr);
-#else /* !BSDSIGS */
- (void) sigset(SIGINT, pintr);
-#endif /* BSDSIGS */
+ sigset_interrupting(SIGINT, queue_pintr);
}
}
/*ARGSUSED*/
void
-donohup(v, c)
- Char **v;
- struct command *c;
+donohup(Char **v, struct command *c)
{
USE(c);
USE(v);
@@ -217,6 +187,7 @@ donohup(v, c)
stderror(ERR_NAME | ERR_TERMINAL);
if (setintr == 0) {
(void) signal(SIGHUP, SIG_IGN);
+ phup_disabled = 1;
#ifdef CC
submit(getpid());
#endif /* CC */
@@ -225,9 +196,7 @@ donohup(v, c)
/*ARGSUSED*/
void
-dohup(v, c)
- Char **v;
- struct command *c;
+dohup(Char **v, struct command *c)
{
USE(c);
USE(v);
@@ -240,9 +209,7 @@ dohup(v, c)
/*ARGSUSED*/
void
-dozip(v, c)
- Char **v;
- struct command *c;
+dozip(Char **v, struct command *c)
{
USE(c);
USE(v);
@@ -250,53 +217,41 @@ dozip(v, c)
/*ARGSUSED*/
void
-dofiletest(v, c)
- Char **v;
- struct command *c;
+dofiletest(Char **v, struct command *c)
{
- Char **fileptr, *ftest, *res;
+ Char **globbed, **fileptr, *ftest, *res;
USE(c);
if (*(ftest = *++v) != '-')
stderror(ERR_NAME | ERR_FILEINQ);
++v;
- gflag = 0;
- tglob(v);
- if (gflag) {
- v = globall(v);
- if (v == 0)
- stderror(ERR_NAME | ERR_NOMATCH);
- }
- else
- v = gargv = saveblk(v);
- trim(v);
+ v = glob_all_or_error(v);
+ globbed = v;
+ cleanup_push(globbed, blk_cleanup);
while (*(fileptr = v++) != '\0') {
- xprintf("%S", res = filetest(ftest, &fileptr, 0));
- xfree((ptr_t) res);
+ res = filetest(ftest, &fileptr, 0);
+ cleanup_push(res, xfree);
+ xprintf("%S", res);
+ cleanup_until(res);
if (*v)
xprintf(" ");
}
xprintf("\n");
- if (gargv) {
- blkfree(gargv);
- gargv = 0;
- }
+ cleanup_until(globbed);
}
void
-prvars()
+prvars(void)
{
plist(&shvhed, VAR_ALL);
}
/*ARGSUSED*/
void
-doalias(v, c)
- Char **v;
- struct command *c;
+doalias(Char **v, struct command *c)
{
struct varent *vp;
Char *p;
@@ -323,9 +278,7 @@ doalias(v, c)
/*ARGSUSED*/
void
-unalias(v, c)
- Char **v;
- struct command *c;
+unalias(Char **v, struct command *c)
{
USE(c);
unset1(v, &aliases);
@@ -334,9 +287,7 @@ unalias(v, c)
/*ARGSUSED*/
void
-dologout(v, c)
- Char **v;
- struct command *c;
+dologout(Char **v, struct command *c)
{
USE(c);
USE(v);
@@ -346,22 +297,22 @@ dologout(v, c)
/*ARGSUSED*/
void
-dologin(v, c)
- Char **v;
- struct command *c;
+dologin(Char **v, struct command *c)
{
#ifdef WINNT_NATIVE
USE(c);
USE(v);
#else /* !WINNT_NATIVE */
char **p = short2blk(v);
+
USE(c);
+ cleanup_push((Char **)p, blk_cleanup);
islogin();
rechist(NULL, adrof(STRsavehist) != NULL);
- (void) signal(SIGTERM, parterm);
+ sigaction(SIGTERM, &parterm, NULL);
(void) execv(_PATH_BIN_LOGIN, p);
(void) execv(_PATH_USRBIN_LOGIN, p);
- blkfree((Char **) p);
+ cleanup_until((Char **)p);
untty();
xexit(1);
#endif /* !WINNT_NATIVE */
@@ -371,14 +322,12 @@ dologin(v, c)
#ifdef NEWGRP
/*ARGSUSED*/
void
-donewgrp(v, c)
- Char **v;
- struct command *c;
+donewgrp(Char **v, struct command *c)
{
char **p;
if (chkstop == 0 && setintr)
panystop(0);
- (void) signal(SIGTERM, parterm);
+ sigaction(SIGTERM, &parterm, NULL);
p = short2blk(v);
/*
* From Beto Appleton (beto@aixwiz.austin.ibm.com)
@@ -393,7 +342,7 @@ donewgrp(v, c)
#endif /* NEWGRP */
static void
-islogin()
+islogin(void)
{
if (chkstop == 0 && setintr)
panystop(0);
@@ -403,15 +352,13 @@ islogin()
}
void
-doif(v, kp)
- Char **v;
- struct command *kp;
+doif(Char **v, struct command *kp)
{
int i;
Char **vv;
v++;
- i = expr(&v);
+ i = noexec ? 1 : expr(&v);
vv = v;
if (*vv == NULL)
stderror(ERR_NAME | ERR_EMPTYIF);
@@ -443,8 +390,7 @@ doif(v, kp)
* to redo i/o redirection, which is already set up.
*/
void
-reexecute(kp)
- struct command *kp;
+reexecute(struct command *kp)
{
kp->t_dflg &= F_SAVE;
kp->t_dflg |= F_REPEAT;
@@ -458,31 +404,30 @@ reexecute(kp)
/*ARGSUSED*/
void
-doelse (v, c)
- Char **v;
- struct command *c;
+doelse (Char **v, struct command *c)
{
USE(c);
USE(v);
- search(TC_ELSE, 0, NULL);
+ if (!noexec)
+ search(TC_ELSE, 0, NULL);
}
/*ARGSUSED*/
void
-dogoto(v, c)
- Char **v;
- struct command *c;
+dogoto(Char **v, struct command *c)
{
Char *lp;
USE(c);
- gotolab(lp = globone(v[1], G_ERROR));
- xfree((ptr_t) lp);
+ lp = globone(v[1], G_ERROR);
+ cleanup_push(lp, xfree);
+ if (!noexec)
+ gotolab(lp);
+ cleanup_until(lp);
}
void
-gotolab(lab)
- Char *lab;
+gotolab(Char *lab)
{
struct whyle *wp;
/*
@@ -507,9 +452,7 @@ gotolab(lab)
/*ARGSUSED*/
void
-doswitch(v, c)
- Char **v;
- struct command *c;
+doswitch(Char **v, struct command *c)
{
Char *cp, *lp;
@@ -522,29 +465,28 @@ doswitch(v, c)
v--;
if (*v)
stderror(ERR_SYNTAX);
- search(TC_SWITCH, 0, lp = globone(cp, G_ERROR));
- xfree((ptr_t) lp);
+ lp = globone(cp, G_ERROR);
+ cleanup_push(lp, xfree);
+ if (!noexec)
+ search(TC_SWITCH, 0, lp);
+ cleanup_until(lp);
}
/*ARGSUSED*/
void
-dobreak(v, c)
- Char **v;
- struct command *c;
+dobreak(Char **v, struct command *c)
{
USE(v);
USE(c);
- if (whyles)
- toend();
- else
+ if (whyles == NULL)
stderror(ERR_NAME | ERR_NOTWHILE);
+ if (!noexec)
+ toend();
}
/*ARGSUSED*/
void
-doexit(v, c)
- Char **v;
- struct command *c;
+doexit(Char **v, struct command *c)
{
USE(c);
@@ -555,7 +497,7 @@ doexit(v, c)
*/
v++;
if (*v) {
- set(STRstatus, putn(expr(&v)), VAR_READWRITE);
+ setv(STRstatus, putn(expr(&v)), VAR_READWRITE);
if (*v)
stderror(ERR_NAME | ERR_EXPRESSION);
}
@@ -564,17 +506,16 @@ doexit(v, c)
if (intty)
#endif
/* Always close, why only on ttys? */
- (void) close(SHIN);
+ xclose(SHIN);
}
/*ARGSUSED*/
void
-doforeach(v, c)
- Char **v;
- struct command *c;
+doforeach(Char **v, struct command *c)
{
Char *cp, *sp;
struct whyle *nwp;
+ int gflag;
USE(c);
v++;
@@ -585,25 +526,22 @@ doforeach(v, c)
cp++;
if (*cp)
stderror(ERR_NAME | ERR_VARALNUM);
- if ((cp - sp) > MAXVARLEN)
- stderror(ERR_NAME | ERR_VARTOOLONG);
cp = *v++;
if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')')
stderror(ERR_NAME | ERR_NOPAREN);
v++;
- gflag = 0, tglob(v);
+ gflag = tglob(v);
if (gflag) {
- v = globall(v);
- if (v == 0)
+ v = globall(v, gflag);
+ if (v == 0 && !noexec)
stderror(ERR_NAME | ERR_NOMATCH);
}
else {
- v = gargv = saveblk(v);
+ v = saveblk(v);
trim(v);
}
- nwp = (struct whyle *) xcalloc(1, sizeof *nwp);
+ nwp = xcalloc(1, sizeof *nwp);
nwp->w_fe = nwp->w_fe0 = v;
- gargv = 0;
btell(&nwp->w_start);
nwp->w_fename = Strsave(cp);
nwp->w_next = whyles;
@@ -615,14 +553,13 @@ doforeach(v, c)
zlast = TC_FOREACH;
if (intty)
preread();
- doagain();
+ if (!noexec)
+ doagain();
}
/*ARGSUSED*/
void
-dowhile(v, c)
- Char **v;
- struct command *c;
+dowhile(Char **v, struct command *c)
{
int status;
int again = whyles != 0 &&
@@ -635,15 +572,16 @@ dowhile(v, c)
* Implement prereading here also, taking care not to evaluate the
* expression before the loop has been read up from a terminal.
*/
- if (intty && !again)
+ if (noexec)
+ status = 0;
+ else if (intty && !again)
status = !exp0(&v, 1);
else
status = !expr(&v);
- if (*v)
+ if (*v && !noexec)
stderror(ERR_NAME | ERR_EXPRESSION);
if (!again) {
- struct whyle *nwp =
- (struct whyle *) xcalloc(1, sizeof(*nwp));
+ struct whyle *nwp = xcalloc(1, sizeof(*nwp));
nwp->w_start = lineloc;
nwp->w_end.type = TCSH_F_SEEK;
@@ -666,54 +604,46 @@ dowhile(v, c)
}
static void
-preread()
+preread(void)
{
+ int old_pintr_disabled;
+
whyles->w_end.type = TCSH_I_SEEK;
if (setintr)
-#ifdef BSDSIGS
- (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
-#else /* !BSDSIGS */
- (void) sigrelse (SIGINT);
-#endif /* BSDSIGS */
+ pintr_push_enable(&old_pintr_disabled);
search(TC_BREAK, 0, NULL); /* read the expression in */
if (setintr)
-#ifdef BSDSIGS
- (void) sigblock(sigmask(SIGINT));
-#else /* !BSDSIGS */
- (void) sighold(SIGINT);
-#endif /* BSDSIGS */
+ cleanup_until(&old_pintr_disabled);
btell(&whyles->w_end);
}
/*ARGSUSED*/
void
-doend(v, c)
- Char **v;
- struct command *c;
+doend(Char **v, struct command *c)
{
USE(v);
USE(c);
if (!whyles)
stderror(ERR_NAME | ERR_NOTWHILE);
btell(&whyles->w_end);
- doagain();
+ if (!noexec)
+ doagain();
}
/*ARGSUSED*/
void
-docontin(v, c)
- Char **v;
- struct command *c;
+docontin(Char **v, struct command *c)
{
USE(v);
USE(c);
if (!whyles)
stderror(ERR_NAME | ERR_NOTWHILE);
- doagain();
+ if (!noexec)
+ doagain();
}
static void
-doagain()
+doagain(void)
{
/* Repeating a while is simple */
if (whyles->w_fename == 0) {
@@ -729,65 +659,51 @@ doagain()
dobreak(NULL, NULL);
return;
}
- set(whyles->w_fename, quote(Strsave(*whyles->w_fe++)), VAR_READWRITE);
+ setv(whyles->w_fename, quote(Strsave(*whyles->w_fe++)), VAR_READWRITE);
bseek(&whyles->w_start);
}
void
-dorepeat(v, kp)
- Char **v;
- struct command *kp;
+dorepeat(Char **v, struct command *kp)
{
int i = 1;
-#ifdef BSDSIGS
- sigmask_t omask = 0;
-#endif /* BSDSIGS */
-
do {
i *= getn(v[1]);
lshift(v, 2);
} while (v[0] != NULL && Strcmp(v[0], STRrepeat) == 0);
+ if (noexec)
+ i = 1;
- if (setintr)
-#ifdef BSDSIGS
- omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT);
-#else /* !BSDSIGS */
- (void) sighold(SIGINT);
-#endif /* BSDSIGS */
+ if (setintr) {
+ pintr_disabled++;
+ cleanup_push(&pintr_disabled, disabled_cleanup);
+ }
while (i > 0) {
- if (setintr)
-#ifdef BSDSIGS
- (void) sigsetmask(omask);
-#else /* !BSDSIGS */
- (void) sigrelse (SIGINT);
-#endif /* BSDSIGS */
+ if (setintr && pintr_disabled == 1) {
+ cleanup_until(&pintr_disabled);
+ pintr_disabled++;
+ cleanup_push(&pintr_disabled, disabled_cleanup);
+ }
reexecute(kp);
--i;
}
+ cleanup_until(&pintr_disabled);
donefds();
- if (setintr)
-#ifdef BSDSIGS
- (void) sigsetmask(omask);
-#else /* !BSDSIGS */
- (void) sigrelse (SIGINT);
-#endif /* BSDSIGS */
}
/*ARGSUSED*/
void
-doswbrk(v, c)
- Char **v;
- struct command *c;
+doswbrk(Char **v, struct command *c)
{
USE(v);
USE(c);
- search(TC_BRKSW, 0, NULL);
+ if (!noexec)
+ search(TC_BRKSW, 0, NULL);
}
int
-srchx(cp)
- Char *cp;
+srchx(Char *cp)
{
struct srch *sp, *sp1, *sp2;
int i;
@@ -816,8 +732,7 @@ srchx(cp)
}
static const char *
-isrchx(n)
- int n;
+isrchx(int n)
{
struct srch *sp, *sp2;
@@ -828,22 +743,18 @@ isrchx(n)
}
-static Char Stype;
+static int Stype;
static Char *Sgoal;
static void
-search(type, level, goal)
- int type;
- int level;
- Char *goal;
+search(int type, int level, Char *goal)
{
- Char wordbuf[BUFSIZE];
- Char *aword = wordbuf;
+ struct Strbuf word = Strbuf_INIT;
Char *cp;
struct whyle *wp;
int wlevel = 0;
- Stype = (Char) type;
+ Stype = type;
Sgoal = goal;
if (type == TC_GOTO) {
struct Ain a;
@@ -851,24 +762,25 @@ search(type, level, goal)
a.f_seek = 0;
bseek(&a);
}
+ cleanup_push(&word, Strbuf_cleanup);
do {
if (intty && fseekp == feobp && aret == TCSH_F_SEEK)
printprompt(1, isrchx(type == TC_BREAK ? zlast : type));
/* xprintf("? "), flush(); */
- aword[0] = 0;
- (void) getword(aword);
- switch (srchx(aword)) {
+ (void) getword(&word);
+ Strbuf_terminate(&word);
+ switch (srchx(word.s)) {
case TC_ELSE:
if (level == 0 && type == TC_IF)
- return;
+ goto end;
break;
case TC_IF:
- while (getword(aword))
+ while (getword(&word))
continue;
if ((type == TC_IF || type == TC_ELSE) &&
- eq(aword, STRthen))
+ eq(word.s, STRthen))
level++;
break;
@@ -910,31 +822,32 @@ search(type, level, goal)
break;
case TC_LABEL:
- if (type == TC_GOTO && getword(aword) && eq(aword, goal))
+ if (type == TC_GOTO && getword(&word) && eq(word.s, goal))
level = -1;
break;
default:
if (type != TC_GOTO && (type != TC_SWITCH || level != 0))
break;
- if (lastchr(aword) != ':')
+ if (word.len == 0 || word.s[word.len - 1] != ':')
break;
- aword[Strlen(aword) - 1] = 0;
- if ((type == TC_GOTO && eq(aword, goal)) ||
- (type == TC_SWITCH && eq(aword, STRdefault)))
+ word.s[--word.len] = 0;
+ if ((type == TC_GOTO && eq(word.s, goal)) ||
+ (type == TC_SWITCH && eq(word.s, STRdefault)))
level = -1;
break;
case TC_CASE:
if (type != TC_SWITCH || level != 0)
break;
- (void) getword(aword);
- if (lastchr(aword) == ':')
- aword[Strlen(aword) - 1] = 0;
- cp = strip(Dfix1(aword));
+ (void) getword(&word);
+ if (word.len != 0 && word.s[word.len - 1] == ':')
+ word.s[--word.len] = 0;
+ cp = strip(Dfix1(word.s));
+ cleanup_push(cp, xfree);
if (Gmatch(goal, cp))
level = -1;
- xfree((ptr_t) cp);
+ cleanup_until(cp);
break;
case TC_DEFAULT:
@@ -944,15 +857,18 @@ search(type, level, goal)
}
(void) getword(NULL);
} while (level >= 0);
+ end:
+ cleanup_until(&word);
}
static int
-getword(wp)
- Char *wp;
+getword(struct Strbuf *wp)
{
int found = 0, first;
eChar c, d;
+ if (wp)
+ wp->len = 0;
c = readc(1);
d = 0;
do {
@@ -984,16 +900,11 @@ getword(wp)
}
if (c == CHAR_ERR)
goto past;
- if (wp) {
- *wp++ = (Char) c;
- *wp = '\0';
- }
+ if (wp)
+ Strbuf_append1(wp, (Char) c);
if (!first && !d && c == '(') {
- if (wp) {
- unreadc(c);
- *--wp = '\0';
- return found;
- }
+ if (wp)
+ goto past_word_end;
else
break;
}
@@ -1001,9 +912,12 @@ getword(wp)
} while ((d || (c != ' ' && c != '\t')) && c != '\n');
} while (wp == 0);
+ past_word_end:
unreadc(c);
- if (found)
- *--wp = '\0';
+ if (found) {
+ wp->len--;
+ Strbuf_terminate(wp);
+ }
return (found);
@@ -1040,7 +954,7 @@ past:
}
static void
-toend()
+toend(void)
{
if (whyles->w_end.type == TCSH_F_SEEK && whyles->w_end.f_seek == 0) {
search(TC_BREAK, 0, NULL);
@@ -1054,18 +968,16 @@ toend()
}
static void
-wpfree(wp)
- struct whyle *wp;
+wpfree(struct whyle *wp)
{
if (wp->w_fe0)
blkfree(wp->w_fe0);
- if (wp->w_fename)
- xfree((ptr_t) wp->w_fename);
- xfree((ptr_t) wp);
+ xfree(wp->w_fename);
+ xfree(wp);
}
void
-wfree()
+wfree(void)
{
struct Ain o;
struct whyle *nwp;
@@ -1074,13 +986,13 @@ wfree()
#endif
#ifdef FDEBUG
- static char foo[] = "IAFE";
+ static const char foo[] = "IAFE";
#endif /* FDEBUG */
btell(&o);
#ifdef FDEBUG
- xprintf("o->type %c o->a_seek %d o->f_seek %d\n",
+ xprintf("o->type %c o->a_seek %d o->f_seek %d\n",
foo[o.type + 1], o.a_seek, o.f_seek);
#endif /* FDEBUG */
@@ -1089,10 +1001,10 @@ wfree()
nwp = wp->w_next;
#ifdef FDEBUG
- xprintf("start->type %c start->a_seek %d start->f_seek %d\n",
+ xprintf("start->type %c start->a_seek %d start->f_seek %d\n",
foo[wp->w_start.type+1],
wp->w_start.a_seek, wp->w_start.f_seek);
- xprintf("end->type %c end->a_seek %d end->f_seek %d\n",
+ xprintf("end->type %c end->a_seek %d end->f_seek %d\n",
foo[wp->w_end.type + 1], wp->w_end.a_seek, wp->w_end.f_seek);
#endif /* FDEBUG */
@@ -1119,9 +1031,7 @@ wfree()
/*ARGSUSED*/
void
-doecho(v, c)
- Char **v;
- struct command *c;
+doecho(Char **v, struct command *c)
{
USE(c);
xecho(' ', v);
@@ -1129,9 +1039,7 @@ doecho(v, c)
/*ARGSUSED*/
void
-doglob(v, c)
- Char **v;
- struct command *c;
+doglob(Char **v, struct command *c)
{
USE(c);
xecho(0, v);
@@ -1139,21 +1047,11 @@ doglob(v, c)
}
static void
-xecho(sep, v)
- int sep;
- Char **v;
+xecho(int sep, Char **v)
{
- Char *cp;
+ Char *cp, **globbed = NULL;
int nonl = 0;
-#ifdef ECHO_STYLE
int echo_style = ECHO_STYLE;
-#else /* !ECHO_STYLE */
-# if SYSVREL > 0
- int echo_style = SYSV_ECHO;
-# else /* SYSVREL == 0 */
- int echo_style = BSD_ECHO;
-# endif /* SYSVREL */
-#endif /* ECHO_STYLE */
struct varent *vp;
if ((vp = adrof(STRecho_style)) != NULL && vp->vec != NULL &&
@@ -1168,25 +1066,20 @@ xecho(sep, v)
echo_style = NONE_ECHO;
}
- if (setintr)
-#ifdef BSDSIGS
- (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
-#else /* !BSDSIGS */
- (void) sigrelse (SIGINT);
-#endif /* BSDSIGS */
v++;
if (*v == 0)
goto done;
- gflag = 0, tglob(v);
- if (gflag) {
- v = globall(v);
- if (v == 0)
- stderror(ERR_NAME | ERR_NOMATCH);
- }
- else {
- v = gargv = saveblk(v);
- trim(v);
- }
+ if (setintr) {
+ int old_pintr_disabled;
+ pintr_push_enable(&old_pintr_disabled);
+ v = glob_all_or_error(v);
+ cleanup_until(&old_pintr_disabled);
+ } else {
+ v = glob_all_or_error(v);
+ }
+ globbed = v;
+ if (globbed != NULL)
+ cleanup_push(globbed, blk_cleanup);
if ((echo_style & BSD_ECHO) != 0 && sep == ' ' && *v && eq(*v, STRmn))
nonl++, v++;
@@ -1194,6 +1087,12 @@ xecho(sep, v)
while ((cp = *v++) != 0) {
Char c;
+ if (setintr) {
+ int old_pintr_disabled;
+
+ pintr_push_enable(&old_pintr_disabled);
+ cleanup_until(&old_pintr_disabled);
+ }
while ((c = *cp++) != 0) {
if ((echo_style & SYSV_ECHO) != 0 && c == '\\') {
switch (c = *cp++) {
@@ -1210,7 +1109,7 @@ xecho(sep, v)
#if 0 /* Windows does not understand \e */
c = '\e';
#else
- c = '\033';
+ c = CTL_ESC('\033');
#endif
break;
case 'f':
@@ -1260,20 +1159,13 @@ done:
xputchar('\n');
else
flush();
- if (setintr)
-#ifdef BSDSIGS
- (void) sigblock(sigmask(SIGINT));
-#else /* !BSDSIGS */
- (void) sighold(SIGINT);
-#endif /* BSDSIGS */
- if (gargv)
- blkfree(gargv), gargv = 0;
+ if (globbed != NULL)
+ cleanup_until(globbed);
}
/* check whether an environment variable should invoke 'set_locale()' */
static int
-islocale_var(var)
- Char *var;
+islocale_var(Char *var)
{
static Char *locale_vars[] = {
STRLANG, STRLC_ALL, STRLC_CTYPE, STRLC_NUMERIC,
@@ -1287,38 +1179,48 @@ islocale_var(var)
return 0;
}
+static void
+xlate_cr_cleanup(void *dummy)
+{
+ USE(dummy);
+ xlate_cr = 0;
+}
+
/*ARGSUSED*/
void
-doprintenv(v, c)
- Char **v;
- struct command *c;
+doprintenv(Char **v, struct command *c)
{
Char *e;
USE(c);
- if (setintr)
-#ifdef BSDSIGS
- (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
-#else /* !BSDSIGS */
- (void) sigrelse (SIGINT);
-#endif /* BSDSIGS */
-
v++;
if (*v == 0) {
Char **ep;
xlate_cr = 1;
- for (ep = STR_environ; *ep; ep++)
+ cleanup_push(&xlate_cr, xlate_cr_cleanup);
+ for (ep = STR_environ; *ep; ep++) {
+ if (setintr) {
+ int old_pintr_disabled;
+
+ pintr_push_enable(&old_pintr_disabled);
+ cleanup_until(&old_pintr_disabled);
+ }
xprintf("%S\n", *ep);
- xlate_cr = 0;
+ }
+ cleanup_until(&xlate_cr);
}
else if ((e = tgetenv(*v)) != NULL) {
+ int old_output_raw;
+
+ old_output_raw = output_raw;
output_raw = 1;
+ cleanup_push(&old_output_raw, output_raw_restore);
xprintf("%S\n", e);
- output_raw = 0;
+ cleanup_until(&old_output_raw);
}
else
- set(STRstatus, Strsave(STR1), VAR_READWRITE);
+ setcopy(STRstatus, STR1, VAR_READWRITE);
}
/* from "Karl Berry." <karl%mote.umb.edu@relay.cs.net> -- for NeXT things
@@ -1326,9 +1228,7 @@ doprintenv(v, c)
/*ARGSUSED*/
void
-dosetenv(v, c)
- Char **v;
- struct command *c;
+dosetenv(Char **v, struct command *c)
{
Char *vp, *lp;
@@ -1349,18 +1249,20 @@ dosetenv(v, c)
if ((lp = *v++) == 0)
lp = STRNULL;
- tsetenv(vp, lp = globone(lp, G_APPEND));
+ lp = globone(lp, G_APPEND);
+ cleanup_push(lp, xfree);
+ tsetenv(vp, lp);
if (eq(vp, STRKPATH)) {
- importpath(lp);
+ importpath(lp);
dohash(NULL, NULL);
- xfree((ptr_t) lp);
+ cleanup_until(lp);
return;
}
#ifdef apollo
if (eq(vp, STRSYSTYPE)) {
dohash(NULL, NULL);
- xfree((ptr_t) lp);
+ cleanup_until(lp);
return;
}
#endif /* apollo */
@@ -1401,7 +1303,7 @@ dosetenv(v, c)
fix_strcoll_bug();
# endif /* STRCOLLBUG */
tw_cmd_free(); /* since the collation sequence has changed */
- for (k = 0200; k <= 0377 && !Isprint(k); k++)
+ for (k = 0200; k <= 0377 && !Isprint(CTL_ESC(k)); k++)
continue;
AsciiOnly = MB_CUR_MAX == 1 && k > 0377;
#else /* !NLS */
@@ -1411,7 +1313,7 @@ dosetenv(v, c)
ed_Init();
if (MapsAreInited && !NLSMapsAreInited)
ed_InitNLSMaps();
- xfree((ptr_t) lp);
+ cleanup_until(lp);
return;
}
@@ -1427,24 +1329,27 @@ dosetenv(v, c)
MapsAreInited = 0;
NLSMapsAreInited = 0;
ed_InitMaps();
- xfree((ptr_t) lp);
+ cleanup_until(lp);
return;
}
#ifdef WINNT_NATIVE
if (eq(vp, STRtcshlang)) {
nlsinit();
- xfree((ptr_t) lp);
+ cleanup_until(lp);
return;
}
#endif /* WINNT_NATIVE */
if (eq(vp, STRKTERM)) {
char *t;
- set(STRterm, quote(lp), VAR_READWRITE); /* lp memory used here */
+
+ setv(STRterm, quote(lp), VAR_READWRITE); /* lp memory used here */
+ cleanup_ignore(lp);
+ cleanup_until(lp);
t = short2str(lp);
if (noediting && strcmp(t, "unknown") != 0 && strcmp(t,"dumb") != 0) {
editing = 1;
noediting = 0;
- set(STRedit, Strsave(STRNULL), VAR_READWRITE);
+ setNS(STRedit);
}
GotTermCaps = 0;
ed_Init();
@@ -1452,11 +1357,17 @@ dosetenv(v, c)
}
if (eq(vp, STRKHOME)) {
+ Char *canon;
/*
* convert to canonical pathname (possibly resolving symlinks)
*/
- lp = dcanon(lp, lp);
- set(STRhome, quote(lp), VAR_READWRITE); /* cp memory used here */
+ canon = dcanon(lp, lp);
+ cleanup_ignore(lp);
+ cleanup_until(lp);
+ cleanup_push(canon, xfree);
+ setv(STRhome, quote(canon), VAR_READWRITE); /* lp memory used here */
+ cleanup_ignore(canon);
+ cleanup_until(canon);
/* fix directory stack for new tilde home */
dtilde();
@@ -1464,24 +1375,30 @@ dosetenv(v, c)
}
if (eq(vp, STRKSHLVL)) {
- /* lp memory used here */
- set(STRshlvl, quote(lp), VAR_READWRITE);
+ setv(STRshlvl, quote(lp), VAR_READWRITE); /* lp memory used here */
+ cleanup_ignore(lp);
+ cleanup_until(lp);
return;
}
if (eq(vp, STRKUSER)) {
- set(STRuser, quote(lp), VAR_READWRITE); /* lp memory used here */
+ setv(STRuser, quote(lp), VAR_READWRITE); /* lp memory used here */
+ cleanup_ignore(lp);
+ cleanup_until(lp);
return;
}
if (eq(vp, STRKGROUP)) {
- set(STRgroup, quote(lp), VAR_READWRITE); /* lp memory used here */
+ setv(STRgroup, quote(lp), VAR_READWRITE); /* lp memory used here */
+ cleanup_ignore(lp);
+ cleanup_until(lp);
return;
}
#ifdef COLOR_LS_F
if (eq(vp, STRLS_COLORS)) {
parseLS_COLORS(lp);
+ cleanup_until(lp);
return;
}
#endif /* COLOR_LS_F */
@@ -1492,7 +1409,7 @@ dosetenv(v, c)
*/
if ((eq(lp, STRNULL) && (eq(vp, STRLINES) || eq(vp, STRCOLUMNS))) ||
eq(vp, STRTERMCAP)) {
- xfree((ptr_t) lp);
+ cleanup_until(lp);
check_window_size(1);
return;
}
@@ -1504,27 +1421,22 @@ dosetenv(v, c)
#if 0
GotTermCaps = 0;
#endif
- xfree((ptr_t) lp);
+ cleanup_until(lp);
ed_Init();
return;
}
#endif /* SIG_WINDOW */
- xfree((ptr_t) lp);
+ cleanup_until(lp);
}
/*ARGSUSED*/
void
-dounsetenv(v, c)
- Char **v;
- struct command *c;
+dounsetenv(Char **v, struct command *c)
{
- Char **ep, *p, *n;
+ Char **ep, *p, *n, *name;
int i, maxi;
- static Char *name = NULL;
USE(c);
- if (name)
- xfree((ptr_t) name);
/*
* Find the longest environment variable
*/
@@ -1535,7 +1447,8 @@ dounsetenv(v, c)
maxi = i;
}
- name = (Char *) xmalloc((size_t) ((maxi + 1) * sizeof(Char)));
+ name = xmalloc((maxi + 1) * sizeof(Char));
+ cleanup_push(name, xfree);
while (++v && *v)
for (maxi = 1; maxi;)
@@ -1577,7 +1490,7 @@ dounsetenv(v, c)
(void) setlocale(LC_COLLATE, "");
# endif
# ifdef LC_CTYPE
- (void) setlocale(LC_CTYPE, ""); /* for iscntrl */
+ (void) setlocale(LC_CTYPE, ""); /* for iscntrl */
# endif /* LC_CTYPE */
# ifdef NLS_CATALOGS
# ifdef LC_MESSAGES
@@ -1593,7 +1506,7 @@ dounsetenv(v, c)
fix_strcoll_bug();
# endif /* STRCOLLBUG */
tw_cmd_free();/* since the collation sequence has changed */
- for (k = 0200; k <= 0377 && !Isprint(k); k++)
+ for (k = 0200; k <= 0377 && !Isprint(CTL_ESC(k)); k++)
continue;
AsciiOnly = MB_CUR_MAX == 1 && k > 0377;
#else /* !NLS */
@@ -1627,12 +1540,11 @@ dounsetenv(v, c)
*/
break;
}
- xfree((ptr_t) name); name = NULL;
+ cleanup_until(name);
}
void
-tsetenv(name, val)
- const Char *name, *val;
+tsetenv(const Char *name, const Char *val)
{
#ifdef SETENV_IN_LIB
/*
@@ -1642,13 +1554,13 @@ tsetenv(name, val)
* it is not needed anymore.
*/
#undef setenv
- char nameBuf[BUFSIZE];
- char *cname = short2str(name);
+ char *cname;
- if (cname == NULL)
+ if (name == NULL)
return;
- (void) strcpy(nameBuf, cname);
- setenv(nameBuf, short2str(val), 1);
+ cname = strsave(short2str(name));
+ setenv(cname, short2str(val), 1);
+ xfree(cname);
#else /* !SETENV_IN_LIB */
Char **ep = STR_environ;
const Char *ccp;
@@ -1657,7 +1569,7 @@ tsetenv(name, val)
Char **oep = ep;
#ifdef WINNT_NATIVE
- nt_set_env(name,val);
+ nt_set_env(name,val);
#endif /* WINNT_NATIVE */
for (; *ep; ep++) {
#ifdef WINNT_NATIVE
@@ -1670,27 +1582,26 @@ tsetenv(name, val)
if (*ccp != 0 || *dp != '=')
continue;
cp = Strspl(STRequal, val);
- xfree((ptr_t) * ep);
+ xfree(*ep);
*ep = strip(Strspl(name, cp));
- xfree((ptr_t) cp);
+ xfree(cp);
blkfree((Char **) environ);
environ = short2blk(STR_environ);
return;
}
cp = Strspl(name, STRequal);
blk[0] = strip(Strspl(cp, val));
- xfree((ptr_t) cp);
+ xfree(cp);
blk[1] = 0;
STR_environ = blkspl(STR_environ, blk);
blkfree((Char **) environ);
environ = short2blk(STR_environ);
- xfree((ptr_t) oep);
+ xfree(oep);
#endif /* SETENV_IN_LIB */
}
void
-Unsetenv(name)
- Char *name;
+Unsetenv(Char *name)
{
Char **ep = STR_environ;
Char *cp, *dp;
@@ -1710,17 +1621,15 @@ Unsetenv(name)
blkfree((Char **) environ);
environ = short2blk(STR_environ);
*ep = cp;
- xfree((ptr_t) cp);
- xfree((ptr_t) oep);
+ xfree(cp);
+ xfree(oep);
return;
}
}
/*ARGSUSED*/
void
-doumask(v, c)
- Char **v;
- struct command *c;
+doumask(Char **v, struct command *c)
{
Char *cp = v[1];
int i;
@@ -1890,16 +1799,15 @@ struct limits limits[] =
{ -1, NULL, 0, NULL }
};
-static struct limits *findlim __P((Char *));
-static RLIM_TYPE getval __P((struct limits *, Char **));
-static void limtail __P((Char *, const char *));
-static void plim __P((struct limits *, int));
-static int setlim __P((struct limits *, int, RLIM_TYPE));
+static struct limits *findlim (Char *);
+static RLIM_TYPE getval (struct limits *, Char **);
+static void limtail (Char *, const char *);
+static void plim (struct limits *, int);
+static int setlim (struct limits *, int, RLIM_TYPE);
#ifdef convex
static RLIM_TYPE
-restrict_limit(value)
- double value;
+restrict_limit(double value)
{
/*
* is f too large to cope with? return the maximum or minimum int
@@ -1917,12 +1825,11 @@ restrict_limit(value)
static struct limits *
-findlim(cp)
- Char *cp;
+findlim(Char *cp)
{
struct limits *lp, *res;
- res = (struct limits *) NULL;
+ res = NULL;
for (lp = limits; lp->limconst >= 0; lp++)
if (prefix(cp, str2short(lp->limname))) {
if (res)
@@ -1938,9 +1845,7 @@ findlim(cp)
/*ARGSUSED*/
void
-dolimit(v, c)
- Char **v;
- struct command *c;
+dolimit(Char **v, struct command *c)
{
struct limits *lp;
RLIM_TYPE limit;
@@ -1968,9 +1873,7 @@ dolimit(v, c)
}
static RLIM_TYPE
-getval(lp, v)
- struct limits *lp;
- Char **v;
+getval(struct limits *lp, Char **v)
{
float f;
Char *cp = *v++;
@@ -2068,9 +1971,7 @@ badscal:
}
static void
-limtail(cp, str)
- Char *cp;
- const char *str;
+limtail(Char *cp, const char *str)
{
const char *sp;
@@ -2084,9 +1985,7 @@ limtail(cp, str)
/*ARGSUSED*/
static void
-plim(lp, hard)
- struct limits *lp;
- int hard;
+plim(struct limits *lp, int hard)
{
# ifdef BSDLIMIT
struct rlimit rlim;
@@ -2131,7 +2030,7 @@ plim(lp, hard)
# endif
# ifdef RLIMIT_CPU
if (lp->limconst == RLIMIT_CPU)
- psecs((long) limit);
+ psecs(limit);
else
# endif /* RLIMIT_CPU */
xprintf("%ld %s", (long) (limit / xdiv), lp->limscale);
@@ -2140,9 +2039,7 @@ plim(lp, hard)
/*ARGSUSED*/
void
-dounlimit(v, c)
- Char **v;
- struct command *c;
+dounlimit(Char **v, struct command *c)
{
struct limits *lp;
int lerr = 0;
@@ -2182,10 +2079,7 @@ dounlimit(v, c)
}
static int
-setlim(lp, hard, limit)
- struct limits *lp;
- int hard;
- RLIM_TYPE limit;
+setlim(struct limits *lp, int hard, RLIM_TYPE limit)
{
# ifdef BSDLIMIT
struct rlimit rlim;
@@ -2223,11 +2117,12 @@ setlim(lp, hard, limit)
err = errno;
op = strsave(limit == RLIM_INFINITY ? CGETS(15, 2, "remove") :
CGETS(15, 3, "set"));
+ cleanup_push(op, xfree);
type = strsave(hard ? CGETS(15, 4, " hard") : "");
+ cleanup_push(type, xfree);
xprintf(CGETS(15, 1, "%s: %s: Can't %s%s limit (%s)\n"), bname,
lp->limname, op, type, strerror(err));
- xfree(type);
- xfree(op);
+ cleanup_until(op);
return (-1);
}
return (0);
@@ -2237,14 +2132,11 @@ setlim(lp, hard, limit)
/*ARGSUSED*/
void
-dosuspend(v, c)
- Char **v;
- struct command *c;
+dosuspend(Char **v, struct command *c)
{
#ifdef BSDJOBS
int ctpgrp;
-
- signalfun_t old;
+ struct sigaction old;
#endif /* BSDJOBS */
USE(c);
@@ -2255,10 +2147,11 @@ dosuspend(v, c)
untty();
#ifdef BSDJOBS
- old = signal(SIGTSTP, SIG_DFL);
+ sigaction(SIGTSTP, NULL, &old);
+ signal(SIGTSTP, SIG_DFL);
(void) kill(0, SIGTSTP);
/* the shell stops here */
- (void) signal(SIGTSTP, old);
+ sigaction(SIGTSTP, &old, NULL);
#else /* !BSDJOBS */
stderror(ERR_JOBCONTROL);
#endif /* BSDJOBS */
@@ -2270,9 +2163,10 @@ retry:
if (ctpgrp == -1)
stderror(ERR_SYSTEM, "tcgetpgrp", strerror(errno));
if (ctpgrp != opgrp) {
- old = signal(SIGTTIN, SIG_DFL);
+ sigaction(SIGTTIN, NULL, &old);
+ signal(SIGTTIN, SIG_DFL);
(void) kill(0, SIGTTIN);
- (void) signal(SIGTTIN, old);
+ sigaction(SIGTTIN, &old, NULL);
goto retry;
}
(void) setpgid(0, shpgrp);
@@ -2295,125 +2189,122 @@ retry:
* pgrp, with no way for the shell to get them going again. -IAN!
*/
-static Char **gv = NULL, **gav = NULL;
-
-/*ARGSUSED*/
-void
-doeval(v, c)
- Char **v;
- struct command *c;
+struct doeval_state
{
- Char **oevalvec;
- Char *oevalp;
- int odidfds;
+ Char **evalvec, *evalp;
+ int didfds;
#ifndef CLOSE_ON_EXEC
- int odidcch;
-#endif /* CLOSE_ON_EXEC */
- jmp_buf_t osetexit;
- int my_reenter;
- Char **savegv;
- int saveIN, saveOUT, saveDIAG;
- int oSHIN, oSHOUT, oSHDIAG;
+ int didcch;
+#endif
+ int saveIN, saveOUT, saveDIAG;
+ int SHIN, SHOUT, SHDIAG;
+};
- USE(c);
- oevalvec = evalvec;
- oevalp = evalp;
- odidfds = didfds;
+static void
+doeval_cleanup(void *xstate)
+{
+ struct doeval_state *state;
+
+ state = xstate;
+ evalvec = state->evalvec;
+ evalp = state->evalp;
+ doneinp = 0;
#ifndef CLOSE_ON_EXEC
- odidcch = didcch;
+ didcch = state->didcch;
#endif /* CLOSE_ON_EXEC */
- oSHIN = SHIN;
- oSHOUT = SHOUT;
- oSHDIAG = SHDIAG;
+ didfds = state->didfds;
+ xclose(SHIN);
+ xclose(SHOUT);
+ xclose(SHDIAG);
+ close_on_exec(SHIN = dmove(state->saveIN, state->SHIN), 1);
+ close_on_exec(SHOUT = dmove(state->saveOUT, state->SHOUT), 1);
+ close_on_exec(SHDIAG = dmove(state->saveDIAG, state->SHDIAG), 1);
+}
- savegv = gv;
- gav = v;
+/*ARGSUSED*/
+void
+doeval(Char **v, struct command *c)
+{
+ struct doeval_state state;
+ int gflag;
+ Char **gv;
- gav++;
- if (*gav == 0)
+ USE(c);
+ v++;
+ if (*v == 0)
return;
- gflag = 0, tglob(gav);
+ gflag = tglob(v);
if (gflag) {
- gv = gav = globall(gav);
- gargv = 0;
- if (gav == 0)
+ gv = v = globall(v, gflag);
+ if (v == 0)
stderror(ERR_NOMATCH);
- gav = copyblk(gav);
+ cleanup_push(gv, blk_cleanup);
+ v = copyblk(v);
}
else {
gv = NULL;
- gav = copyblk(gav);
- trim(gav);
- }
-
- (void)close_on_exec(saveIN = dcopy(SHIN, -1), 1);
- (void)close_on_exec(saveOUT = dcopy(SHOUT, -1), 1);
- (void)close_on_exec(saveDIAG = dcopy(SHDIAG, -1), 1);
-
- getexit(osetexit);
-
- /* PWP: setjmp/longjmp bugfix for optimizing compilers */
-#ifdef cray
- my_reenter = 1; /* assume non-zero return val */
- if (setexit() == 0) {
- my_reenter = 0; /* Oh well, we were wrong */
-#else /* !cray */
- if ((my_reenter = setexit()) == 0) {
-#endif /* cray */
- evalvec = gav;
- evalp = 0;
- (void)close_on_exec(SHIN = dcopy(0, -1), 1);
- (void)close_on_exec(SHOUT = dcopy(1, -1), 1);
- (void)close_on_exec(SHDIAG = dcopy(2, -1), 1);
+ v = copyblk(v);
+ trim(v);
+ }
+
+ state.evalvec = evalvec;
+ state.evalp = evalp;
+ state.didfds = didfds;
#ifndef CLOSE_ON_EXEC
- didcch = 0;
+ state.didcch = didcch;
#endif /* CLOSE_ON_EXEC */
- didfds = 0;
- process(0);
- }
+ state.SHIN = SHIN;
+ state.SHOUT = SHOUT;
+ state.SHDIAG = SHDIAG;
- evalvec = oevalvec;
- evalp = oevalp;
- doneinp = 0;
+ (void)close_on_exec(state.saveIN = dcopy(SHIN, -1), 1);
+ (void)close_on_exec(state.saveOUT = dcopy(SHOUT, -1), 1);
+ (void)close_on_exec(state.saveDIAG = dcopy(SHDIAG, -1), 1);
+
+ cleanup_push(&state, doeval_cleanup);
+
+ evalvec = v;
+ evalp = 0;
+ (void)close_on_exec(SHIN = dcopy(0, -1), 1);
+ (void)close_on_exec(SHOUT = dcopy(1, -1), 1);
+ (void)close_on_exec(SHDIAG = dcopy(2, -1), 1);
#ifndef CLOSE_ON_EXEC
- didcch = odidcch;
+ didcch = 0;
#endif /* CLOSE_ON_EXEC */
- didfds = odidfds;
- (void) close(SHIN);
- (void) close(SHOUT);
- (void) close(SHDIAG);
- (void)close_on_exec (SHIN = dmove(saveIN, oSHIN), 1);
- (void)close_on_exec (SHOUT = dmove(saveOUT, oSHOUT), 1);
- (void)close_on_exec (SHDIAG = dmove(saveDIAG, oSHDIAG), 1);
+ didfds = 0;
+ process(0);
- if (gv)
- blkfree(gv);
+ cleanup_until(&state);
- gv = savegv;
- resexit(osetexit);
- if (my_reenter)
- stderror(ERR_SILENT);
+ if (gv)
+ cleanup_until(gv);
}
/*************************************************************************/
/* print list of builtin commands */
+static void
+lbuffed_cleanup (void *dummy)
+{
+ USE(dummy);
+ lbuffed = 1;
+}
+
/*ARGSUSED*/
void
-dobuiltins(v, c)
-Char **v;
-struct command *c;
+dobuiltins(Char **v, struct command *c)
{
/* would use print_by_column() in tw.parse.c but that assumes
* we have an array of Char * to pass.. (sg)
*/
- struct biltins *b;
+ const struct biltins *b;
int row, col, columns, rows;
unsigned int w, maxwidth;
USE(c);
USE(v);
lbuffed = 0; /* turn off line buffering */
+ cleanup_push(&lbuffed, lbuffed_cleanup);
/* find widest string */
for (maxwidth = 0, b = bfunc; b < &bfunc[nbfunc]; ++b)
@@ -2450,30 +2341,37 @@ struct command *c;
xputchar('\n');
#endif /* WINNT_NATIVE */
- lbuffed = 1; /* turn back on line buffering */
+ cleanup_until(&lbuffed); /* turn back on line buffering */
flush();
}
#ifdef NLS_CATALOGS
-#ifdef HAVE_ICONV
char *
-iconv_catgets(ctd, set_id, msg_id, s)
-nl_catd ctd;
-int set_id, msg_id;
-const char *s;
+xcatgets(nl_catd ctd, int set_id, int msg_id, const char *s)
+{
+ char *res;
+
+ errno = 0;
+ while ((res = catgets(ctd, set_id, msg_id, s)) == s && errno == EINTR) {
+ handle_pending_signals();
+ errno = 0;
+ }
+ return res;
+}
+
+
+# if defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO)
+char *
+iconv_catgets(nl_catd ctd, int set_id, int msg_id, const char *s)
{
static char *buf = NULL;
static size_t buf_size = 0;
char *orig, *dest, *p;
-#ifdef __NetBSD__
- const char *src;
-#else
- char *src;
-#endif
+ ICONV_CONST char *src;
size_t src_size, dest_size;
- orig = catgets(ctd, set_id, msg_id, s);
+ orig = xcatgets(ctd, set_id, msg_id, s);
if (catgets_iconv == (iconv_t)-1 || orig == s)
return orig;
src = orig;
@@ -2501,24 +2399,27 @@ const char *s;
}
return buf;
}
-#endif
-#endif
+# endif /* HAVE_ICONV && HAVE_NL_LANGINFO */
+#endif /* NLS_CATALOGS */
void
-nlsinit()
+nlsinit(void)
{
#ifdef NLS_CATALOGS
- char catalog[ 256 ] = { 't', 'c', 's', 'h', '\0' };
+ static const char default_catalog[] = "tcsh";
+
+ char *catalog = (char *)(intptr_t)default_catalog;
if (adrof(STRcatalog) != NULL)
- xsnprintf((char *)catalog, sizeof(catalog), "tcsh.%s",
- short2str(varval(STRcatalog)));
+ catalog = xasprintf("tcsh.%s", short2str(varval(STRcatalog)));
catd = catopen(catalog, MCLoadBySet);
-#ifdef HAVE_ICONV
- /* catgets (), not CGETS, the charset name should be in ASCII anyway. */
+ if (catalog != default_catalog)
+ xfree(catalog);
+#if defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO)
+ /* xcatgets (), not CGETS, the charset name should be in ASCII anyway. */
catgets_iconv = iconv_open (nl_langinfo (CODESET),
- catgets(catd, 255, 1, "ASCII"));
-#endif /* HAVE_ICONV */
+ xcatgets(catd, 255, 1, "ASCII"));
+#endif /* HAVE_ICONV && HAVE_NL_LANGINFO */
#endif /* NLS_CATALOGS */
#ifdef WINNT_NATIVE
nls_dll_init();
@@ -2531,15 +2432,26 @@ nlsinit()
}
void
-nlsclose()
+nlsclose(void)
{
#ifdef NLS_CATALOGS
-#ifdef HAVE_ICONV
+#if defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO)
if (catgets_iconv != (iconv_t)-1) {
iconv_close(catgets_iconv);
catgets_iconv = (iconv_t)-1;
}
-#endif /* HAVE_ICONV */
- catclose(catd);
+#endif /* HAVE_ICONV && HAVE_NL_LANGINFO */
+ if (catd != (nl_catd)-1) {
+ /*
+ * catclose can call other functions which can call longjmp
+ * making us re-enter this code. Prevent infinite recursion
+ * by resetting catd. Problem reported and solved by:
+ * Gerhard Niklasch
+ */
+ nl_catd oldcatd = catd;
+ catd = (nl_catd)-1;
+ while (catclose(oldcatd) == -1 && errno == EINTR)
+ handle_pending_signals();
+ }
#endif /* NLS_CATALOGS */
}
OpenPOWER on IntegriCloud