-/* $OpenBSD: main.c,v 1.51 2012/09/10 01:25:30 tedu Exp $ */
+/* $OpenBSD: main.c,v 1.54 2013/11/28 10:33:37 sobrado Exp $ */
/* $OpenBSD: tty.c,v 1.9 2006/03/14 22:08:01 deraadt Exp $ */
-/* $OpenBSD: io.c,v 1.22 2006/03/17 16:30:13 millert Exp $ */
+/* $OpenBSD: io.c,v 1.23 2013/12/17 16:37:06 deraadt Exp $ */
/* $OpenBSD: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- * 2011, 2012, 2013
+ * 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
#include <locale.h>
#endif
-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.260 2013/02/10 21:42:16 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.280 2014/06/09 12:28:17 tg Exp $");
extern char **environ;
/* not in Android for political reasons */
/* not in ARGE mksh due to no job control */
"stop=kill -STOP",
- "suspend=kill -STOP $$",
#endif
"autoload=typeset -fu",
"functions=typeset -f",
/* introduce variation (and yes, second arg MBZ for portability) */
mksh_TIME(bufptr->tv);
- NZATInit(h);
- /* variation through pid, ppid, and the works */
- NZATUpdateMem(h, &rndsetupstate, sizeof(rndsetupstate));
- /* some variation, some possibly entropy, depending on OE */
- NZATUpdateMem(h, bufptr, sizeof(*bufptr));
- NZAATFinish(h);
+ h = chvt_rndsetup(bufptr, sizeof(*bufptr));
afree(cp, APERM);
return ((mksh_uari_t)h);
if (!*ccp)
ccp = empty_argv[0];
+ /*
+ * Turn on nohup by default. (AT&T ksh does not have a nohup
+ * option - it always sends the hup).
+ */
+ Flag(FNOHUP) = 1;
+
+ /*
+ * Turn on brace expansion by default. AT&T kshs that have
+ * alternation always have it on.
+ */
+ Flag(FBRACEEXPAND) = 1;
+
+ /*
+ * Turn on "set -x" inheritance by default.
+ */
+ Flag(FXTRACEREC) = 1;
+
/* define built-in commands and see if we were called as one */
ktinit(APERM, &builtins,
- /* currently up to 50 builtins: 75% of 128 = 2^7 */
+ /* currently up to 51 builtins: 75% of 128 = 2^7 */
7);
for (i = 0; mkshbuiltins[i].name != NULL; i++)
if (!strcmp(ccp, builtin(mkshbuiltins[i].name,
if (argi < 0)
return (1);
+#if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED)
+ /* are we called as -sh or /bin/sh or so? */
+ if (!strcmp(ccp, "sh")) {
+ /* either also turns off braceexpand */
+#ifdef MKSH_BINSHPOSIX
+ /* enable better POSIX conformance */
+ change_flag(FPOSIX, OF_FIRSTTIME, true);
+#endif
#ifdef MKSH_BINSHREDUCED
- /* set FSH if we're called as -sh or /bin/sh or so */
- if (!strcmp(ccp, "sh"))
+ /* enable kludge/compat mode */
change_flag(FSH, OF_FIRSTTIME, true);
#endif
+ }
+#endif
}
initvar();
/* setstr can't fail here */
setstr(vp, def_path, KSH_RETURN_ERROR);
- /*
- * Turn on nohup by default for now - will change to off
- * by default once people are aware of its existence
- * (AT&T ksh does not have a nohup option - it always sends
- * the hup).
- */
- Flag(FNOHUP) = 1;
-
- /*
- * Turn on brace expansion by default. AT&T kshs that have
- * alternation always have it on.
- */
- Flag(FBRACEEXPAND) = 1;
-
#ifndef MKSH_NO_CMDLINE_EDITING
/*
* Set edit mode to emacs by default, may be overridden
#endif
/* import environment */
- if (environ != NULL)
- for (wp = (const char **)environ; *wp != NULL; wp++)
+ if (environ != NULL) {
+ wp = (const char **)environ;
+ while (*wp != NULL) {
+ rndpush(*wp);
typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
+ ++wp;
+ }
+ }
/* for security */
typeset(initifs, 0, 0, 0, 0);
setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);
/* Set this before parsing arguments */
- Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid;
+ Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
/* this to note if monitor is set on command line (see below) */
#ifndef MKSH_UNEMPLOYED
return (1);
}
-#ifdef DEBUG
- /* test wraparound of arithmetic types */
- {
- volatile long xl;
- volatile unsigned long xul;
- volatile int xi;
- volatile unsigned int xui;
- volatile mksh_ari_t xa;
- volatile mksh_uari_t xua, xua2;
- volatile uint8_t xc;
-
- xa = 2147483647;
- xua = 2147483647;
- ++xa;
- ++xua;
- xua2 = xa;
- xl = xa;
- xul = xua;
- xa = 0;
- xua = 0;
- --xa;
- --xua;
- xi = xa;
- xui = xua;
- xa = -1;
- xua = xa;
- ++xa;
- ++xua;
- xc = 0;
- --xc;
- if ((xua2 != 2147483648UL) ||
- (xl != -2147483648L) || (xul != 2147483648UL) ||
- (xi != -1) || (xui != 4294967295U) ||
- (xa != 0) || (xua != 0) || (xc != 255))
- errorf("integer wraparound test failed");
- }
-#endif
-
/* process this later only, default to off (hysterical raisins) */
utf_flag = UTFMODE;
UTFMODE = 0;
s = pushs(SSTRINGCMDLINE, ATEMP);
if (!(s->start = s->str = argv[argi++]))
errorf("%s %s", "-c", "requires an argument");
-#if !defined(MKSH_SMALL)
while (*s->str) {
if (*s->str != ' ' && ctype(*s->str, C_QUOTE))
break;
if (!*s->str)
s->flags |= SF_MAYEXEC;
s->str = s->start;
-#endif
#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT
/* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */
if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--"))
#ifndef MKSH_ASSUME_UTF8
/* auto-detect from locale or environment */
utf_flag = 4;
-#elif MKSH_ASSUME_UTF8
+#else /* this may not be an #elif */
+#if MKSH_ASSUME_UTF8
utf_flag = 1;
#else
/* always disable UTF-8 (for interactive) */
utf_flag = 0;
#endif
+#endif
}
#ifndef MKSH_NO_CMDLINE_EDITING
x_init();
if (!current_wd[0] && Flag(FTALKING))
warningf(false, "can't determine current directory");
- if (Flag(FLOGIN)) {
+ if (Flag(FLOGIN))
include(MKSH_SYSTEM_PROFILE, 0, NULL, true);
- if (!Flag(FPRIVILEGED))
- include(substitute("$HOME/.profile", 0), 0,
- NULL, true);
- }
- if (Flag(FPRIVILEGED))
+ if (!Flag(FPRIVILEGED)) {
+ if (Flag(FLOGIN))
+ include(substitute("$HOME/.profile", 0), 0, NULL, true);
+ if (Flag(FTALKING)) {
+ cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}",
+ 0), DOTILDE);
+ if (cp[0] != '\0')
+ include(cp, 0, NULL, true);
+ }
+ } else {
include(MKSH_SUID_PROFILE, 0, NULL, true);
- else if (Flag(FTALKING)) {
- char *env_file;
-
- /* include $ENV */
- env_file = substitute(substitute("${ENV:-" MKSHRC_PATH "}", 0),
- DOTILDE);
- if (*env_file != '\0')
- include(env_file, 0, NULL, true);
+ /* turn off -p if not set explicitly */
+ if (Flag(FPRIVILEGED) != 1)
+ change_flag(FPRIVILEGED, OF_INTERNAL, false);
}
if (restricted) {
unwind(LEXIT);
break;
}
- }
-#if !defined(MKSH_SMALL)
- else if ((s->flags & SF_MAYEXEC) && t->type == TCOM)
+ } else if ((s->flags & SF_MAYEXEC) && t->type == TCOM)
t->u.evalflags |= DOTCOMEXEC;
-#endif
if (!Flag(FNOEXEC) || (s->flags & SF_TTY))
exstat = execute(t, 0, NULL) & 0xFF;
}
/* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */
- if (i == LEXIT ||
- ((i == LERROR || i == LINTR) && sigtraps[ksh_SIGEXIT].trap)) {
+ if (i == LEXIT || ((i == LERROR || i == LINTR) &&
+ sigtraps[ksh_SIGEXIT].trap &&
+ (!Flag(FTALKING) || Flag(FERREXIT)))) {
++trap_nested;
runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1);
--trap_nested;
#ifndef MKSH_NO_CMDLINE_EDITING
x_done();
#endif
+#ifndef MKSH_NOPROSPECTOFWORK
+ /* block at least SIGCHLD during/after afreeall */
+ sigprocmask(SIG_BLOCK, &sm_sigchld, NULL);
+#endif
afreeall(APERM);
for (fd = 3; fd < NUFILE; fd++)
if ((i = fcntl(fd, F_GETFD, 0)) != -1 &&
/* force buffer allocation */
shf_fdopen(1, SHF_WR, shl_stdout);
shf_fdopen(2, SHF_WR, shl_out);
- shf_fdopen(2, SHF_WR, shl_spare);
+ shf_fdopen(2, SHF_WR, shl_xtrace);
#ifdef DF
if ((lfp = getenv("SDMKSH_PATH")) == NULL) {
if ((lfp = getenv("HOME")) == NULL || *lfp != '/')
{
char *cp;
size_t len;
- int i;
+ int i, j;
struct temp *tp;
const char *dir;
struct stat sb;
} while (len < 5);
/* cyclically attempt to open a temporary file */
- while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR, 0600)) < 0) {
+ while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR | O_BINARY,
+ 0600)) < 0) {
if (errno != EEXIST)
goto maketemp_out;
/* count down from z to a then from 9 to 0 */
}
if (type == TT_FUNSUB) {
- int nfd;
-
/* map us high and mark as close-on-exec */
- if ((nfd = savefd(i)) != i) {
+ if ((j = savefd(i)) != i) {
close(i);
- i = nfd;
+ i = j;
}
- }
+
+ /* operation mode for the shf */
+ j = SHF_RD;
+ } else
+ j = SHF_WR;
/* shf_fdopen cannot fail, so no fd leak */
- tp->shf = shf_fdopen(i, SHF_WR, NULL);
+ tp->shf = shf_fdopen(i, j, NULL);
maketemp_out:
tp->next = *tlist;
cb = *ocb;
if (forread) {
+ cb.c_iflag &= ~(ISTRIP);
cb.c_lflag &= ~(ICANON) | ECHO;
} else {
- cb.c_iflag &= ~(INLCR | ICRNL);
+ cb.c_iflag &= ~(INLCR | ICRNL | ISTRIP);
cb.c_lflag &= ~(ISIG | ICANON | ECHO);
}
#if defined(VLNEXT) && defined(_POSIX_VDISABLE)