// Lock creates a lockfile which prevents to open more than one instance // of the same node (on the same machine). func (ctx *Context) Lock() (err error) { var f *os.File var p *os.Process var pid int lockFile := path.Join(ctx.storageDir, ctx.nodeName+".lock") if f, err = os.Open(lockFile); err != nil { goto lock } if _, err = fmt.Fscanf(f, "%d", &pid); err != nil && pid == 0 { goto lock } if p, err = os.FindProcess(pid); err == nil && p != nil { if err = p.Signal(os.UnixSignal(0)); err == nil { return errors.New( fmt.Sprintf("node '%s' is already running", ctx.NodeName())) } } lock: // Write a lock file. if f, err = os.Create(lockFile); err == nil { pid := os.Getppid() f.Write([]byte(fmt.Sprintf("%d", pid))) f.Close() } return nil }
func process(ch chan<- os.Signal) { for { var mask uint32 = runtime.Sigrecv() for sig := uint(0); sig < 32; sig++ { if mask&(1<<sig) != 0 { ch <- os.UnixSignal(sig) } } } }
// InstallCtrlCPanic installs a Ctrl-C signal handler that panics func InstallCtrlCPanic() { go func() { defer SavePanicTrace() for s := range signal.Incoming { if s == os.UnixSignal(syscall.SIGINT) { log.Printf("ctrl-c interruption: %s\n", s) panic("ctrl-c") } } }() }
func Kill(call []string) error { e := flagSet.Parse(call[1:]) if e != nil { return e } if flagSet.NArg() != 1 || *helpFlag { println("`kill` [options] <pid>") flagSet.PrintDefaults() println("1 SIGHUP terminal line hangup") println("2 SIGINT interrupt program") println("3 SIGQUIT quit program") println("4 SIGILL illegal instruction") println("5 SIGTRAP trace trap") println("6 SIGABRT abort program (formerly SIGIOT)") println("7 SIGEMT emulate instruction executed") println("8 SIGFPE floating-point exception") println("9 SIGKILL kill program") println("10 SIGBUS bus error") println("11 SIGSEGV segmentation violation") println("12 SIGSYS non-existent system call invoked") println("13 SIGPIPE write on a pipe with no reader") println("14 SIGALRM real-time timer expired") println("15 SIGTERM software termination signal") println("16 SIGURG urgent condition present on socket") return nil } pid, e := strconv.Atoi(flagSet.Arg(0)) if e != nil { return e } p, e := os.FindProcess(pid) if e != nil { return e } return p.Signal(os.UnixSignal(int32(*signalFlag))) }
// TestCopyError tests that we kill the process if there's an error copying // its output. (for example, from the client having gone away) func TestCopyError(t *testing.T) { if skipTest(t) || runtime.GOOS == "windows" { return } h := &Handler{ Path: "testdata/test.cgi", Root: "/test.cgi", } ts := httptest.NewServer(h) defer ts.Close() conn, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatal(err) } req, _ := http.NewRequest("GET", "http://example.com/test.cgi?bigresponse=1", nil) err = req.Write(conn) if err != nil { t.Fatalf("Write: %v", err) } res, err := http.ReadResponse(bufio.NewReader(conn), req) if err != nil { t.Fatalf("ReadResponse: %v", err) } pidstr := res.Header.Get("X-CGI-Pid") if pidstr == "" { t.Fatalf("expected an X-CGI-Pid header in response") } pid, err := strconv.Atoi(pidstr) if err != nil { t.Fatalf("invalid X-CGI-Pid value") } var buf [5000]byte n, err := io.ReadFull(res.Body, buf[:]) if err != nil { t.Fatalf("ReadFull: %d bytes, %v", n, err) } childRunning := func() bool { p, err := os.FindProcess(pid) if err != nil { return false } return p.Signal(os.UnixSignal(0)) == nil } if !childRunning() { t.Fatalf("pre-conn.Close, expected child to be running") } conn.Close() tries := 0 for tries < 25 && childRunning() { time.Sleep(50 * time.Millisecond * time.Duration(tries)) tries++ } if childRunning() { t.Fatalf("post-conn.Close, expected child to be gone") } }
// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build darwin freebsd linux netbsd openbsd package signal import ( "os" "syscall" "testing" ) const sighup = os.UnixSignal(syscall.SIGHUP) func TestSignal(t *testing.T) { // Send this process a SIGHUP. syscall.Syscall(syscall.SYS_KILL, uintptr(syscall.Getpid()), syscall.SIGHUP, 0) if sig := (<-Incoming).(os.UnixSignal); sig != sighup { t.Errorf("signal was %v, want %v", sig, sighup) } }