fix jobless mksh so much to make it work on Minix 3

This commit is contained in:
tg 2009-04-05 12:35:32 +00:00
parent 97c9d172d7
commit 398be9867a
7 changed files with 94 additions and 30 deletions

View File

@ -1,5 +1,5 @@
#!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.383 2009/04/05 12:21:14 tg Exp $'
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.384 2009/04/05 12:35:28 tg Exp $'
#-
# Environment used: CC CFLAGS CPPFLAGS LDFLAGS LIBS NOWARN NROFF TARGET_OS
# CPPFLAGS recognised: MKSH_SMALL MKSH_ASSUME_UTF8 MKSH_NOPWNAM MKSH_NOVI
@ -324,9 +324,9 @@ MidnightBSD)
Minix)
CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_POSIX_1_SOURCE=2"
CPPFLAGS="$CPPFLAGS -DMKSH_UNEMPLOYED -D_MINIX"
warn=' and will currently not work'
# warn=" but might work with the GNU tools"
# warn="$warn${nl}but not with ACK - /usr/bin/cc - yet)"
warn=" but will probably work with GCC"
warn="$warn${nl}but not with ACK - /usr/bin/cc - yet)"
oldish_ed=no-stderr-ed # /usr/bin/ed(!) is broken
: ${HAVE_SETLOCALE_CTYPE=0}
;;
MirBSD)

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.267 2009/04/03 09:39:03 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.268 2009/04/05 12:35:29 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -7,7 +7,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout:
@(#)MIRBSD KSH R37 2009/04/03
@(#)MIRBSD KSH R37 2009/04/05
description:
Check version of shell.
stdin:

View File

@ -5,7 +5,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.102 2009/04/03 09:45:23 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.103 2009/04/05 12:35:30 tg Exp $");
/* A leading = means assignments before command are kept;
* a leading * means a POSIX special builtin;
@ -51,8 +51,10 @@ const struct builtin mkshbuiltins[] = {
{"=typeset", c_typeset},
{"+unalias", c_unalias},
{"whence", c_whence},
#ifndef MKSH_UNEMPLOYED
{"+bg", c_fgbg},
{"+fg", c_fgbg},
#endif
{"bind", c_bind},
#if HAVE_MKNOD
{"mknod", c_mknod},
@ -1238,6 +1240,7 @@ c_jobs(const char **wp)
return rv;
}
#ifndef MKSH_UNEMPLOYED
int
c_fgbg(const char **wp)
{
@ -1258,6 +1261,7 @@ c_fgbg(const char **wp)
rv = j_resume("%%", bg);
return bg ? 0 : rv;
}
#endif
/* format a single kill item */
static char *

68
jobs.c
View File

@ -2,7 +2,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.48 2009/04/03 09:48:10 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.49 2009/04/05 12:35:31 tg Exp $");
/* Order important! */
#define PRUNNING 0
@ -59,8 +59,10 @@ struct job {
Proc *proc_list; /* process list */
Proc *last_proc; /* last process in list */
Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
#ifndef MKSH_UNEMPLOYED
struct termios ttystate;/* saved tty state for stopped jobs */
pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */
#endif
};
/* Flags for j_waitj() */
@ -102,10 +104,12 @@ static int32_t njobs; /* # of jobs started */
/* held_sigchld is set if sigchld occurs before a job is completely started */
static volatile sig_atomic_t held_sigchld;
#ifndef MKSH_UNEMPLOYED
static struct shf *shl_j;
static bool ttypgrp_ok; /* set if can use tty pgrps */
static pid_t restore_ttypgrp = -1;
static int const tt_sigs[] = { SIGTSTP, SIGTTIN, SIGTTOU };
#endif
static void j_set_async(Job *);
static void j_startjob(Job *);
@ -122,8 +126,14 @@ static int kill_job(Job *, int);
/* initialise job control */
void
j_init(int mflagset)
j_init(void)
{
#ifndef MKSH_UNEMPLOYED
bool mflagset = Flag(FMONITOR) != 127;
#endif
Flag(FMONITOR) = 0;
(void)sigemptyset(&sm_default);
sigprocmask(SIG_SETMASK, &sm_default, NULL);
@ -136,7 +146,6 @@ j_init(int mflagset)
#ifndef MKSH_UNEMPLOYED
if (!mflagset && Flag(FTALKING))
Flag(FMONITOR) = 1;
#endif
/* shl_j is used to do asynchronous notification (used in
* an interrupt handler, so need a distinct shf)
@ -160,7 +169,9 @@ j_init(int mflagset)
/* j_change() calls tty_init() */
if (Flag(FMONITOR))
j_change();
else if (Flag(FTALKING))
else
#endif
if (Flag(FTALKING))
tty_init(true, true);
}
@ -183,18 +194,21 @@ j_exit(void)
kill_job(j, SIGHUP);
else
killpg(j->pgrp, SIGHUP);
#ifndef MKSH_UNEMPLOYED
if (j->state == PSTOPPED) {
if (j->pgrp == 0)
kill_job(j, SIGCONT);
else
killpg(j->pgrp, SIGCONT);
}
#endif
}
}
if (killed)
sleep(1);
j_notify();
#ifndef MKSH_UNEMPLOYED
if (kshpid == procpid && restore_ttypgrp >= 0) {
/* Need to restore the tty pgrp to what it was when the
* shell started up, so that the process that started us
@ -210,8 +224,10 @@ j_exit(void)
Flag(FMONITOR) = 0;
j_change();
}
#endif
}
#ifndef MKSH_UNEMPLOYED
/* turn job control on or off according to Flag(FMONITOR) */
void
j_change(void)
@ -288,6 +304,7 @@ j_change(void)
tty_close();
}
}
#endif
/* execute tree in child subprocess */
int
@ -377,6 +394,7 @@ exchild(struct op *t, int flags,
change_random(((unsigned long)p->pid << 1) | (ischild ? 1 : 0));
#endif
#ifndef MKSH_UNEMPLOYED
/* job control set up */
if (Flag(FMONITOR) && !(flags&XXCOM)) {
int dotty = 0;
@ -392,6 +410,7 @@ exchild(struct op *t, int flags,
if (ttypgrp_ok && dotty && !(flags & XBGND))
tcsetpgrp(tty_fd, j->pgrp);
}
#endif
/* used to close pipe input fd */
if (close_fd >= 0 && (((flags & XPCLOSE) && !ischild) ||
@ -403,6 +422,7 @@ exchild(struct op *t, int flags,
coproc_cleanup(false);
sigprocmask(SIG_SETMASK, &omask, NULL);
cleanup_parents_env();
#ifndef MKSH_UNEMPLOYED
/* If FMONITOR or FTALKING is set, these signals are ignored,
* if neither FMONITOR nor FTALKING are set, the signals have
* their inherited values.
@ -412,6 +432,7 @@ exchild(struct op *t, int flags,
setsig(&sigtraps[tt_sigs[i]], SIG_DFL,
SS_RESTORE_DFL|SS_FORCE);
}
#endif
#if HAVE_NICE
if (Flag(FBGNICE) && (flags & XBGND))
(void)nice(4);
@ -429,8 +450,10 @@ exchild(struct op *t, int flags,
}
remove_job(j, "child"); /* in case of $(jobs) command */
nzombie = 0;
#ifndef MKSH_UNEMPLOYED
ttypgrp_ok = false;
Flag(FMONITOR) = 0;
#endif
Flag(FTALKING) = 0;
tty_close();
cleartraps();
@ -591,8 +614,10 @@ j_kill(const char *cp, int sig)
rv = 1;
}
} else {
#ifndef MKSH_UNEMPLOYED
if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP))
(void) killpg(j->pgrp, SIGCONT);
(void)killpg(j->pgrp, SIGCONT);
#endif
if (killpg(j->pgrp, sig) < 0) {
bi_errorf("%s: %s", cp, strerror(errno));
rv = 1;
@ -604,6 +629,7 @@ j_kill(const char *cp, int sig)
return rv;
}
#ifndef MKSH_UNEMPLOYED
/* fg and bg built-ins: called only if Flag(FMONITOR) set */
int
j_resume(const char *cp, int bg)
@ -705,6 +731,7 @@ j_resume(const char *cp, int bg)
sigprocmask(SIG_SETMASK, &omask, NULL);
return rv;
}
#endif
/* are there any running or stopped jobs ? */
int
@ -714,8 +741,10 @@ j_stopped_running(void)
int which = 0;
for (j = job_list; j != NULL; j = j->next) {
#ifndef MKSH_UNEMPLOYED
if (j->ppid == procpid && j->state == PSTOPPED)
which |= 1;
#endif
if (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid &&
j->ppid == procpid && j->state == PRUNNING)
which |= 2;
@ -803,8 +832,10 @@ j_notify(void)
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
for (j = job_list; j; j = j->next) {
#ifndef MKSH_UNEMPLOYED
if (Flag(FMONITOR) && (j->flags & JF_CHANGED))
j_print(j, JP_MEDIUM, shl_out);
#endif
/* Remove job after doing reports so there aren't
* multiple +/- jobs.
*/
@ -932,9 +963,8 @@ j_waitj(Job *j,
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
if (j->flags & JF_FG) {
int status;
j->flags &= ~JF_FG;
#ifndef MKSH_UNEMPLOYED
if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
/*
* Save the tty's current pgrp so it can be restored
@ -959,6 +989,7 @@ j_waitj(Job *j,
tcgetattr(tty_fd, &j->ttystate);
}
}
#endif
if (tty_fd >= 0) {
/* Only restore tty settings if job was originally
* started in the foreground. Problems can be
@ -988,16 +1019,22 @@ j_waitj(Job *j,
j->flags &= ~JF_USETTYMODE;
}
}
#ifndef MKSH_UNEMPLOYED
/* If it looks like user hit ^C to kill a job, pretend we got
* one too to break out of for loops, etc. (at&t ksh does this
* even when not monitoring, but this doesn't make sense since
* a tty generated ^C goes to the whole process group)
*/
status = j->last_proc->status;
if (Flag(FMONITOR) && j->state == PSIGNALLED &&
(WIFSIGNALED(status)) &&
(sigtraps[WTERMSIG(status)].flags & TF_TTY_INTR))
trapsig(WTERMSIG(status));
{
int status;
status = j->last_proc->status;
if (Flag(FMONITOR) && j->state == PSIGNALLED &&
(WIFSIGNALED(status)) &&
(sigtraps[WTERMSIG(status)].flags & TF_TTY_INTR))
trapsig(WTERMSIG(status));
}
#endif
}
j_usrtime = j->usrtime;
@ -1072,9 +1109,12 @@ j_sigchld(int sig __unused)
timersub(&j->systime, &ru0.ru_stime, &j->systime);
ru0 = ru1;
p->status = status;
#ifndef MKSH_UNEMPLOYED
if (WIFSTOPPED(status))
p->state = PSTOPPED;
else if (WIFSIGNALED(status))
else
#endif
if (WIFSIGNALED(status))
p->state = PSIGNALLED;
else
p->state = PEXITED;
@ -1152,6 +1192,7 @@ check_job(Job *j)
}
j->flags |= JF_CHANGED;
#ifndef MKSH_UNEMPLOYED
if (Flag(FMONITOR) && !(j->flags & JF_XXCOM)) {
/* Only put stopped jobs at the front to avoid confusing
* the user (don't want finished jobs effecting %+ or %-)
@ -1180,6 +1221,7 @@ check_job(Job *j)
remove_job(j, "notify");
}
}
#endif
if (!Flag(FMONITOR) && !(j->flags & (JF_WAITING|JF_FG)) &&
j->state != PSTOPPED) {
if (j == async_job || (j->flags & JF_KNOWN)) {

11
main.c
View File

@ -13,7 +13,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.123 2009/04/05 11:44:56 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.124 2009/04/05 12:35:31 tg Exp $");
extern char **environ;
@ -40,8 +40,11 @@ static const char *initcoms[] = {
"alias",
"hash=alias -t", /* not "alias -t --": hash -r needs to work */
"type=whence -v",
#ifndef notyet_MKSH_UNEMPLOYED
/* the alias list must be constant, for the regression test suite */
"stop=kill -STOP",
"suspend=kill -STOP $$",
#endif
"autoload=typeset -fu",
"functions=typeset -f",
"history=fc -l",
@ -309,10 +312,8 @@ main(int argc, const char *argv[])
reset_nonblock(0);
/* initialise job control */
i = Flag(FMONITOR) != 127;
Flag(FMONITOR) = 0;
j_init(i);
/* Do this after j_init(), as tty_fd is not initialised 'til then */
j_init();
/* Do this after j_init(), as tty_fd is not initialised until then */
if (Flag(FTALKING)) {
#ifndef MKSH_ASSUME_UTF8
#define isuc(x) (((x) != NULL) && \

13
misc.c
View File

@ -9,7 +9,7 @@
#include <grp.h>
#endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.101 2009/04/03 10:54:58 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.102 2009/04/05 12:35:32 tg Exp $");
#undef USE_CHVT
#if defined(TIOCSCTTY) && !defined(MKSH_SMALL)
@ -100,13 +100,19 @@ const struct shoption options[] = {
{ "keyword", 'k', OF_ANY },
{ "login", 'l', OF_CMDLINE },
{ "markdirs", 'X', OF_ANY },
#ifndef MKSH_UNEMPLOYED
{ "monitor", 'm', OF_ANY },
#else
{ NULL, 'm', 0 }, /* needed */
#endif
{ "noclobber", 'C', OF_ANY },
{ "noexec", 'n', OF_ANY },
{ "noglob", 'f', OF_ANY },
{ "nohup", 0, OF_ANY },
{ "nolog", 0, OF_ANY }, /* no effect */
#ifndef MKSH_UNEMPLOYED
{ "notify", 'b', OF_ANY },
#endif
{ "nounset", 'u', OF_ANY },
{ "physical", 0, OF_ANY }, /* non-standard */
{ "posix", 0, OF_ANY }, /* non-standard */
@ -219,10 +225,13 @@ change_flag(enum sh_flag f,
oldval = Flag(f);
Flag(f) = newval ? 1 : 0; /* needed for tristates */
#ifndef MKSH_UNEMPLOYED
if (f == FMONITOR) {
if (what != OF_CMDLINE && newval != oldval)
j_change();
} else if ((
} else
#endif
if ((
#ifndef MKSH_NOVI
f == FVI ||
#endif

14
sh.h
View File

@ -102,9 +102,9 @@
#define __SCCSID(x) __IDSTRING(sccsid,x)
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.287 2009/04/03 09:39:07 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.288 2009/04/05 12:35:32 tg Exp $");
#endif
#define MKSH_VERSION "R37 2009/04/03"
#define MKSH_VERSION "R37 2009/04/05"
#ifndef MKSH_INCLUDES_ONLY
@ -512,7 +512,9 @@ enum sh_flag {
FNOGLOB, /* -f: don't do file globbing */
FNOHUP, /* -H: don't kill running jobs when login shell exits */
FNOLOG, /* don't save functions in history (ignored) */
#ifndef MKSH_UNEMPLOYED
FNOTIFY, /* -b: asynchronous job completion notification */
#endif
FNOUNSET, /* -u: using an unset var is an error */
FPHYSICAL, /* -o physical: don't do logical cds/pwds */
FPOSIX, /* -o posix (try to be more compatible) */
@ -1333,7 +1335,9 @@ int c_alias(const char **);
int c_unalias(const char **);
int c_let(const char **);
int c_jobs(const char **);
#ifndef MKSH_UNEMPLOYED
int c_fgbg(const char **);
#endif
int c_kill(const char **);
void getopts_reset(int);
int c_getopts(const char **);
@ -1398,15 +1402,19 @@ void restore_pipe(int);
int setsig(Trap *, sig_t, int);
void setexecsig(Trap *, int);
/* jobs.c */
void j_init(int);
void j_init(void);
void j_exit(void);
#ifndef MKSH_UNEMPLOYED
void j_change(void);
#endif
int exchild(struct op *, int, volatile int *, int);
void startlast(void);
int waitlast(void);
int waitfor(const char *, int *);
int j_kill(const char *, int);
#ifndef MKSH_UNEMPLOYED
int j_resume(const char *, int);
#endif
int j_jobs(const char *, int, int);
int j_njobs(void);
void j_notify(void);