Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Mar 2022 20:39:50 +0100
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Ganael Laplanche <ganael.laplanche@martymac.org>
Cc:        Bryan Drewery <bdrewery@FreeBSD.org>, freebsd-hackers@freebsd.org
Subject:   Re: Our /bin/sh and process group IDs
Message-ID:  <20220326193950.GA1667@stack.nl>
In-Reply-To: <9745f2ef-3aae-5548-c8db-5da7d4ce11e7@martymac.org>
References:  <48e49ad0-a12a-d10b-5867-da9736c6c1fd@martymac.org> <243ebc92-26a1-e5e7-67fe-1477ed6b5f7a@FreeBSD.org> <9745f2ef-3aae-5548-c8db-5da7d4ce11e7@martymac.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Mar 26, 2022 at 03:52:40PM +0100, Ganael Laplanche wrote:
> Le 25/03/2022 à 20:13, Bryan Drewery a écrit :

> Hello Bryan,

> > set -m needs to be set from the parent process, not child.

> Thanks for those clarifications.

> Is that something required by POSIX (I could not find any documentation
> about that) ? Or is it a limitation (or bug) of our implementation ? Other
> shells -mostly- do not behave that way (see my original post).

This appears to be a gray area, and the exact behaviour varies across
shells. For example, with  stty tostop  in effect,

sh -c '(set -m; echo "echo from background" & wait "$!"); echo "wait returns $?"'

has a variety of behaviours:

* with FreeBSD sh, dash and also ksh93, it prints both lines
* with mksh, it only prints the "wait returns 0" line
* with bash, it hangs (as expected with a new process group)

I think it is definitely undesirable for  set -m  to have an effect
across multiple levels of subshells by default, since it makes the
innermost processes immediately escape from the outer process group
supervision again.

As it is now, FreeBSD sh has implemented this by ignoring  set -m  from
a process other than the first process (so for example

sh -c '(set -m; echo "echo from background" & wait "$!"; echo "wait returns $?")'

still hangs with tostop in effect, since this particular subshell is
implemented without creating a new process), but perhaps this could be
extended a bit more.

> > In this  example test_func is a child *and* the sleep is a child which
> > is also very racy. Here's a pattern I use that works:
> > [...]

> Unfortunately, in my case, spawn would have to be called from a sub-process
> already forked (from a background function, executed as a child process) ;
> so that wouldn't work either. Anyway, thanks for the hint :)

A second workaround is to start a new instance of sh.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20220326193950.GA1667>