Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go programs don't respond to SIGTSTP (ctl+Z) #776

Closed
hoisie opened this issue May 12, 2010 · 7 comments
Closed

Go programs don't respond to SIGTSTP (ctl+Z) #776

hoisie opened this issue May 12, 2010 · 7 comments

Comments

@hoisie
Copy link
Contributor

hoisie commented May 12, 2010

What steps will reproduce the problem?
Run a simple program that sleeps:

package main

import "time"

func main() {
        time.Sleep(100 * 1e9)
}


2. Either type Ctl+Z, or send the process a signal 'kill -s SIGTSTP pid'

What is the expected output? What do you see instead?
Expect to stop, instead it keeps running.

What is your $GOOS?  $GOARCH?
Linux/amd64

Which revision are you using?  (hg identify)
17ded5ad443b+ release.2010-05-04/release
@kylelemons
Copy link
Contributor

Comment 1:

Works on darwin/amd64:
package main
import (
    "fmt"
    "syscall"
    "os/signal"
)
func main() {
    for sig := range signal.Incoming {
        fmt.Printf("Got signal: %s\n", sig)
        if usig,ok := sig.(signal.UnixSignal); ok {
            if usig == syscall.SIGTSTP {
                fmt.Printf("Suspending\n")
                syscall.Kill(syscall.Getppid(), syscall.SIGTSTP)
            }
        }
    }
}

@kylelemons
Copy link
Contributor

Comment 2:

The following works on darwin/amd64:
package main
import (
    "fmt"
    "syscall"
    "os/signal"
)
func main() {
    for sig := range signal.Incoming {
        fmt.Printf("Got signal: %s\n", sig)
        if usig,ok := sig.(signal.UnixSignal); ok {
            if usig == syscall.SIGTSTP {
                fmt.Printf("Suspending\n")
                syscall.Kill(syscall.Getpid(), syscall.SIGSTOP)
            }
        }
    }
}
Essentially, you can catch the TSTP signal and then send yourself the STOP signal.  I
don't know how this will 
interact with things like time.Sleep, as I don't know if the runtime is equipped to
handle being forcibly stopped, 
but in my trivial case it appears to work.  While this is not an automated, built-in
solution, it will emulate the 
behavior that you are seeking.  (sorry about the extra comment, I pasted an older
version of the code and 
managed to send it instead of repasting)

@ianlancetaylor
Copy link
Contributor

Comment 3:

The issue is that we want to permit Go programs to catch SIGTSTP.  However, if the
program does not catch SIGTSTP, then we want it to have its default effect.  So a
partial answer would be that if sigsend returns false for SIGTSTP, we should remove the
handler and reraise the signal.  Then we should reinstall the signal handler, so that
the obscure case of a later call to runtime.Siginit will work correctly.
However, I don't know a natural way to make this work for a program that calls
runtime.Siginit (typically via importing os/signal).  Most programs that catch signals
do not actually want to catch SIGTSTP, but some do.  The best idea I can think of right
now is that we could require a program which handles SIGTSTP to call a function in the
os/signal package to enable it.
We should probably handle SIGTTIN and SIGTTOU the same way we handle SIGTSTP.

@rsc
Copy link
Contributor

rsc commented Jun 25, 2010

Comment 4:

A simpler issue is that if the program doesn't import os/signal, I believe the SIGTSTP
behavior is still wrong.

@ianlancetaylor
Copy link
Contributor

Comment 5:

Yes, it's wrong because we always catch SIGTSTP, and if the program did not import
os/signal, we throw it away.  We have to instead re-raise it.
A different approach would be to only install signal handlers for the Q+I signals if the
program calls runtime.Siginit.

@adg
Copy link
Contributor

adg commented Jun 29, 2010

Comment 6:

Status changed to Accepted.

@ianlancetaylor
Copy link
Contributor

Comment 7:

This issue was closed by revision 807605d.

Status changed to Fixed.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants