On Wed, Mar 22, 2017 at 07:39:21PM +0000, Thorsten Glaser wrote: > > Dr. Werner Fink dixit: > > >Just to be mentioned, I can mksh change in such a way that without job > >control > >I can do > > > > ~/rpmbuild/BUILD/mksh> ./mksh -c 'echo xxx | read yyy; echo $yyy' > > xxx > > > >that is it does work similar to the lastpipe shell option of the bash > >I had initiated now 7 years back. The trick is to avouid forking the > >last element in a pipe chain. > > I’ve thought about this… years ago, too. But seeing as POSIX allows > either behaviour, I decided that this (running all sides of pipelines > in subshells) is a language feature now, for simplicity of user scripts > (as they can just use co-processes when they don’t want it). > > So, thanks but no. (I’ve got scripts that actually rely on that now.)
OK .. nevertheless, only for the records, the change might look
similar to that in the attachment I guess.
Werner
--
"Having a smoking section in a restaurant is like having
a peeing section in a swimming pool." -- Edward Burr
--- mksh/exec.c
+++ mksh/exec.c 2017-03-27 10:33:11.000000000 +0000
@@ -156,6 +156,8 @@ execute(struct op * volatile t,
}
}
+ flags &= ~XPIPELS;
+
switch (t->type) {
case TCOM:
rv = comexec(t, tp, (const char **)ap, flags, xerrok);
@@ -192,8 +194,23 @@ execute(struct op * volatile t,
restfd(1, e->savefd[1]);
/* no need to re-restore this */
e->savefd[1] = 0;
- /* Let exchild() close 0 in parent, after fork, before wait */
- i = exchild(t, flags | XPCLOSE | XPIPEST, xerrok, 0);
+
+ tp = NULL;
+ if (Flag(FLASTPIPE) && !Flag(FPIPEFAIL) && t->args) {
+ up = eval(t->args, t->u.evalflags | DOBLANK | DOGLOB | DOTILDE);
+ ap = (const char **)up;
+ if (ap[0])
+ tp = findcom(ap[0], FC_BI|FC_FUNC);
+ }
+
+ if (tp && tp->type == CSHELL) {
+ flags &= ~XFORK;
+ flags |= XPIPELS;
+ i = execute(t, flags | XPIPELS | XERROK, xerrok);
+ } else
+ /* Let exchild() close 0 in parent, after fork, before wait */
+ i = exchild(t, flags | XPCLOSE | XPIPEST, xerrok, 0);
+
if (!(flags&XBGND) && !(flags&XXCOM))
rv = i;
break;
@@ -453,6 +470,12 @@ execute(struct op * volatile t,
/* restores IO */
quitenv(NULL);
+
+#ifndef MKSH_UNEMPLOYED
+ if (flags & XPIPELS)
+ j_restore(flags);
+#endif
+
if ((flags&XEXEC))
/* exit child */
unwind(LEXIT);
--- mksh/jobs.c
+++ mksh/jobs.c 2017-03-27 10:34:26.000000000 +0000
@@ -641,6 +641,23 @@ exchild(struct op *t, int flags,
return (rv);
}
+#ifndef MKSH_UNEMPLOYED
+void
+j_restore(int flags)
+{
+ if (!Flag(FMONITOR) || (flags&XXCOM))
+ return;
+ /* job control set up */
+
+ if (!ttypgrp_ok)
+ return;
+
+ if (kshpgrp == kshpid && kshpgrp != tcgetpgrp(tty_fd))
+ if (tcsetpgrp(tty_fd, kshpid) < 0)
+ ttypgrp_ok = false;
+}
+#endif
+
/* start the last job: only used for $(command) jobs */
void
startlast(void)
--- mksh/main.c
+++ mksh/main.c 2017-03-27 10:45:27.000000000 +0000
@@ -250,6 +250,15 @@ main_init(int argc, const char *argv[],
*/
Flag(FBRACEEXPAND) = 1;
+#if 1
+ /*
+ * Turn on lastpipe by default ??
+ * If set the shell runs the last command of a pipeline not
+ * executed in the background in the current shell environment.
+ */
+ Flag(FLASTPIPE) = 1;
+#endif
+
/*
* Turn on "set -x" inheritance by default.
*/
--- mksh/mksh.1
+++ mksh/mksh.1 2017-03-27 10:58:39.0000000 +0000
@@ -4291,6 +4291,9 @@ Do not reset
.Fl o Ic xtrace
upon entering functions.
This is enabled by default.
+.It Fl o Ic lastpipe
+If set the shell runs the last command of a pipeline not executed in the
+background in the current shell environment.
.It Fl o Ic nohup
Do not kill running jobs with a
.Dv SIGHUP
--- mksh/sh.h
+++ mksh/sh.h 2017-03-27 10:47:08.000000000 +0000
@@ -1653,6 +1653,7 @@ struct op {
#define TTIME 20 /* time pipeline */
#define TEXEC 21 /* fork/exec eval'd TCOM */
#define TCOPROC 22 /* coprocess |& */
+#define TLPIPE 23 /* last in pipe chain */
/*
* prefix codes for words in command tree
@@ -1714,6 +1715,7 @@ struct ioword {
#define XCOPROC BIT(9) /* starting a co-process */
#define XTIME BIT(10) /* timing TCOM command */
#define XPIPEST BIT(11) /* want PIPESTATUS */
+#define XPIPELS BIT(12) /* Last element in pipe chain */
/*
* flags to control expansion of words (assumed by t->evalflags to fit
@@ -2142,6 +2144,7 @@ void j_init(void);
void j_exit(void);
#ifndef MKSH_UNEMPLOYED
void j_change(void);
+void j_restore(int);
#endif
int exchild(struct op *, int, volatile int *, int);
void startlast(void);
--- mksh/sh_flags.opt
+++ mksh/sh_flags.opt 2017-03-27 10:40:06.000000000 +0000
@@ -79,6 +79,10 @@ FN("interactive", FTALKING, OF_CMDLINE
>k|
FN("keyword", FKEYWORD, OF_ANY
+/* ./. if set the shell runs the last command of a pipeline not executed in the background in the current shell environment */
+>|
+FN("lastpipe", FLASTPIPE, OF_ANY
+
/* -l login shell */
>l|!SHFLAGS_NOT_CMD
FN("login", FLOGIN, OF_CMDLINE
signature.asc
Description: PGP signature
