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

os/signal: No way to re-enable default handlers #4268

Closed
gopherbot opened this issue Oct 20, 2012 · 5 comments
Closed

os/signal: No way to re-enable default handlers #4268

gopherbot opened this issue Oct 20, 2012 · 5 comments
Milestone

Comments

@gopherbot
Copy link

by jacobsa@google.com:

(Note: I am not an old hand with signals, and may be missing something obvious
here. Please be gentle.)

As I understand it, if I say

    c := make(chan os.Signal)
    signal.Notify(c, os.Interrupt)

then I have forever disabled the default SIGINT handler, even if I close the
channel and never touch it. It would be nice if there were a way to declare to
the signal package that I no longer am interested in a signal, similar to
calling signal(3) with SIG_DFL.

I came across this issue when using this package for reading passwords without
echoing:

    http://code.google.com/p/gopass/source/browse/gopass.go

(Admittedly this package's implementation is hacky. I couldn't find a better
way to do this though. Calling getpass(3) using cgo screwed up signal handling
even worse, as far as I can tell.)

The package installs a temporary SIGINT handler that turns terminal echoing
back on before exiting when a signal is received. It returns from this handler
when it's done reading a password though, and the net effect is that after
calling GetPass once, SIGINT never again works except while calling GetPass
another time.

If I control all of the code in my program then I can keep my signal handler
running and emulating the default handler. But this is a bit annoying, and I
can't think of any way for a library developer to do it correctly. (If the
library developer chooses to do this, she may interfere with some other
library developer who is intentionally trying to suppress SIGINT, for
example.)
@gopherbot
Copy link
Author

Comment 1 by jacobsa@google.com:

In case my rambling above wasn't clear, here's an example:
    package main
    
    import (
        "os"
        "os/signal"
    )
    
    func main() {
        c := make(chan os.Signal)
        signal.Notify(c, os.Interrupt)
    
        select {}
    }
Run `go build signal.go && ./signal`, then observe you can't stop it using
Ctrl-C. This is a stupid case, but the "suppress SIGINT temporarily but not
forever from a library" thing maybe isn't.

@robpike
Copy link
Contributor

robpike commented Oct 20, 2012

Comment 2:

Labels changed: added priority-later, removed priority-triage.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Dec 10, 2012

Comment 3:

Labels changed: added size-l.

@gopherbot
Copy link
Author

Comment 4 by guelfey:

I'd suggest to add another function to the package that removes the handler from the
list and returns the channel that was previously used for this signal, so a library may
restore a user-defined handler. This shouldn't be too hard to implement; I'll try it
later.

@rsc
Copy link
Contributor

rsc commented Mar 15, 2013

Comment 5:

This issue was closed by revision cb4428e.

Status changed to Fixed.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1 label Apr 14, 2015
@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

3 participants