Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
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)
			}
		}
	}
}
Ejemplo n.º 3
0
// 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")
			}
		}
	}()
}
Ejemplo n.º 4
0
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)))
}
Ejemplo n.º 5
0
// 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")
	}
}
Ejemplo n.º 6
0
// 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)
	}
}