Discussion:
ash backgrounding bug?
Edgar Fuß
2014-06-05 13:12:50 UTC
Permalink
If I do

#!/bin/sh

daemon() {
sleep 5
}

fork_daemon() {
( cd /; $1 <&- >&- 2>&- & echo $! ) &
}

daemon_pid=$(fork_daemon daemon)
echo "daemon pid=$daemon_pid"

with any non-ash POSIX shell I can find, it works as I expect.
When using ash (or dash), the $() evaluation waits for daemon() to return.
Is that a bug in ash or does POSIX allow such behaviour?
Christos Zoulas
2014-06-05 15:44:34 UTC
Permalink
Post by Edgar Fuß
If I do
#!/bin/sh
daemon() {
sleep 5
}
fork_daemon() {
( cd /; $1 <&- >&- 2>&- & echo $! ) &
}
daemon_pid=$(fork_daemon daemon)
echo "daemon pid=$daemon_pid"
with any non-ash POSIX shell I can find, it works as I expect.
When using ash (or dash), the $() evaluation waits for daemon() to return.
Is that a bug in ash or does POSIX allow such behaviour?
Looks like a bug to me. Note that this is not due to vfork() I think because
the following patch and invoking sh -F does the same. Send-pr?

christos

Index: eval.c
===================================================================
RCS file: /cvsroot/src/bin/sh/eval.c,v
retrieving revision 1.109
diff -u -u -r1.109 eval.c
--- eval.c 31 May 2014 14:42:18 -0000 1.109
+++ eval.c 5 Jun 2014 15:43:29 -0000
@@ -860,7 +860,7 @@
* child's address space is actually shared with the parent as
* we rely on this.
*/
- if (cmdentry.cmdtype == CMDNORMAL) {
+ if (usefork == 0 && cmdentry.cmdtype == CMDNORMAL) {
pid_t pid;
int serrno;

Index: options.h
===================================================================
RCS file: /cvsroot/src/bin/sh/options.h,v
retrieving revision 1.20
diff -u -u -r1.20 options.h
--- options.h 18 Jun 2011 21:18:46 -0000 1.20
+++ options.h 5 Jun 2014 15:43:29 -0000
@@ -99,9 +99,11 @@
#define cdprint optlist[17].val
DEF_OPT( "tabcomplete", 0 ) /* <tab> causes filename expansion */
#define tabcomplete optlist[18].val
+DEF_OPT( "fork", 'F' ) /* use fork(2) instead of vfork(2) */
+#define usefork optlist[19].val
#ifdef DEBUG
DEF_OPT( "debug", 0 ) /* enable debug prints */
-#define debug optlist[19].val
+#define debug optlist[20].val
#endif

#ifdef DEFINE_OPTIONS
Edgar Fuß
2014-06-05 16:39:19 UTC
Permalink
Post by Christos Zoulas
Looks like a bug to me.
I boiled it down to

#!/bin/sh

f() {
sleep 3
}

echo $(sleep 3 >&- & echo $!)
echo $(f >&- & echo $!)

where the first echo completes immediately, the second only after three seconds.
Post by Christos Zoulas
Send-pr?
bin/48875
David Laight
2014-06-11 19:59:18 UTC
Permalink
Post by Edgar Fuß
Post by Christos Zoulas
Looks like a bug to me.
I boiled it down to
#!/bin/sh
f() {
sleep 3
}
echo $(sleep 3 >&- & echo $!)
echo $(f >&- & echo $!)
where the first echo completes immediately, the second only after three seconds.
Looks like it won't 'background' a shell function inside $(...)
a simple f & doesn't stop the shell.

David
--
David Laight: ***@l8s.co.uk
Loading...