integrate latest changes from oksh: Wed Sep 4 15:49:19 2013 UTC by millert

Add a proper suspend builtin that saves/restores the tty and pgrp
as needed instead of an alias that just sends SIGSTOP.  Login shells
may be suspended if they are not running in an orphan process group.
This commit is contained in:
tg 2013-09-10 17:33:04 +00:00
parent 8352fc78d3
commit 2e7509548a
8 changed files with 112 additions and 29 deletions

View File

@ -1,5 +1,5 @@
#!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.646 2013/08/23 14:07:32 tg Exp $'
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.647 2013/09/10 17:32:56 tg Exp $'
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013
@ -1598,7 +1598,7 @@ else
#define EXTERN
#define MKSH_INCLUDES_ONLY
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.646 2013/08/23 14:07:32 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.647 2013/09/10 17:32:56 tg Exp $");
int main(void) { printf("Hello, World!\n"); return (0); }
EOF
case $cm in
@ -2113,7 +2113,7 @@ addsrcs USE_PRINTF_BUILTIN printf.c
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
test -n "$LDSTATIC" && add_cppflags -DMKSH_OPTSTATIC
add_cppflags -DMKSH_BUILD_R=483
add_cppflags -DMKSH_BUILD_R=489
$e $bi$me: Finished configuration testing, now producing output.$ao

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/Makefile,v 1.125 2013/08/23 14:07:33 tg Exp $
# $MirOS: src/bin/mksh/Makefile,v 1.126 2013/09/10 17:32:57 tg Exp $
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013
@ -54,7 +54,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=483
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=489
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
COPTS+= -std=c99 -Wall
.endif

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.631 2013/08/23 14:07:34 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.632 2013/09/10 17:32:58 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 $
@ -31,7 +31,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout:
@(#)MIRBSD KSH R48 2013/08/23
@(#)MIRBSD KSH R48 2013/09/10
description:
Check version of shell.
stdin:
@ -40,7 +40,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R48 2013/08/23
@(#)LEGACY KSH R48 2013/09/10
description:
Check version of legacy shell.
stdin:
@ -6733,7 +6733,6 @@ expected-stdout:
r='fc -e -'
source='PATH=$PATH:. command .'
stop='kill -STOP'
suspend='kill -STOP $$'
type='whence -v'
---
name: aliases-1-hartz4
@ -6802,7 +6801,6 @@ expected-stdout:
r='fc -e -'
source='PATH=$PATH:. command .'
stop='kill -STOP'
suspend='kill -STOP $$'
type='whence -v'
---
name: aliases-3b
@ -6826,7 +6824,6 @@ expected-stdout:
r='fc -e -'
source='PATH=$PATH:. command .'
stop='kill -STOP'
suspend='kill -STOP $$'
type='whence -v'
---
name: aliases-2b-hartz4

32
funcs.c
View File

@ -1,5 +1,5 @@
/* $OpenBSD: c_ksh.c,v 1.33 2009/02/07 14:03:24 kili Exp $ */
/* $OpenBSD: c_sh.c,v 1.43 2013/04/19 17:39:45 deraadt Exp $ */
/* $OpenBSD: c_sh.c,v 1.44 2013/09/04 15:49:18 millert Exp $ */
/* $OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $ */
/* $OpenBSD: c_ulimit.c,v 1.17 2008/03/21 12:51:19 millert Exp $ */
@ -38,7 +38,7 @@
#endif
#endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.245 2013/09/10 16:30:49 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.246 2013/09/10 17:33:00 tg Exp $");
#if HAVE_KILLPG
/*
@ -60,6 +60,10 @@ __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.245 2013/09/10 16:30:49 tg Exp $");
#define c_ulimit c_true
#endif
#ifndef MKSH_UNEMPLOYED
static int c_suspend(const char **);
#endif
/* getn() that prints error */
static int
bi_getn(const char *as, int *ai)
@ -123,6 +127,9 @@ const struct builtin mkshbuiltins[] = {
{"*=return", c_exitreturn},
{Tsgset, c_set},
{"*=shift", c_shift},
#ifndef MKSH_UNEMPLOYED
{"suspend", c_suspend},
#endif
{"test", c_test},
{"*=times", c_times},
{"*=trap", c_trap},
@ -3843,3 +3850,24 @@ c_sleep(const char **wp)
return (rv);
}
#endif
#ifndef MKSH_UNEMPLOYED
static int
c_suspend(const char **wp)
{
if (wp[1] != NULL) {
bi_errorf("too many arguments");
return (1);
}
if (Flag(FLOGIN)) {
/* Can't suspend an orphaned process group. */
if (getpgid(kshppid) == getpgid(0) ||
getsid(kshppid) != getsid(0)) {
bi_errorf("can't suspend a login shell");
return (1);
}
}
j_suspend();
return (0);
}
#endif

52
jobs.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: jobs.c,v 1.39 2009/12/13 04:36:48 deraadt Exp $ */
/* $OpenBSD: jobs.c,v 1.40 2013/09/04 15:49:18 millert Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.101 2013/09/10 16:51:17 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.102 2013/09/10 17:33:01 tg Exp $");
#if HAVE_KILLPG
#define mksh_killpg killpg
@ -225,6 +225,54 @@ proc_errorlevel(Proc *p)
}
}
#ifndef MKSH_UNEMPLOYED
/* suspend the shell */
void
j_suspend(void)
{
struct sigaction sa, osa;
/* Restore tty and pgrp. */
if (ttypgrp_ok) {
if (tty_hasstate)
mksh_tcset(tty_fd, &tty_state);
if (restore_ttypgrp >= 0) {
if (tcsetpgrp(tty_fd, restore_ttypgrp) < 0) {
warningf(false, "%s: %s %s: %s", "j_suspend",
"tcsetpgrp", "failed", cstrerror(errno));
} else if (setpgid(0, restore_ttypgrp) < 0) {
warningf(false, "%s: %s %s: %s", "j_suspend",
"setpgid", "failed", cstrerror(errno));
}
}
}
/* Suspend the shell. */
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_DFL;
sigaction(SIGTSTP, &sa, &osa);
kill(0, SIGTSTP);
/* Back from suspend, reset signals, pgrp and tty. */
sigaction(SIGTSTP, &osa, NULL);
if (ttypgrp_ok) {
if (restore_ttypgrp >= 0) {
if (setpgid(0, kshpid) < 0) {
warningf(false, "%s: %s %s: %s", "j_suspend",
"setpgid", "failed", cstrerror(errno));
ttypgrp_ok = false;
} else if (tcsetpgrp(tty_fd, kshpid) < 0) {
warningf(false, "%s: %s %s: %s", "j_suspend",
"tcsetpgrp", "failed", cstrerror(errno));
ttypgrp_ok = false;
}
}
tty_init_state();
}
}
#endif
/* job cleanup before shell exit */
void
j_exit(void)

5
main.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: main.c,v 1.52 2013/06/15 17:25:19 millert Exp $ */
/* $OpenBSD: main.c,v 1.53 2013/09/04 15:49:19 millert 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: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $ */
@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.269 2013/07/25 18:07:46 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.270 2013/09/10 17:33:02 tg Exp $");
extern char **environ;
@ -76,7 +76,6 @@ static const char *initcoms[] = {
/* 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",

24
mksh.1
View File

@ -1,5 +1,5 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.321 2013/08/23 14:07:37 tg Exp $
.\" $OpenBSD: ksh.1,v 1.147 2013/06/13 19:43:09 millert Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.322 2013/09/10 17:33:02 tg Exp $
.\" $OpenBSD: ksh.1,v 1.148 2013/09/04 15:49:18 millert Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
.\" 2010, 2011, 2012, 2013
@ -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: August 23 2013 $
.Dd $Mdocdate: September 10 2013 $
.\"
.\" Check which macro package we use, and do other -mdoc setup.
.\"
@ -1130,7 +1130,6 @@ nameref=\*(aqtypeset \-n\*(aq
nohup=\*(aqnohup \*(aq
r=\*(aqfc \-e \-\*(aq
stop=\*(aqkill \-STOP\*(aq
suspend=\*(aqkill \-STOP $$\*(aq
type=\*(aqwhence \-v\*(aq
.Ed
.Pp
@ -2960,8 +2959,9 @@ Builtins that are not special:
.Ic false , fc , fg , getopts ,
.Ic jobs , kill , let , mknod ,
.Ic print , pwd , read , realpath ,
.Ic rename , sleep , test , true ,
.Ic ulimit , umask , unalias , whence
.Ic rename , sleep , suspend , test ,
.Ic true , ulimit , umask , unalias ,
.Ic whence
.Pp
Once the type of command has been determined, any command-line parameter
assignments are performed and exported for the duration of the command.
@ -4322,6 +4322,16 @@ and
.Nm mksh ,
this is implemented as a shell alias instead of a builtin.
.Pp
.It Ic suspend
Stops the shell as if it had received the suspend character from
the terminal.
It is not possible to suspend a login shell unless the parent process
is a member of the same terminal session but is a member of a different
process group.
As a general rule, if the shell was started by another shell or via
.Xr su 1 ,
it can be suspended.
.Pp
.It Ic test Ar expression
.It Ic \&[ Ar expression Ic \&]
.Ic test
@ -6432,7 +6442,7 @@ $ /bin/sleep 666 && echo fubar
.Ed
.Pp
This document attempts to describe
.Nm mksh\ R48c
.Nm mksh\ R48+CVS
and up,
compiled without any options impacting functionality, such as
.Dv MKSH_SMALL ,

9
sh.h
View File

@ -4,7 +4,7 @@
/* $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $ */
/* $OpenBSD: expand.h,v 1.6 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: lex.h,v 1.13 2013/03/03 19:11:34 guenther Exp $ */
/* $OpenBSD: proto.h,v 1.34 2012/06/27 07:17:19 otto Exp $ */
/* $OpenBSD: proto.h,v 1.35 2013/09/04 15:49:19 millert Exp $ */
/* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */
/* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */
@ -164,9 +164,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.669 2013/08/23 14:07:39 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.670 2013/09/10 17:33:04 tg Exp $");
#endif
#define MKSH_VERSION "R48 2013/08/23"
#define MKSH_VERSION "R48 2013/09/10"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -518,7 +518,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 483)
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 489)
#error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void);
int
@ -1817,6 +1817,7 @@ int waitfor(const char *, int *);
int j_kill(const char *, int);
#ifndef MKSH_UNEMPLOYED
int j_resume(const char *, int);
void j_suspend(void);
#endif
int j_jobs(const char *, int, int);
void j_notify(void);