support n̲o̲t̲ fork(2)ing for -T (by prepending the tty with ‘!’); especially useful on Linux since our own setsid(2) is more annoying; gets rid of the need for oneit_lite and similar hacks; WARNING: also removes chown/chmod on the tty!

This commit is contained in:
tg 2013-06-03 22:28:06 +00:00
parent 4e1196239a
commit 8e6b0f712a
3 changed files with 86 additions and 56 deletions

19
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.265 2013/06/02 03:09:16 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.266 2013/06/03 22:28:04 tg Exp $");
extern char **environ;
@ -48,6 +48,7 @@ extern char **environ;
static uint8_t isuc(const char *);
static int main_init(int, const char *[], Source **, struct block **);
uint32_t chvt_rndsetup(const void *, size_t);
void chvt_reinit(void);
static void reclaim(void);
static void remove_temps(struct temp *);
@ -137,15 +138,25 @@ rndsetup(void)
/* introduce variation (and yes, second arg MBZ for portability) */
mksh_TIME(bufptr->tv);
h = chvt_rndsetup(bufptr, sizeof(*bufptr));
afree(cp, APERM);
return ((mksh_uari_t)h);
}
uint32_t
chvt_rndsetup(const void *bp, size_t sz)
{
register uint32_t h;
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));
NZATUpdateMem(h, bp, sz);
NZAATFinish(h);
afree(cp, APERM);
return ((mksh_uari_t)h);
return (h);
}
void

91
misc.c
View File

@ -30,7 +30,7 @@
#include <grp.h>
#endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.211 2013/05/02 20:21:44 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.212 2013/06/03 22:28:05 tg Exp $");
#define KSH_CHVT_FLAG
#ifdef MKSH_SMALL
@ -54,7 +54,7 @@ static int do_gmatch(const unsigned char *, const unsigned char *,
const unsigned char *, const unsigned char *);
static const unsigned char *cclass(const unsigned char *, unsigned char);
#ifdef KSH_CHVT_CODE
static void chvt(const char *);
static void chvt(const Getopt *);
#endif
/*XXX this should go away */
@ -414,7 +414,7 @@ parse_args(const char **argv,
errorf("no TIOCSCTTY ioctl");
#else
change_flag(FTALKING, OF_CMDLINE, true);
chvt(go.optarg);
chvt(&go);
break;
#endif
#endif
@ -1925,59 +1925,69 @@ c_cd(const char **wp)
#ifdef KSH_CHVT_CODE
extern uint32_t chvt_rndsetup(const void *, size_t);
extern void chvt_reinit(void);
static void
chvt(const char *fn)
chvt(const Getopt *go)
{
char dv[20];
struct stat sb;
const char *dv = go->optarg;
char *cp = NULL;
int fd;
if (*fn == '-') {
memcpy(dv, "-/dev/null", sizeof("-/dev/null"));
fn = dv + 1;
} else {
if (stat(fn, &sb)) {
memcpy(dv, "/dev/ttyC", 9);
strlcpy(dv + 9, fn, sizeof(dv) - 9);
switch (*dv) {
case '-':
dv = "/dev/null";
break;
case '!':
++dv;
/* FALLTHROUGH */
default: {
struct stat sb;
if (stat(dv, &sb)) {
cp = shf_smprintf("/dev/ttyC%s", dv);
dv = cp;
if (stat(dv, &sb)) {
strlcpy(dv + 8, fn, sizeof(dv) - 8);
if (stat(dv, &sb))
errorf("%s: %s %s", "chvt",
"can't find tty", fn);
memmove(cp + 1, cp, /* /dev/tty */ 8);
dv = cp + 1;
if (stat(dv, &sb)) {
errorf("%s: %s: %s", "chvt",
"can't find tty", go->optarg);
}
}
fn = dv;
}
if (!(sb.st_mode & S_IFCHR))
errorf("%s %s %s", "chvt: not a char", "device", fn);
if ((sb.st_uid != 0) && chown(fn, 0, 0))
warningf(false, "%s: %s %s", "chvt", "can't chown root", fn);
if (((sb.st_mode & 07777) != 0600) && chmod(fn, (mode_t)0600))
warningf(false, "%s: %s %s", "chvt", "can't chmod 0600", fn);
errorf("%s: %s: %s", "chvt", "not a char device", dv);
#ifndef MKSH_DISABLE_REVOKE_WARNING
#if HAVE_REVOKE
if (revoke(fn))
if (revoke(dv))
#endif
warningf(false, "%s: %s %s", "chvt",
"new shell is potentially insecure, can't revoke",
fn);
dv);
#endif
}
}
if ((fd = open(fn, O_RDWR)) < 0) {
if ((fd = open(dv, O_RDWR)) < 0) {
sleep(1);
if ((fd = open(fn, O_RDWR)) < 0)
errorf("%s: %s %s", "chvt", "can't open", fn);
if ((fd = open(dv, O_RDWR)) < 0) {
errorf("%s: %s %s", "chvt", "can't open", dv);
}
}
switch (fork()) {
case -1:
errorf("%s: %s %s", "chvt", "fork", "failed");
case 0:
break;
default:
exit(0);
if (go->optarg[0] != '!') {
switch (fork()) {
case -1:
errorf("%s: %s %s", "chvt", "fork", "failed");
case 0:
break;
default:
exit(0);
}
}
if (setsid() == -1)
errorf("%s: %s %s", "chvt", "setsid", "failed");
if (fn != dv + 1) {
if (go->optarg[0] != '-') {
if (ioctl(fd, TIOCSCTTY, NULL) == -1)
errorf("%s: %s %s", "chvt", "TIOCSCTTY", "failed");
if (tcflush(fd, TCIOFLUSH))
@ -1988,14 +1998,7 @@ chvt(const char *fn)
ksh_dup2(fd, 2, false);
if (fd > 2)
close(fd);
{
register uint32_t h;
NZATInit(h);
NZATUpdateMem(h, &rndsetupstate, sizeof(rndsetupstate));
NZAATFinish(h);
rndset((unsigned long)h);
}
rndset((unsigned long)chvt_rndsetup(go, sizeof(Getopt)));
chvt_reinit();
}
#endif

32
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.315 2013/05/02 21:59:50 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.316 2013/06/03 22:28:06 tg Exp $
.\" $OpenBSD: ksh.1,v 1.146 2013/03/18 11:10:52 mpi Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always.
.\"
.Dd $Mdocdate: May 2 2013 $
.Dd $Mdocdate: June 3 2013 $
.\"
.\" Check which macro package we use, and do other -mdoc setup.
.\"
@ -157,7 +157,11 @@
.Nm
.Bk -words
.Op Fl +abCefhiklmnprUuvXx
.Op Fl T Ar /dev/ttyCn \*(Ba \-
.Oo
.Fl T Oo Ar \&! Oc Ns Ar tty
\*(Ba
.Ar \&\-
.Oc
.Op Fl +o Ar option
.Oo
.Fl c Ar string \*(Ba
@ -295,16 +299,28 @@ Redirections that create files can't be used (i.e.\&
.It Fl s
The shell reads commands from standard input; all non-option arguments
are positional parameters.
.It Fl T Ar tty
.It Fl T Ar name
Spawn
.Nm
on the
.Xr tty 4
device given.
Superuser only.
The paths
.Ar name ,
.Pa /dev/ttyC Ns Ar name
and
.Pa /dev/tty Ns Ar name
are attempted in order.
Unless
.Ar name
begins with an exclamation mark
.Pq Sq \&! ,
this is done in a subshell and returns immediately.
If
.Ar tty
is a dash, detach from controlling terminal (daemonise) instead.
.Ar name
is a dash
.Pq Sq \&\- ,
detach from controlling terminal (daemonise) instead.
.El
.Pp
In addition to the above, the options described in the
@ -6384,7 +6400,7 @@ $ /bin/sleep 666 && echo fubar
.Ed
.Pp
This document attempts to describe
.Nm mksh\ R46
.Nm mksh\ R47
and up,
compiled without any options impacting functionality, such as
.Dv MKSH_SMALL ,