• implement KSHEGID, KSHGID, KSHUID variables by suggestion of Richard K.
(KSHEUID aka USER_ID already exists) • simplify, speed up LCG and $RANDOM handling again
This commit is contained in:
parent
1d6e0470e0
commit
cc31d86e3b
103
jobs.c
103
jobs.c
@ -1,7 +1,7 @@
|
|||||||
/* $OpenBSD: jobs.c,v 1.38 2009/12/12 04:28:44 deraadt Exp $ */
|
/* $OpenBSD: jobs.c,v 1.38 2009/12/12 04:28:44 deraadt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011
|
||||||
* Thorsten Glaser <tg@mirbsd.org>
|
* Thorsten Glaser <tg@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.72 2010/08/28 20:22:19 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.73 2011/01/21 21:04:44 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
#define mksh_killpg killpg
|
#define mksh_killpg killpg
|
||||||
@ -342,11 +342,9 @@ exchild(struct op *t, int flags,
|
|||||||
|
|
||||||
int rv = 0, forksleep;
|
int rv = 0, forksleep;
|
||||||
sigset_t omask;
|
sigset_t omask;
|
||||||
struct {
|
|
||||||
Proc *p;
|
Proc *p;
|
||||||
Job *j;
|
Job *j;
|
||||||
pid_t cldpid;
|
pid_t cldpid;
|
||||||
} pi;
|
|
||||||
|
|
||||||
if (flags & XEXEC)
|
if (flags & XEXEC)
|
||||||
/*
|
/*
|
||||||
@ -358,11 +356,11 @@ exchild(struct op *t, int flags,
|
|||||||
/* no SIGCHLDs while messing with job and process lists */
|
/* no SIGCHLDs while messing with job and process lists */
|
||||||
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
||||||
|
|
||||||
pi.p = new_proc();
|
p = new_proc();
|
||||||
pi.p->next = NULL;
|
p->next = NULL;
|
||||||
pi.p->state = PRUNNING;
|
p->state = PRUNNING;
|
||||||
pi.p->status = 0;
|
p->status = 0;
|
||||||
pi.p->pid = 0;
|
p->pid = 0;
|
||||||
|
|
||||||
/* link process into jobs list */
|
/* link process into jobs list */
|
||||||
if (flags & XPIPEI) {
|
if (flags & XPIPEI) {
|
||||||
@ -371,78 +369,76 @@ exchild(struct op *t, int flags,
|
|||||||
internal_errorf("%s %d",
|
internal_errorf("%s %d",
|
||||||
"exchild: XPIPEI and no last_job - pid",
|
"exchild: XPIPEI and no last_job - pid",
|
||||||
(int)procpid);
|
(int)procpid);
|
||||||
pi.j = last_job;
|
j = last_job;
|
||||||
if (last_proc)
|
if (last_proc)
|
||||||
last_proc->next = pi.p;
|
last_proc->next = p;
|
||||||
last_proc = pi.p;
|
last_proc = p;
|
||||||
} else {
|
} else {
|
||||||
pi.j = new_job(); /* fills in pi.j->job */
|
/* fills in j->job */
|
||||||
|
j = new_job();
|
||||||
/*
|
/*
|
||||||
* we don't consider XXCOMs foreground since they don't get
|
* we don't consider XXCOMs foreground since they don't get
|
||||||
* tty process group and we don't save or restore tty modes.
|
* tty process group and we don't save or restore tty modes.
|
||||||
*/
|
*/
|
||||||
pi.j->flags = (flags & XXCOM) ? JF_XXCOM :
|
j->flags = (flags & XXCOM) ? JF_XXCOM :
|
||||||
((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
|
((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
|
||||||
timerclear(&pi.j->usrtime);
|
timerclear(&j->usrtime);
|
||||||
timerclear(&pi.j->systime);
|
timerclear(&j->systime);
|
||||||
pi.j->state = PRUNNING;
|
j->state = PRUNNING;
|
||||||
pi.j->pgrp = 0;
|
j->pgrp = 0;
|
||||||
pi.j->ppid = procpid;
|
j->ppid = procpid;
|
||||||
pi.j->age = ++njobs;
|
j->age = ++njobs;
|
||||||
pi.j->proc_list = pi.p;
|
j->proc_list = p;
|
||||||
pi.j->coproc_id = 0;
|
j->coproc_id = 0;
|
||||||
last_job = pi.j;
|
last_job = j;
|
||||||
last_proc = pi.p;
|
last_proc = p;
|
||||||
put_job(pi.j, PJ_PAST_STOPPED);
|
put_job(j, PJ_PAST_STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
snptreef(pi.p->command, sizeof(pi.p->command), "%T", t);
|
snptreef(p->command, sizeof(p->command), "%T", t);
|
||||||
|
|
||||||
/* create child process */
|
/* create child process */
|
||||||
forksleep = 1;
|
forksleep = 1;
|
||||||
while ((pi.cldpid = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
|
while ((cldpid = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
|
||||||
if (intrsig) /* allow user to ^C out... */
|
if (intrsig) /* allow user to ^C out... */
|
||||||
break;
|
break;
|
||||||
sleep(forksleep);
|
sleep(forksleep);
|
||||||
forksleep <<= 1;
|
forksleep <<= 1;
|
||||||
}
|
}
|
||||||
if (pi.cldpid < 0) {
|
/* ensure $RANDOM changes between parent and child */
|
||||||
kill_job(pi.j, SIGKILL);
|
rndset((long)cldpid);
|
||||||
remove_job(pi.j, "fork failed");
|
/* fork failed? */
|
||||||
|
if (cldpid < 0) {
|
||||||
|
kill_job(j, SIGKILL);
|
||||||
|
remove_job(j, "fork failed");
|
||||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||||
errorf("can't fork - try again");
|
errorf("can't fork - try again");
|
||||||
}
|
}
|
||||||
pi.p->pid = pi.cldpid ? pi.cldpid : (procpid = getpid());
|
p->pid = cldpid ? cldpid : (procpid = getpid());
|
||||||
|
|
||||||
/*
|
|
||||||
* ensure next child gets a (slightly) different $RANDOM sequence
|
|
||||||
* from its parent process and other child processes
|
|
||||||
*/
|
|
||||||
change_random(&pi, sizeof(pi));
|
|
||||||
|
|
||||||
#ifndef MKSH_UNEMPLOYED
|
#ifndef MKSH_UNEMPLOYED
|
||||||
/* job control set up */
|
/* job control set up */
|
||||||
if (Flag(FMONITOR) && !(flags&XXCOM)) {
|
if (Flag(FMONITOR) && !(flags&XXCOM)) {
|
||||||
int dotty = 0;
|
int dotty = 0;
|
||||||
if (pi.j->pgrp == 0) { /* First process */
|
if (j->pgrp == 0) { /* First process */
|
||||||
pi.j->pgrp = pi.p->pid;
|
j->pgrp = p->pid;
|
||||||
dotty = 1;
|
dotty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set pgrp in both parent and child to deal with race
|
/* set pgrp in both parent and child to deal with race
|
||||||
* condition
|
* condition
|
||||||
*/
|
*/
|
||||||
setpgid(pi.p->pid, pi.j->pgrp);
|
setpgid(p->pid, j->pgrp);
|
||||||
if (ttypgrp_ok && dotty && !(flags & XBGND))
|
if (ttypgrp_ok && dotty && !(flags & XBGND))
|
||||||
tcsetpgrp(tty_fd, pi.j->pgrp);
|
tcsetpgrp(tty_fd, j->pgrp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* used to close pipe input fd */
|
/* used to close pipe input fd */
|
||||||
if (close_fd >= 0 && (((flags & XPCLOSE) && pi.cldpid) ||
|
if (close_fd >= 0 && (((flags & XPCLOSE) && cldpid) ||
|
||||||
((flags & XCCLOSE) && !pi.cldpid)))
|
((flags & XCCLOSE) && !cldpid)))
|
||||||
close(close_fd);
|
close(close_fd);
|
||||||
if (!pi.cldpid) {
|
if (!cldpid) {
|
||||||
/* child */
|
/* child */
|
||||||
|
|
||||||
/* Do this before restoring signal */
|
/* Do this before restoring signal */
|
||||||
@ -480,7 +476,7 @@ exchild(struct op *t, int flags,
|
|||||||
close(forksleep);
|
close(forksleep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remove_job(pi.j, "child"); /* in case of $(jobs) command */
|
remove_job(j, "child"); /* in case of $(jobs) command */
|
||||||
nzombie = 0;
|
nzombie = 0;
|
||||||
#ifndef MKSH_UNEMPLOYED
|
#ifndef MKSH_UNEMPLOYED
|
||||||
ttypgrp_ok = false;
|
ttypgrp_ok = false;
|
||||||
@ -505,27 +501,26 @@ exchild(struct op *t, int flags,
|
|||||||
|
|
||||||
/* shell (parent) stuff */
|
/* shell (parent) stuff */
|
||||||
if (!(flags & XPIPEO)) { /* last process in a job */
|
if (!(flags & XPIPEO)) { /* last process in a job */
|
||||||
j_startjob(pi.j);
|
j_startjob(j);
|
||||||
if (flags & XCOPROC) {
|
if (flags & XCOPROC) {
|
||||||
pi.j->coproc_id = coproc.id;
|
j->coproc_id = coproc.id;
|
||||||
/* n jobs using co-process output */
|
/* n jobs using co-process output */
|
||||||
coproc.njobs++;
|
coproc.njobs++;
|
||||||
/* j using co-process input */
|
/* j using co-process input */
|
||||||
coproc.job = (void *)pi.j;
|
coproc.job = (void *)j;
|
||||||
}
|
}
|
||||||
if (flags & XBGND) {
|
if (flags & XBGND) {
|
||||||
j_set_async(pi.j);
|
j_set_async(j);
|
||||||
if (Flag(FTALKING)) {
|
if (Flag(FTALKING)) {
|
||||||
shf_fprintf(shl_out, "[%d]", pi.j->job);
|
shf_fprintf(shl_out, "[%d]", j->job);
|
||||||
for (pi.p = pi.j->proc_list; pi.p;
|
for (p = j->proc_list; p; p = p->next)
|
||||||
pi.p = pi.p->next)
|
|
||||||
shf_fprintf(shl_out, " %d",
|
shf_fprintf(shl_out, " %d",
|
||||||
(int)pi.p->pid);
|
(int)p->pid);
|
||||||
shf_putchar('\n', shl_out);
|
shf_putchar('\n', shl_out);
|
||||||
shf_flush(shl_out);
|
shf_flush(shl_out);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
rv = j_waitj(pi.j, JW_NONE, "jw:last proc");
|
rv = j_waitj(j, JW_NONE, "jw:last proc");
|
||||||
}
|
}
|
||||||
|
|
||||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||||
|
172
main.c
172
main.c
@ -4,7 +4,7 @@
|
|||||||
/* $OpenBSD: table.c,v 1.13 2009/01/17 22:06:44 millert Exp $ */
|
/* $OpenBSD: table.c,v 1.13 2009/01/17 22:06:44 millert Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||||
* Thorsten Glaser <tg@mirbsd.org>
|
* Thorsten Glaser <tg@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
@ -33,15 +33,10 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.173 2010/11/01 17:29:04 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.174 2011/01/21 21:04:44 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
#if !HAVE_SETRESUGID
|
|
||||||
extern uid_t kshuid;
|
|
||||||
extern gid_t kshgid, kshegid;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MKSHRC_PATH
|
#ifndef MKSHRC_PATH
|
||||||
#define MKSHRC_PATH "~/.mkshrc"
|
#define MKSHRC_PATH "~/.mkshrc"
|
||||||
#endif
|
#endif
|
||||||
@ -50,10 +45,10 @@ extern gid_t kshgid, kshegid;
|
|||||||
#define MKSH_DEFAULT_TMPDIR "/tmp"
|
#define MKSH_DEFAULT_TMPDIR "/tmp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void chvt_reinit(void);
|
||||||
static void reclaim(void);
|
static void reclaim(void);
|
||||||
static void remove_temps(struct temp *);
|
static void remove_temps(struct temp *);
|
||||||
void chvt_reinit(void);
|
static mksh_uari_t rndsetup(void);
|
||||||
Source *mksh_init(int, const char *[]);
|
|
||||||
#ifdef SIGWINCH
|
#ifdef SIGWINCH
|
||||||
static void x_sigwinch(int);
|
static void x_sigwinch(int);
|
||||||
#endif
|
#endif
|
||||||
@ -66,8 +61,9 @@ static const char initsubs[] =
|
|||||||
static const char *initcoms[] = {
|
static const char *initcoms[] = {
|
||||||
T_typeset, "-r", initvsn, NULL,
|
T_typeset, "-r", initvsn, NULL,
|
||||||
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
|
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
|
||||||
T_typeset, "-i10", "COLUMNS", "LINES", "OPTIND", "PGRP", "PPID",
|
T_typeset, "-i10", "COLUMNS", "KSHEGID", "KSHGID", "KSHUID", "LINES",
|
||||||
"RANDOM", "SECONDS", "TMOUT", "USER_ID", NULL,
|
"OPTIND", "PGRP", "PPID", "RANDOM", "SECONDS", "TMOUT", "USER_ID",
|
||||||
|
NULL,
|
||||||
T_alias,
|
T_alias,
|
||||||
"integer=typeset -i",
|
"integer=typeset -i",
|
||||||
T_local_typeset,
|
T_local_typeset,
|
||||||
@ -97,7 +93,41 @@ static const char *initcoms[] = {
|
|||||||
|
|
||||||
static int initio_done;
|
static int initio_done;
|
||||||
|
|
||||||
struct env *e = &kshstate_v.env_;
|
/* top-level parsing and execution environment */
|
||||||
|
static struct env env;
|
||||||
|
struct env *e = &env;
|
||||||
|
|
||||||
|
static mksh_uari_t
|
||||||
|
rndsetup(void)
|
||||||
|
{
|
||||||
|
register uint32_t h;
|
||||||
|
struct {
|
||||||
|
ALLOC_ITEM __alloc_i;
|
||||||
|
void *dataptr, *stkptr, *mallocptr;
|
||||||
|
sigjmp_buf jbuf;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timezone tz;
|
||||||
|
} *bufptr;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
cp = alloc(sizeof(*bufptr) - ALLOC_SIZE, APERM);
|
||||||
|
bufptr = (void *)(cp - ALLOC_SIZE); /* undo what alloc() did */
|
||||||
|
bufptr->dataptr = &rndsetupstate; /* PIE or something */
|
||||||
|
bufptr->stkptr = &bufptr; /* ASLR in Win/Lin */
|
||||||
|
bufptr->mallocptr = bufptr; /* randomised malloc in BSD */
|
||||||
|
sigsetjmp(bufptr->jbuf, 1); /* glibc pointer guard */
|
||||||
|
gettimeofday(&bufptr->tv, &bufptr->tz); /* introduce variation */
|
||||||
|
|
||||||
|
oaat1_init_impl(h);
|
||||||
|
/* variation through pid, ppid, and the works */
|
||||||
|
oaat1_addmem_impl(h, &rndsetupstate, sizeof(rndsetupstate));
|
||||||
|
/* some variation, some possibly entropy, depending on OE */
|
||||||
|
oaat1_addmem_impl(h, bufptr, sizeof(*bufptr));
|
||||||
|
oaat1_fini_impl(h);
|
||||||
|
|
||||||
|
afree(cp, APERM);
|
||||||
|
return ((mksh_uari_t)h);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
chvt_reinit(void)
|
chvt_reinit(void)
|
||||||
@ -108,8 +138,8 @@ chvt_reinit(void)
|
|||||||
kshppid = getppid();
|
kshppid = getppid();
|
||||||
}
|
}
|
||||||
|
|
||||||
Source *
|
int
|
||||||
mksh_init(int argc, const char *argv[])
|
main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
int argi, i;
|
int argi, i;
|
||||||
Source *s;
|
Source *s;
|
||||||
@ -140,16 +170,17 @@ mksh_init(int argc, const char *argv[])
|
|||||||
ainit(&aperm); /* initialise permanent Area */
|
ainit(&aperm); /* initialise permanent Area */
|
||||||
|
|
||||||
/* set up base environment */
|
/* set up base environment */
|
||||||
kshstate_v.env_.type = E_NONE;
|
env.type = E_NONE;
|
||||||
ainit(&kshstate_v.env_.area);
|
ainit(&env.area);
|
||||||
newblock(); /* set up global l->vars and l->funs */
|
/* set up global l->vars and l->funs */
|
||||||
|
newblock();
|
||||||
|
|
||||||
/* Do this first so output routines (eg, errorf, shellf) can work */
|
/* Do this first so output routines (eg, errorf, shellf) can work */
|
||||||
initio();
|
initio();
|
||||||
|
|
||||||
argi = parse_args(argv, OF_FIRSTTIME, NULL);
|
argi = parse_args(argv, OF_FIRSTTIME, NULL);
|
||||||
if (argi < 0)
|
if (argi < 0)
|
||||||
return (NULL);
|
return (1);
|
||||||
|
|
||||||
initvar();
|
initvar();
|
||||||
|
|
||||||
@ -197,28 +228,33 @@ mksh_init(int argc, const char *argv[])
|
|||||||
def_path = "/bin:/usr/bin:/sbin:/usr/sbin";
|
def_path = "/bin:/usr/bin:/sbin:/usr/sbin";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set PATH to def_path (will set the path global variable).
|
/*
|
||||||
|
* Set PATH to def_path (will set the path global variable).
|
||||||
* (import of environment below will probably change this setting).
|
* (import of environment below will probably change this setting).
|
||||||
*/
|
*/
|
||||||
vp = global("PATH");
|
vp = global("PATH");
|
||||||
/* setstr can't fail here */
|
/* setstr can't fail here */
|
||||||
setstr(vp, def_path, KSH_RETURN_ERROR);
|
setstr(vp, def_path, KSH_RETURN_ERROR);
|
||||||
|
|
||||||
/* Turn on nohup by default for now - will change to off
|
/*
|
||||||
|
* Turn on nohup by default for now - will change to off
|
||||||
* by default once people are aware of its existence
|
* by default once people are aware of its existence
|
||||||
* (AT&T ksh does not have a nohup option - it always sends
|
* (AT&T ksh does not have a nohup option - it always sends
|
||||||
* the hup).
|
* the hup).
|
||||||
*/
|
*/
|
||||||
Flag(FNOHUP) = 1;
|
Flag(FNOHUP) = 1;
|
||||||
|
|
||||||
/* Turn on brace expansion by default. AT&T kshs that have
|
/*
|
||||||
|
* Turn on brace expansion by default. AT&T kshs that have
|
||||||
* alternation always have it on.
|
* alternation always have it on.
|
||||||
*/
|
*/
|
||||||
Flag(FBRACEEXPAND) = 1;
|
Flag(FBRACEEXPAND) = 1;
|
||||||
|
|
||||||
/* Set edit mode to emacs by default, may be overridden
|
/*
|
||||||
|
* Set edit mode to emacs by default, may be overridden
|
||||||
* by the environment or the user. Also, we want tab completion
|
* by the environment or the user. Also, we want tab completion
|
||||||
* on in vi by default. */
|
* on in vi by default.
|
||||||
|
*/
|
||||||
change_flag(FEMACS, OF_SPECIAL, 1);
|
change_flag(FEMACS, OF_SPECIAL, 1);
|
||||||
#if !MKSH_S_NOVI
|
#if !MKSH_S_NOVI
|
||||||
Flag(FVITABCOMPLETE) = 1;
|
Flag(FVITABCOMPLETE) = 1;
|
||||||
@ -266,7 +302,8 @@ mksh_init(int argc, const char *argv[])
|
|||||||
set_current_wd(pwdx);
|
set_current_wd(pwdx);
|
||||||
if (current_wd[0])
|
if (current_wd[0])
|
||||||
simplify_path(current_wd);
|
simplify_path(current_wd);
|
||||||
/* Only set pwd if we know where we are or if it had a
|
/*
|
||||||
|
* Only set pwd if we know where we are or if it had a
|
||||||
* bogus value
|
* bogus value
|
||||||
*/
|
*/
|
||||||
if (current_wd[0] || pwd != null)
|
if (current_wd[0] || pwd != null)
|
||||||
@ -283,6 +320,10 @@ mksh_init(int argc, const char *argv[])
|
|||||||
setint(global("LINES"), 0);
|
setint(global("LINES"), 0);
|
||||||
setint(global("OPTIND"), 1);
|
setint(global("OPTIND"), 1);
|
||||||
|
|
||||||
|
kshuid = getuid();
|
||||||
|
kshgid = getgid();
|
||||||
|
kshegid = getegid();
|
||||||
|
|
||||||
safe_prompt = ksheuid ? "$ " : "# ";
|
safe_prompt = ksheuid ? "$ " : "# ";
|
||||||
vp = global("PS1");
|
vp = global("PS1");
|
||||||
/* Set PS1 if unset or we are root and prompt doesn't contain a # */
|
/* Set PS1 if unset or we are root and prompt doesn't contain a # */
|
||||||
@ -294,18 +335,19 @@ mksh_init(int argc, const char *argv[])
|
|||||||
vp->flag |= INT_U;
|
vp->flag |= INT_U;
|
||||||
setint((vp = global("PPID")), (mksh_uari_t)kshppid);
|
setint((vp = global("PPID")), (mksh_uari_t)kshppid);
|
||||||
vp->flag |= INT_U;
|
vp->flag |= INT_U;
|
||||||
setint((vp = global("RANDOM")), (mksh_uari_t)evilhash(kshname));
|
|
||||||
vp->flag |= INT_U;
|
|
||||||
setint((vp = global("USER_ID")), (mksh_uari_t)ksheuid);
|
setint((vp = global("USER_ID")), (mksh_uari_t)ksheuid);
|
||||||
vp->flag |= INT_U;
|
vp->flag |= INT_U;
|
||||||
|
setint((vp = global("KSHUID")), (mksh_uari_t)kshuid);
|
||||||
|
vp->flag |= INT_U;
|
||||||
|
setint((vp = global("KSHEGID")), (mksh_uari_t)kshegid);
|
||||||
|
vp->flag |= INT_U;
|
||||||
|
setint((vp = global("KSHGID")), (mksh_uari_t)kshgid);
|
||||||
|
vp->flag |= INT_U;
|
||||||
|
setint((vp = global("RANDOM")), rndsetup());
|
||||||
|
vp->flag |= INT_U;
|
||||||
|
|
||||||
/* Set this before parsing arguments */
|
/* Set this before parsing arguments */
|
||||||
#if HAVE_SETRESUGID
|
Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid;
|
||||||
Flag(FPRIVILEGED) = getuid() != ksheuid || getgid() != getegid();
|
|
||||||
#else
|
|
||||||
Flag(FPRIVILEGED) = (kshuid = getuid()) != ksheuid ||
|
|
||||||
(kshgid = getgid()) != (kshegid = getegid());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* this to note if monitor is set on command line (see below) */
|
/* this to note if monitor is set on command line (see below) */
|
||||||
#ifndef MKSH_UNEMPLOYED
|
#ifndef MKSH_UNEMPLOYED
|
||||||
@ -316,7 +358,7 @@ mksh_init(int argc, const char *argv[])
|
|||||||
|
|
||||||
argi = parse_args(argv, OF_CMDLINE, NULL);
|
argi = parse_args(argv, OF_CMDLINE, NULL);
|
||||||
if (argi < 0)
|
if (argi < 0)
|
||||||
return (NULL);
|
return (1);
|
||||||
|
|
||||||
/* process this later only, default to off (hysterical raisins) */
|
/* process this later only, default to off (hysterical raisins) */
|
||||||
utf_flag = UTFMODE;
|
utf_flag = UTFMODE;
|
||||||
@ -422,7 +464,8 @@ mksh_init(int argc, const char *argv[])
|
|||||||
errexit = Flag(FERREXIT);
|
errexit = Flag(FERREXIT);
|
||||||
Flag(FERREXIT) = 0;
|
Flag(FERREXIT) = 0;
|
||||||
|
|
||||||
/* Do this before profile/$ENV so that if it causes problems in them,
|
/*
|
||||||
|
* Do this before profile/$ENV so that if it causes problems in them,
|
||||||
* user will know why things broke.
|
* user will know why things broke.
|
||||||
*/
|
*/
|
||||||
if (!current_wd[0] && Flag(FTALKING))
|
if (!current_wd[0] && Flag(FTALKING))
|
||||||
@ -464,23 +507,9 @@ mksh_init(int argc, const char *argv[])
|
|||||||
} else
|
} else
|
||||||
Flag(FTRACKALL) = 1; /* set after ENV */
|
Flag(FTRACKALL) = 1; /* set after ENV */
|
||||||
|
|
||||||
return (s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
Source *s;
|
|
||||||
|
|
||||||
kshstate_v.lcg_state_ = 5381;
|
|
||||||
|
|
||||||
if ((s = mksh_init(argc, argv))) {
|
|
||||||
/* put more entropy into the LCG */
|
|
||||||
change_random(s, sizeof(*s));
|
|
||||||
/* doesn't return */
|
/* doesn't return */
|
||||||
shell(s, true);
|
shell(s, true);
|
||||||
}
|
return (0);
|
||||||
return (1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -516,7 +545,8 @@ include(const char *name, int argc, const char **argv, int intr_ok)
|
|||||||
case LERROR:
|
case LERROR:
|
||||||
return (exstat & 0xff); /* see below */
|
return (exstat & 0xff); /* see below */
|
||||||
case LINTR:
|
case LINTR:
|
||||||
/* intr_ok is set if we are including .profile or $ENV.
|
/*
|
||||||
|
* intr_ok is set if we are including .profile or $ENV.
|
||||||
* If user ^Cs out, we don't want to kill the shell...
|
* If user ^Cs out, we don't want to kill the shell...
|
||||||
*/
|
*/
|
||||||
if (intr_ok && (exstat - 128) != SIGTERM)
|
if (intr_ok && (exstat - 128) != SIGTERM)
|
||||||
@ -587,13 +617,15 @@ shell(Source * volatile s, volatile int toplevel)
|
|||||||
if (interactive) {
|
if (interactive) {
|
||||||
if (i == LINTR)
|
if (i == LINTR)
|
||||||
shellf("\n");
|
shellf("\n");
|
||||||
/* Reset any eof that was read as part of a
|
/*
|
||||||
|
* Reset any eof that was read as part of a
|
||||||
* multiline command.
|
* multiline command.
|
||||||
*/
|
*/
|
||||||
if (Flag(FIGNOREEOF) && s->type == SEOF &&
|
if (Flag(FIGNOREEOF) && s->type == SEOF &&
|
||||||
wastty)
|
wastty)
|
||||||
s->type = SSTDIN;
|
s->type = SSTDIN;
|
||||||
/* Used by exit command to get back to
|
/*
|
||||||
|
* Used by exit command to get back to
|
||||||
* top level shell. Kind of strange since
|
* top level shell. Kind of strange since
|
||||||
* interactive is set if we are reading from
|
* interactive is set if we are reading from
|
||||||
* a tty, but to have stopped jobs, one only
|
* a tty, but to have stopped jobs, one only
|
||||||
@ -642,7 +674,8 @@ shell(Source * volatile s, volatile int toplevel)
|
|||||||
really_exit = 1;
|
really_exit = 1;
|
||||||
s->type = SSTDIN;
|
s->type = SSTDIN;
|
||||||
} else {
|
} else {
|
||||||
/* this for POSIX which says EXIT traps
|
/*
|
||||||
|
* this for POSIX which says EXIT traps
|
||||||
* shall be taken in the environment
|
* shall be taken in the environment
|
||||||
* immediately after the last command
|
* immediately after the last command
|
||||||
* executed.
|
* executed.
|
||||||
@ -742,7 +775,8 @@ quitenv(struct shf *shf)
|
|||||||
if (ep->savefd[2]) /* Clear any write errors */
|
if (ep->savefd[2]) /* Clear any write errors */
|
||||||
shf_reopen(2, SHF_WR, shl_out);
|
shf_reopen(2, SHF_WR, shl_out);
|
||||||
}
|
}
|
||||||
/* Bottom of the stack.
|
/*
|
||||||
|
* Bottom of the stack.
|
||||||
* Either main shell is exiting or cleanup_parents_env() was called.
|
* Either main shell is exiting or cleanup_parents_env() was called.
|
||||||
*/
|
*/
|
||||||
if (ep->oenv == NULL) {
|
if (ep->oenv == NULL) {
|
||||||
@ -755,7 +789,8 @@ quitenv(struct shf *shf)
|
|||||||
if (ep->flags & EF_FAKE_SIGDIE) {
|
if (ep->flags & EF_FAKE_SIGDIE) {
|
||||||
int sig = exstat - 128;
|
int sig = exstat - 128;
|
||||||
|
|
||||||
/* ham up our death a bit (AT&T ksh
|
/*
|
||||||
|
* ham up our death a bit (AT&T ksh
|
||||||
* only seems to do this for SIGTERM)
|
* only seems to do this for SIGTERM)
|
||||||
* Don't do it for SIGQUIT, since we'd
|
* Don't do it for SIGQUIT, since we'd
|
||||||
* dump a core..
|
* dump a core..
|
||||||
@ -839,7 +874,8 @@ remove_temps(struct temp *tp)
|
|||||||
unlink(tp->name);
|
unlink(tp->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise tty_fd. Used for saving/reseting tty modes upon
|
/*
|
||||||
|
* Initialise tty_fd. Used for saving/reseting tty modes upon
|
||||||
* foreground job completion and for setting up tty process group.
|
* foreground job completion and for setting up tty process group.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -937,7 +973,8 @@ warningf(bool fileline, const char *fmt, ...)
|
|||||||
shf_flush(shl_out);
|
shf_flush(shl_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used by built-in utilities to prefix shell and utility name to message
|
/*
|
||||||
|
* Used by built-in utilities to prefix shell and utility name to message
|
||||||
* (also unwinds environments for special builtins).
|
* (also unwinds environments for special builtins).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -958,7 +995,8 @@ bi_errorf(const char *fmt, ...)
|
|||||||
shf_putchar('\n', shl_out);
|
shf_putchar('\n', shl_out);
|
||||||
}
|
}
|
||||||
shf_flush(shl_out);
|
shf_flush(shl_out);
|
||||||
/* POSIX special builtins and ksh special builtins cause
|
/*
|
||||||
|
* POSIX special builtins and ksh special builtins cause
|
||||||
* non-interactive shells to exit.
|
* non-interactive shells to exit.
|
||||||
* XXX odd use of KEEPASN; also may not want LERROR here
|
* XXX odd use of KEEPASN; also may not want LERROR here
|
||||||
*/
|
*/
|
||||||
@ -1133,7 +1171,8 @@ closepipe(int *pv)
|
|||||||
close(pv[1]);
|
close(pv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by iosetup() (deals with 2>&4, etc.), c_read, c_print to turn
|
/*
|
||||||
|
* Called by iosetup() (deals with 2>&4, etc.), c_read, c_print to turn
|
||||||
* a string (the X in 2>&X, read -uX, print -uX) into a file descriptor.
|
* a string (the X in 2>&X, read -uX, print -uX) into a file descriptor.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -1156,7 +1195,8 @@ check_fd(const char *name, int mode, const char **emsgp)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
fl &= O_ACCMODE;
|
fl &= O_ACCMODE;
|
||||||
/* X_OK is a kludge to disable this check for dups (x<&1):
|
/*
|
||||||
|
* X_OK is a kludge to disable this check for dups (x<&1):
|
||||||
* historical shells never did this check (XXX don't know what
|
* historical shells never did this check (XXX don't know what
|
||||||
* POSIX has to say).
|
* POSIX has to say).
|
||||||
*/
|
*/
|
||||||
@ -1192,7 +1232,8 @@ coproc_read_close(int fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by c_read() and by iosetup() to close the other side of the
|
/*
|
||||||
|
* Called by c_read() and by iosetup() to close the other side of the
|
||||||
* read pipe, so reads will actually terminate.
|
* read pipe, so reads will actually terminate.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -1204,7 +1245,8 @@ coproc_readw_close(int fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by c_print when a write to a fd fails with EPIPE and by iosetup
|
/*
|
||||||
|
* Called by c_print when a write to a fd fails with EPIPE and by iosetup
|
||||||
* when co-process input is dup'd
|
* when co-process input is dup'd
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -1216,7 +1258,8 @@ coproc_write_close(int fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called to check for existence of/value of the co-process file descriptor.
|
/*
|
||||||
|
* Called to check for existence of/value of the co-process file descriptor.
|
||||||
* (Used by check_fd() and by c_read/c_print to deal with -p option).
|
* (Used by check_fd() and by c_read/c_print to deal with -p option).
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -1231,7 +1274,8 @@ coproc_getfd(int mode, const char **emsgp)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called to close file descriptors related to the coprocess (if any)
|
/*
|
||||||
|
* called to close file descriptors related to the coprocess (if any)
|
||||||
* Should be called with SIGCHLD blocked.
|
* Should be called with SIGCHLD blocked.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
25
misc.c
25
misc.c
@ -29,15 +29,10 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.149 2011/01/09 21:57:27 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.150 2011/01/21 21:04:45 tg Exp $");
|
||||||
|
|
||||||
unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */
|
unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */
|
||||||
|
|
||||||
#if !HAVE_SETRESUGID
|
|
||||||
uid_t kshuid;
|
|
||||||
gid_t kshgid, kshegid;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int do_gmatch(const unsigned char *, const unsigned char *,
|
static int do_gmatch(const unsigned char *, const unsigned char *,
|
||||||
const unsigned char *, const unsigned char *);
|
const unsigned char *, const unsigned char *);
|
||||||
static const unsigned char *cclass(const unsigned char *, int);
|
static const unsigned char *cclass(const unsigned char *, int);
|
||||||
@ -233,9 +228,10 @@ change_flag(enum sh_flag f, int what, unsigned int newval)
|
|||||||
Flag(f) = (unsigned char)newval;
|
Flag(f) = (unsigned char)newval;
|
||||||
} else if (f == FPRIVILEGED && oldval && !newval) {
|
} else if (f == FPRIVILEGED && oldval && !newval) {
|
||||||
/* Turning off -p? */
|
/* Turning off -p? */
|
||||||
#if HAVE_SETRESUGID
|
|
||||||
gid_t kshegid = getgid();
|
|
||||||
|
|
||||||
|
/*XXX this can probably be optimised */
|
||||||
|
kshegid = kshgid = getgid();
|
||||||
|
#if HAVE_SETRESUGID
|
||||||
DO_SETUID(setresgid, (kshegid, kshegid, kshegid));
|
DO_SETUID(setresgid, (kshegid, kshegid, kshegid));
|
||||||
#if HAVE_SETGROUPS
|
#if HAVE_SETGROUPS
|
||||||
/* setgroups doesn't EAGAIN on Linux */
|
/* setgroups doesn't EAGAIN on Linux */
|
||||||
@ -246,7 +242,7 @@ change_flag(enum sh_flag f, int what, unsigned int newval)
|
|||||||
/* seteuid, setegid, setgid don't EAGAIN on Linux */
|
/* seteuid, setegid, setgid don't EAGAIN on Linux */
|
||||||
seteuid(ksheuid = kshuid = getuid());
|
seteuid(ksheuid = kshuid = getuid());
|
||||||
DO_SETUID(setuid, (ksheuid));
|
DO_SETUID(setuid, (ksheuid));
|
||||||
setegid(kshegid = kshgid = getgid());
|
setegid(kshegid);
|
||||||
setgid(kshegid);
|
setgid(kshegid);
|
||||||
#endif
|
#endif
|
||||||
} else if ((f == FPOSIX || f == FSH) && newval) {
|
} else if ((f == FPOSIX || f == FSH) && newval) {
|
||||||
@ -1305,9 +1301,6 @@ chvt(const char *fn)
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* for entropy */
|
|
||||||
kshstate_f.h = evilhash(fn);
|
|
||||||
|
|
||||||
if (*fn == '-') {
|
if (*fn == '-') {
|
||||||
memcpy(dv, "-/dev/null", sizeof("-/dev/null"));
|
memcpy(dv, "-/dev/null", sizeof("-/dev/null"));
|
||||||
fn = dv + 1;
|
fn = dv + 1;
|
||||||
@ -1362,6 +1355,14 @@ chvt(const char *fn)
|
|||||||
ksh_dup2(fd, 2, false);
|
ksh_dup2(fd, 2, false);
|
||||||
if (fd > 2)
|
if (fd > 2)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
{
|
||||||
|
register uint32_t h;
|
||||||
|
|
||||||
|
oaat1_init_impl(h);
|
||||||
|
oaat1_addmem_impl(h, &rndsetupstate, sizeof(rndsetupstate));
|
||||||
|
oaat1_fini_impl(h);
|
||||||
|
rndset((long)h);
|
||||||
|
}
|
||||||
chvt_reinit();
|
chvt_reinit();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
10
mksh.1
10
mksh.1
@ -1,4 +1,4 @@
|
|||||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.244 2011/01/09 21:57:27 tg Exp $
|
.\" $MirOS: src/bin/mksh/mksh.1,v 1.245 2011/01/21 21:04:45 tg Exp $
|
||||||
.\" $OpenBSD: ksh.1,v 1.138 2010/09/20 07:41:17 jmc Exp $
|
.\" $OpenBSD: ksh.1,v 1.138 2010/09/20 07:41:17 jmc Exp $
|
||||||
.\"-
|
.\"-
|
||||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
@ -72,7 +72,7 @@
|
|||||||
.\" with -mandoc, it might implement .Mx itself, but we want to
|
.\" with -mandoc, it might implement .Mx itself, but we want to
|
||||||
.\" use our own definition. And .Dd must come *first*, always.
|
.\" use our own definition. And .Dd must come *first*, always.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: January 9 2011 $
|
.Dd $Mdocdate: January 21 2011 $
|
||||||
.\"
|
.\"
|
||||||
.\" Check which macro package we use
|
.\" Check which macro package we use
|
||||||
.\"
|
.\"
|
||||||
@ -1768,6 +1768,12 @@ above for details.
|
|||||||
.Sy Note :
|
.Sy Note :
|
||||||
This parameter is not imported from the environment when the shell is
|
This parameter is not imported from the environment when the shell is
|
||||||
started.
|
started.
|
||||||
|
.It Ev KSHEGID
|
||||||
|
The effective group id of the shell.
|
||||||
|
.It Ev KSHGID
|
||||||
|
The real group id of the shell.
|
||||||
|
.It Ev KSHUID
|
||||||
|
The real user id of the shell.
|
||||||
.It Ev KSH_VERSION
|
.It Ev KSH_VERSION
|
||||||
The name and version of the shell (read-only).
|
The name and version of the shell (read-only).
|
||||||
See also the version commands in
|
See also the version commands in
|
||||||
|
99
sh.h
99
sh.h
@ -154,7 +154,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.421 2011/01/09 21:57:29 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.422 2011/01/21 21:04:47 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R39 2011/01/08"
|
#define MKSH_VERSION "R39 2011/01/08"
|
||||||
|
|
||||||
@ -519,7 +519,7 @@ enum sh_flag {
|
|||||||
FNFLAGS /* (place holder: how many flags are there) */
|
FNFLAGS /* (place holder: how many flags are there) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Flag(f) (kshstate_v.shell_flags_[(int)(f)])
|
#define Flag(f) (shell_flags[(int)(f)])
|
||||||
#define UTFMODE Flag(FUNICODE)
|
#define UTFMODE Flag(FUNICODE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -569,46 +569,31 @@ extern struct env {
|
|||||||
#define LSHELL 8 /* return to interactive shell() */
|
#define LSHELL 8 /* return to interactive shell() */
|
||||||
#define LAEXPR 9 /* error in arithmetic expression */
|
#define LAEXPR 9 /* error in arithmetic expression */
|
||||||
|
|
||||||
/*
|
/* sort of shell global state */
|
||||||
* some kind of global shell state, for change_random() mostly
|
EXTERN pid_t procpid; /* PID of executing process */
|
||||||
*/
|
EXTERN int exstat; /* exit status */
|
||||||
|
EXTERN int subst_exstat; /* exit status of last $(..)/`..` */
|
||||||
EXTERN struct mksh_kshstate_v {
|
EXTERN short trap_exstat; /* exit status before running a trap */
|
||||||
/* for change_random */
|
EXTERN uint8_t trap_nested; /* running nested traps */
|
||||||
struct timeval cr_tv; /* timestamp */
|
EXTERN uint8_t shell_flags[FNFLAGS];
|
||||||
const void *cr_dp; /* argument address */
|
EXTERN const char *kshname; /* $0 */
|
||||||
size_t cr_dsz; /* argument length */
|
EXTERN struct {
|
||||||
uint32_t lcg_state_; /* previous LCG state */
|
uid_t kshuid_; /* real UID of shell */
|
||||||
/* global state */
|
|
||||||
pid_t procpid_; /* PID of executing process */
|
|
||||||
int exstat_; /* exit status */
|
|
||||||
int subst_exstat_; /* exit status of last $(..)/`..` */
|
|
||||||
struct env env_; /* top-level parsing & execution env. */
|
|
||||||
short trap_exstat_; /* exit status before running a trap */
|
|
||||||
uint8_t trap_nested_; /* running nested traps */
|
|
||||||
uint8_t shell_flags_[FNFLAGS];
|
|
||||||
} kshstate_v;
|
|
||||||
EXTERN struct mksh_kshstate_f {
|
|
||||||
const char *kshname_; /* $0 */
|
|
||||||
pid_t kshpid_; /* $$, shell PID */
|
|
||||||
pid_t kshpgrp_; /* process group of shell */
|
|
||||||
uid_t ksheuid_; /* effective UID of shell */
|
uid_t ksheuid_; /* effective UID of shell */
|
||||||
|
gid_t kshgid_; /* real GID of shell */
|
||||||
|
gid_t kshegid_; /* effective GID of shell */
|
||||||
|
pid_t kshpgrp_; /* process group of shell */
|
||||||
pid_t kshppid_; /* PID of parent of shell */
|
pid_t kshppid_; /* PID of parent of shell */
|
||||||
uint32_t h; /* some kind of hash */
|
pid_t kshpid_; /* $$, shell PID */
|
||||||
} kshstate_f;
|
} rndsetupstate;
|
||||||
#define kshname kshstate_f.kshname_
|
|
||||||
#define kshpid kshstate_f.kshpid_
|
|
||||||
#define procpid kshstate_v.procpid_
|
|
||||||
#define kshpgrp kshstate_f.kshpgrp_
|
|
||||||
#define ksheuid kshstate_f.ksheuid_
|
|
||||||
#define kshppid kshstate_f.kshppid_
|
|
||||||
#define exstat kshstate_v.exstat_
|
|
||||||
#define subst_exstat kshstate_v.subst_exstat_
|
|
||||||
#define trap_exstat kshstate_v.trap_exstat_
|
|
||||||
#define trap_nested kshstate_v.trap_nested_
|
|
||||||
|
|
||||||
/* evil hack: return hash(kshstate_f concat (kshstate_f'.h:=hash(arg))) */
|
#define kshpid rndsetupstate.kshpid_
|
||||||
uint32_t evilhash(const char *);
|
#define kshpgrp rndsetupstate.kshpgrp_
|
||||||
|
#define kshuid rndsetupstate.kshuid_
|
||||||
|
#define ksheuid rndsetupstate.ksheuid_
|
||||||
|
#define kshgid rndsetupstate.kshgid_
|
||||||
|
#define kshegid rndsetupstate.kshegid_
|
||||||
|
#define kshppid rndsetupstate.kshppid_
|
||||||
|
|
||||||
|
|
||||||
/* option processing */
|
/* option processing */
|
||||||
@ -1407,6 +1392,36 @@ EXTERN struct timeval j_usrtime, j_systime;
|
|||||||
'+', (unsigned long)(cnst)); \
|
'+', (unsigned long)(cnst)); \
|
||||||
} while (/* CONSTCOND */ 0)
|
} while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
|
/* Bob Jenkins' one-at-a-time hash, with better start value */
|
||||||
|
#define oaat1_init_impl(h) do { \
|
||||||
|
(h) = 0x100; \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
#define oaat1_addmem_impl(h, buf, len) do { \
|
||||||
|
register const uint8_t *oaat1_addmem_p = (const void *)(buf); \
|
||||||
|
register size_t oaat1_addmem_n = (len); \
|
||||||
|
\
|
||||||
|
while (oaat1_addmem_n--) { \
|
||||||
|
(h) += *oaat1_addmem_p++; \
|
||||||
|
(h) += (h) << 10; \
|
||||||
|
(h) ^= (h) >> 6; \
|
||||||
|
} \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
#define oaat1_addstr_impl(h, s) do { \
|
||||||
|
register const uint8_t *oaat1_addstr_p = (const void *)(s); \
|
||||||
|
register uint8_t oaat1_addstr_c; \
|
||||||
|
\
|
||||||
|
while ((oaat1_addstr_c = *oaat1_addstr_p++)) { \
|
||||||
|
h += oaat1_addstr_c; \
|
||||||
|
(h) += (h) << 10; \
|
||||||
|
(h) ^= (h) >> 6; \
|
||||||
|
} \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
#define oaat1_fini_impl(h) do { \
|
||||||
|
(h) += (h) << 3; \
|
||||||
|
(h) ^= (h) >> 11; \
|
||||||
|
(h) += (h) << 15; \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
/* lalloc.c */
|
/* lalloc.c */
|
||||||
void ainit(Area *);
|
void ainit(Area *);
|
||||||
void afreeall(Area *);
|
void afreeall(Area *);
|
||||||
@ -1614,9 +1629,6 @@ void coproc_write_close(int);
|
|||||||
int coproc_getfd(int, const char **);
|
int coproc_getfd(int, const char **);
|
||||||
void coproc_cleanup(int);
|
void coproc_cleanup(int);
|
||||||
struct temp *maketemp(Area *, Temp_type, struct temp **);
|
struct temp *maketemp(Area *, Temp_type, struct temp **);
|
||||||
#define hash(s) oaathash_full((const uint8_t *)(s))
|
|
||||||
uint32_t oaathash_full(register const uint8_t *);
|
|
||||||
uint32_t hashmem(const void *, size_t);
|
|
||||||
void ktinit(struct table *, Area *, size_t);
|
void ktinit(struct table *, Area *, size_t);
|
||||||
struct tbl *ktsearch(struct table *, const char *, uint32_t);
|
struct tbl *ktsearch(struct table *, const char *, uint32_t);
|
||||||
struct tbl *ktenter(struct table *, const char *, uint32_t);
|
struct tbl *ktenter(struct table *, const char *, uint32_t);
|
||||||
@ -1712,11 +1724,12 @@ const char *skip_wdvarname(const char *, int);
|
|||||||
int is_wdvarname(const char *, int);
|
int is_wdvarname(const char *, int);
|
||||||
int is_wdvarassign(const char *);
|
int is_wdvarassign(const char *);
|
||||||
char **makenv(void);
|
char **makenv(void);
|
||||||
void change_random(const void *, size_t);
|
|
||||||
void change_winsz(void);
|
void change_winsz(void);
|
||||||
int array_ref_len(const char *);
|
int array_ref_len(const char *);
|
||||||
char *arrayname(const char *);
|
char *arrayname(const char *);
|
||||||
mksh_uari_t set_array(const char *, bool, const char **);
|
mksh_uari_t set_array(const char *, bool, const char **);
|
||||||
|
uint32_t hash(const void *);
|
||||||
|
void rndset(long);
|
||||||
|
|
||||||
enum Test_op {
|
enum Test_op {
|
||||||
TO_NONOP = 0, /* non-operator */
|
TO_NONOP = 0, /* non-operator */
|
||||||
|
135
var.c
135
var.c
@ -1,7 +1,7 @@
|
|||||||
/* $OpenBSD: var.c,v 1.34 2007/10/15 02:16:35 deraadt Exp $ */
|
/* $OpenBSD: var.c,v 1.34 2007/10/15 02:16:35 deraadt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||||
* Thorsten Glaser <tg@mirbsd.org>
|
* Thorsten Glaser <tg@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
@ -26,7 +26,7 @@
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.114 2010/09/19 19:21:20 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.115 2011/01/21 21:04:48 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables
|
* Variables
|
||||||
@ -39,6 +39,8 @@ __RCSID("$MirOS: src/bin/mksh/var.c,v 1.114 2010/09/19 19:21:20 tg Exp $");
|
|||||||
*/
|
*/
|
||||||
static struct tbl vtemp;
|
static struct tbl vtemp;
|
||||||
static struct table specials;
|
static struct table specials;
|
||||||
|
static uint32_t lcg_state = 5381;
|
||||||
|
|
||||||
static char *formatstr(struct tbl *, const char *);
|
static char *formatstr(struct tbl *, const char *);
|
||||||
static void exportprep(struct tbl *, const char *);
|
static void exportprep(struct tbl *, const char *);
|
||||||
static int special(const char *);
|
static int special(const char *);
|
||||||
@ -50,9 +52,6 @@ static int getint(struct tbl *, mksh_ari_t *, bool);
|
|||||||
static mksh_ari_t intval(struct tbl *);
|
static mksh_ari_t intval(struct tbl *);
|
||||||
static struct tbl *arraysearch(struct tbl *, uint32_t);
|
static struct tbl *arraysearch(struct tbl *, uint32_t);
|
||||||
static const char *array_index_calc(const char *, bool *, uint32_t *);
|
static const char *array_index_calc(const char *, bool *, uint32_t *);
|
||||||
static uint32_t oaathash_update(register uint32_t, register const uint8_t *,
|
|
||||||
register size_t);
|
|
||||||
static uint32_t oaathash_finalise(register uint32_t);
|
|
||||||
|
|
||||||
uint8_t set_refflag = 0;
|
uint8_t set_refflag = 0;
|
||||||
|
|
||||||
@ -986,79 +985,6 @@ makenv(void)
|
|||||||
return ((char **)XPclose(denv));
|
return ((char **)XPclose(denv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bob Jenkins' one-at-a-time hash */
|
|
||||||
static uint32_t
|
|
||||||
oaathash_update(register uint32_t h, register const uint8_t *cp,
|
|
||||||
register size_t n)
|
|
||||||
{
|
|
||||||
while (n--) {
|
|
||||||
h += *cp++;
|
|
||||||
h += h << 10;
|
|
||||||
h ^= h >> 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t
|
|
||||||
oaathash_finalise(register uint32_t h)
|
|
||||||
{
|
|
||||||
h += h << 3;
|
|
||||||
h ^= h >> 11;
|
|
||||||
h += h << 15;
|
|
||||||
|
|
||||||
return (h);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
oaathash_full(register const uint8_t *bp)
|
|
||||||
{
|
|
||||||
register uint32_t h = 0;
|
|
||||||
register uint8_t c;
|
|
||||||
|
|
||||||
while ((c = *bp++)) {
|
|
||||||
h += c;
|
|
||||||
h += h << 10;
|
|
||||||
h ^= h >> 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (oaathash_finalise(h));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
change_random(const void *vp, size_t n)
|
|
||||||
{
|
|
||||||
register uint32_t h = 0x100;
|
|
||||||
#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
|
|
||||||
uint32_t i;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kshstate_v.cr_dp = vp;
|
|
||||||
kshstate_v.cr_dsz = n;
|
|
||||||
gettimeofday(&kshstate_v.cr_tv, NULL);
|
|
||||||
h = oaathash_update(oaathash_update(h, (void *)&kshstate_v,
|
|
||||||
sizeof(kshstate_v)), vp, n);
|
|
||||||
kshstate_v.lcg_state_ = oaathash_finalise(h);
|
|
||||||
|
|
||||||
#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
|
|
||||||
/*
|
|
||||||
* either we have very check entropy get and push available,
|
|
||||||
* with malloc() pulling in this code already anyway, or the
|
|
||||||
* user requested us to use the old functions
|
|
||||||
*/
|
|
||||||
#if defined(arc4random_pushb_fast)
|
|
||||||
arc4random_pushb_fast(&kshstate_v.lcg_state_,
|
|
||||||
sizeof(kshstate_v.lcg_state_));
|
|
||||||
i = arc4random();
|
|
||||||
#else
|
|
||||||
i = arc4random_pushb(&kshstate_v.lcg_state_,
|
|
||||||
sizeof(kshstate_v.lcg_state_));
|
|
||||||
#endif
|
|
||||||
h = oaathash_update(h, (void *)&i, sizeof(i));
|
|
||||||
kshstate_v.lcg_state_ = oaathash_finalise(h);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle special variables with side effects - PATH, SECONDS.
|
* handle special variables with side effects - PATH, SECONDS.
|
||||||
*/
|
*/
|
||||||
@ -1113,8 +1039,7 @@ getspec(struct tbl *vp)
|
|||||||
* this is the same Linear Congruential PRNG as Borland
|
* this is the same Linear Congruential PRNG as Borland
|
||||||
* C/C++ allegedly uses in its built-in rand() function
|
* C/C++ allegedly uses in its built-in rand() function
|
||||||
*/
|
*/
|
||||||
i = ((kshstate_v.lcg_state_ =
|
i = ((lcg_state = 22695477 * lcg_state + 1) >> 16) & 0x7FFF;
|
||||||
22695477 * kshstate_v.lcg_state_ + 1) >> 16) & 0x7FFF;
|
|
||||||
break;
|
break;
|
||||||
case V_HISTSIZE:
|
case V_HISTSIZE:
|
||||||
i = histsize;
|
i = histsize;
|
||||||
@ -1181,17 +1106,17 @@ setspec(struct tbl *vp)
|
|||||||
stat(s, &statb) == 0 && S_ISDIR(statb.st_mode))
|
stat(s, &statb) == 0 && S_ISDIR(statb.st_mode))
|
||||||
strdupx(tmpdir, s, APERM);
|
strdupx(tmpdir, s, APERM);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
#if HAVE_PERSISTENT_HISTORY
|
#if HAVE_PERSISTENT_HISTORY
|
||||||
case V_HISTFILE:
|
case V_HISTFILE:
|
||||||
sethistfile(str_val(vp));
|
sethistfile(str_val(vp));
|
||||||
break;
|
return;
|
||||||
#endif
|
#endif
|
||||||
case V_TMOUT:
|
case V_TMOUT:
|
||||||
/* AT&T ksh seems to do this (only listen if integer) */
|
/* AT&T ksh seems to do this (only listen if integer) */
|
||||||
if (vp->flag & INTEGER)
|
if (vp->flag & INTEGER)
|
||||||
ksh_tmout = vp->val.i >= 0 ? vp->val.i : 0;
|
ksh_tmout = vp->val.i >= 0 ? vp->val.i : 0;
|
||||||
break;
|
return;
|
||||||
|
|
||||||
/* common sub-cases */
|
/* common sub-cases */
|
||||||
case V_OPTIND:
|
case V_OPTIND:
|
||||||
@ -1232,7 +1157,7 @@ setspec(struct tbl *vp)
|
|||||||
* mksh R39d+ no longer has the traditional repeatability
|
* mksh R39d+ no longer has the traditional repeatability
|
||||||
* of $RANDOM sequences, but always retains state
|
* of $RANDOM sequences, but always retains state
|
||||||
*/
|
*/
|
||||||
change_random(&i, sizeof(i));
|
rndset((long)i);
|
||||||
break;
|
break;
|
||||||
case V_SECONDS:
|
case V_SECONDS:
|
||||||
{
|
{
|
||||||
@ -1476,12 +1401,42 @@ change_winsz(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
evilhash(const char *s)
|
hash(const void *s)
|
||||||
{
|
{
|
||||||
register uint32_t h = 0x100;
|
register uint32_t h;
|
||||||
|
|
||||||
h = oaathash_update(h, (void *)&kshstate_f, sizeof(kshstate_f));
|
oaat1_init_impl(h);
|
||||||
kshstate_f.h = oaathash_full((const uint8_t *)s);
|
oaat1_addstr_impl(h, s);
|
||||||
return (oaathash_finalise(oaathash_update(h,
|
oaat1_fini_impl(h);
|
||||||
(void *)&kshstate_f.h, sizeof(kshstate_f.h))));
|
return (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rndset(long v)
|
||||||
|
{
|
||||||
|
register uint32_t h;
|
||||||
|
|
||||||
|
oaat1_init_impl(h);
|
||||||
|
oaat1_addmem_impl(h, &lcg_state, sizeof(lcg_state));
|
||||||
|
oaat1_addmem_impl(h, &v, sizeof(v));
|
||||||
|
|
||||||
|
#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
|
||||||
|
/*
|
||||||
|
* either we have very chap entropy get and push available,
|
||||||
|
* with malloc() pulling in this code already anyway, or the
|
||||||
|
* user requested us to use the old functions
|
||||||
|
*/
|
||||||
|
lcg_state = h;
|
||||||
|
oaat1_fini_impl(lcg_state);
|
||||||
|
#if defined(arc4random_pushb_fast)
|
||||||
|
arc4random_pushb_fast(&lcg_state, sizeof(lcg_state));
|
||||||
|
lcg_state = arc4random();
|
||||||
|
#else
|
||||||
|
lcg_state = arc4random_pushb(&lcg_state, sizeof(lcg_state));
|
||||||
|
#endif
|
||||||
|
oaat1_addmem_impl(h, &lcg_state, sizeof(lcg_state));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
oaat1_fini_impl(h);
|
||||||
|
lcg_state = h;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user