diff --git a/Build.sh b/Build.sh index ef6c87f..54e1615 100644 --- a/Build.sh +++ b/Build.sh @@ -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 diff --git a/Makefile b/Makefile index e0509de..9fd917a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/check.t b/check.t index f4854ca..5548f5c 100644 --- a/check.t +++ b/check.t @@ -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 diff --git a/funcs.c b/funcs.c index e83bafd..39de590 100644 --- a/funcs.c +++ b/funcs.c @@ -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 diff --git a/jobs.c b/jobs.c index ae8021b..aea5acf 100644 --- a/jobs.c +++ b/jobs.c @@ -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) diff --git a/main.c b/main.c index 291ab40..d49474e 100644 --- a/main.c +++ b/main.c @@ -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 #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", diff --git a/mksh.1 b/mksh.1 index 245767c..db17f78 100644 --- a/mksh.1 +++ b/mksh.1 @@ -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 , diff --git a/sh.h b/sh.h index 565c1e2..4820e44 100644 --- a/sh.h +++ b/sh.h @@ -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);