Source file src/pkg/os/signal/signal.go
1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package signal implements access to incoming signals. 6 package signal 7 8 // BUG(rsc): This package is not yet implemented on Plan 9 and Windows. 9 10 import ( 11 "os" 12 "sync" 13 ) 14 15 var handlers struct { 16 sync.Mutex 17 list []handler 18 } 19 20 type handler struct { 21 c chan<- os.Signal 22 sig os.Signal 23 all bool 24 } 25 26 // Notify causes package signal to relay incoming signals to c. 27 // If no signals are listed, all incoming signals will be relayed to c. 28 // Otherwise, just the listed signals will. 29 // 30 // Package signal will not block sending to c: the caller must ensure 31 // that c has sufficient buffer space to keep up with the expected 32 // signal rate. For a channel used for notification of just one signal value, 33 // a buffer of size 1 is sufficient. 34 // 35 func Notify(c chan<- os.Signal, sig ...os.Signal) { 36 if c == nil { 37 panic("os/signal: Notify using nil channel") 38 } 39 40 handlers.Lock() 41 defer handlers.Unlock() 42 if len(sig) == 0 { 43 enableSignal(nil) 44 handlers.list = append(handlers.list, handler{c: c, all: true}) 45 } else { 46 for _, s := range sig { 47 // We use nil as a special wildcard value for enableSignal, 48 // so filter it out of the list of arguments. This is safe because 49 // we will never get an incoming nil signal, so discarding the 50 // registration cannot affect the observed behavior. 51 if s != nil { 52 enableSignal(s) 53 handlers.list = append(handlers.list, handler{c: c, sig: s}) 54 } 55 } 56 } 57 } 58 59 func process(sig os.Signal) { 60 handlers.Lock() 61 defer handlers.Unlock() 62 63 for _, h := range handlers.list { 64 if h.all || h.sig == sig { 65 // send but do not block for it 66 select { 67 case h.c <- sig: 68 default: 69 } 70 } 71 } 72 }