go programs by default ignore SIGTSTP, SIGTTIN, SIGTTOU now

360 views
Skip to first unread message

minux

unread,
Feb 15, 2012, 12:43:46 PM2/15/12
to golan...@googlegroups.com
Hi all,

    Recent changes to os/signal has a side effect to effectively ignore SIGTSTP, SIGTTIN, 
SIGTTOU signals. This is not natural. For example, ignoring SIGTSTP will make ^Z unable
to suspend the task, which is very unconventional, and frustrating when first met.

    IMO, these signals (at least SIGTSTP) should be handled as special cases, and if they
are not requested explicitly by the program through runtime.signal_enable, they shouldn't be
caught (and ignored).


Best regards,
minux.

Russ Cox

unread,
Feb 15, 2012, 12:51:19 PM2/15/12
to minux, golan...@googlegroups.com
I had blocked this trauma out of my mind.
Are there other signals that must only be handled
if they are explicitly asked for, or is it just the
SIGT ones?

Russ

minux

unread,
Feb 15, 2012, 2:13:35 PM2/15/12
to r...@golang.org, golan...@googlegroups.com
I just reviewed runtime/signals_linux.h line by line, and found no other cases
that need special treatment.

To correctly handle these signals, should we add a way to call disable_signal for
os/signal?

Filed Issue 3037.

David Symonds

unread,
Feb 16, 2012, 6:52:14 AM2/16/12
to minux, r...@golang.org, golan...@googlegroups.com
I took a crack at this in http://codereview.appspot.com/5674072. It
allows programs to be stopped with ^Z correctly, but for some reason
system calls don't get restarted. For instance, suspending a plain
"gofmt" (reading from stdin) works, but then resuming it yields
read /dev/stdin: interrupted system call

If my approach is completely wrong, I'm fine with abandoning it. Maybe
there's just something simple I'm overlooking, though.


Dave.

Russ Cox

unread,
Feb 16, 2012, 10:30:11 AM2/16/12
to David Symonds, minux, golan...@googlegroups.com

It looks right to me. It is possible that read-from-standard input
is always interrupted by ^Z, regardless of the restart setting.
It's worth trying under strace -f to double-check the system calls.

Russ

minux

unread,
Feb 16, 2012, 12:35:31 PM2/16/12
to r...@golang.org, David Symonds, golan...@googlegroups.com
Of the systems I tested (Mac OS X, Linux, FreeBSD), David's CL only exhibit this behavior
on Mac OS X.

I updated to rev 9d7addec2635, just before the selective signal handling was commited, and
also found this behavior.

To verify if this is specific to reading from terminal, I make a fifo, and gofmt < fifo, suspend
it and resume, no error is reported.
So, this might be a bug (or feature) of Darwin kernel. (even /bin/cat suffer from this bug, but
GNU cat doesn't)

It seems we have to handle syscall restart for Darwin in the syscall package.

Russ Cox

unread,
Feb 16, 2012, 1:07:34 PM2/16/12
to minux, David Symonds, golan...@googlegroups.com
On Thu, Feb 16, 2012 at 12:35, minux <minu...@gmail.com> wrote:
> It seems we have to handle syscall restart for Darwin in the syscall
> package.

I don't think we need to bother. People using ^Z get what the
operating system sees fit to provide.

Russ

minux

unread,
Feb 16, 2012, 1:39:11 PM2/16/12
to r...@golang.org, David Symonds, golan...@googlegroups.com
But the user will certainly not expect this. Occasionally,  people will suspend
a interact program to do some other things, but when they resume their program,
it simply exits because of EINTR.... This is OK for simple programs like /bin/cat,
but not desirable for larger programs. (BSD variants by default always auto restart
a syscall, I don't know why the Darwin kernel dropped this.)

If we don't do restart in pkg syscall, user who don't want the buggy behavior simply
could not workaround it in some cases (if a std. library call failed with EINTR, should
it be retried? What if other side effects have already happened?).

PS:
I've also tried to set SA_RESTART with SIG_DFL for SIGTSTP, but still not solving
the problem.

The only workaround I found is to actually catch SIGTSTP, and in the sighandler, send
itself a SIGSTOP, then the read(2) syscall won't be interrupted. I wonder if this work-
around is acceptable.

Russ Cox

unread,
Feb 16, 2012, 2:00:49 PM2/16/12
to minux, David Symonds, golan...@googlegroups.com
A C program would exhibit the same buggy behavior.
Even /bin/cat exhibits this buggy behavior.

We're talking about a very specific case: ^Z on a Mac.
^Z is a clumsy hack introduced before there were
window systems that could give you multiple virtual
terminal sessions at once. Luckily, every modern Mac
includes a window system that lets you create as many
terminals as you want, meaning ^Z is less important,
which is probably Apple has not fixed this OS bug.

It cannot be Go's role to bring sanity to job control.
That is setting ourselves up for failure.

Russ

minux

unread,
Feb 16, 2012, 2:10:36 PM2/16/12
to r...@golang.org, David Symonds, golan...@googlegroups.com
OK, fair enough. Now that because I can implement the SIGSTOP workaround
in Go, I would not object this. But should this be at least mentioned in the docs?

On Fri, Feb 17, 2012 at 3:00 AM, Russ Cox <r...@golang.org> wrote:
A C program would exhibit the same buggy behavior.
Even /bin/cat exhibits this buggy behavior.
Only those incorrectly assume that the BSD auto syscall restart is present.
As I've said, GNU cat doesn't exhibit this.

Russ Cox

unread,
Feb 16, 2012, 2:17:04 PM2/16/12
to minux, David Symonds, golan...@googlegroups.com
I don't think this needs to be documented. It's an OS X detail, not a
Go detail.
Reply all
Reply to author
Forward
0 new messages