func TestDeath(t *testing.T) { defer log.Flush() Convey("Validate death happens cleanly", t, func() { death := NewDeath(syscall.SIGTERM) syscall.Kill(os.Getpid(), syscall.SIGTERM) death.WaitForDeath() }) Convey("Validate death happens with other signals", t, func() { death := NewDeath(syscall.SIGHUP) closeMe := &CloseMe{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(closeMe) So(closeMe.Closed, ShouldEqual, 1) }) Convey("Validate death gives up after timeout", t, func() { death := NewDeath(syscall.SIGHUP) death.setTimeout(10 * time.Millisecond) neverClose := &neverClose{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(neverClose) }) }
func main() { http.HandleFunc("/sleep/", func(w http.ResponseWriter, r *http.Request) { duration, err := time.ParseDuration(r.FormValue("duration")) if err != nil { http.Error(w, err.Error(), 400) return } time.Sleep(duration) fmt.Fprintf( w, "started at %s slept for %d nanoseconds from pid %d.\n", time.Now(), duration.Nanoseconds(), os.Getpid(), ) }) log.Println(fmt.Sprintf("Serving :8080 with pid %d.", os.Getpid())) gracehttp.ListenAndServe(":8080", nil) log.Println("Server stoped.") }
func New(id circuit.WorkerID, bindAddr string, host string) *Transport { // Bind var l *net.TCPListener if strings.Index(bindAddr, ":") < 0 { bindAddr = bindAddr + ":0" } l_, err := net.Listen("tcp", bindAddr) if err != nil { panic(err) } // Build transport structure l = l_.(*net.TCPListener) t := &Transport{ listener: l, addrtabl: makeAddrTabl(), pipelining: DefaultPipelining, remote: make(map[circuit.WorkerID]*link), ach: make(chan *conn), } // Resolve self address laddr := l.Addr().(*net.TCPAddr) t.self, err = NewAddr(id, os.Getpid(), fmt.Sprintf("%s:%d", host, laddr.Port)) if err != nil { panic(err) } // This LocalAddr might be useless for connect purposes (e.g. 0.0.0.0). Consider self instead. t.bind = t.addrtabl.Normalize(&Addr{ID: id, PID: os.Getpid(), Addr: laddr}) go t.loop() return t }
func TestNewStatus(t *testing.T) { now := time.Now() mem := runtime.MemStats{Alloc: 0} status := NewStatus("v1", now, &mem) if status == nil { t.Fatal("status is nil") } if status.Code != "OK" { t.Errorf("status is %s, expected %s", status.Code, "OK") } if status.Version != "v1" { t.Errorf("version is %s, expected %s", status.Version, "v1") } if host := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH); status.Host != host { t.Errorf("host is %s, expected %s", status.Host, host) } if status.PID != os.Getpid() { t.Errorf("PID is %d, expected %d", status.PID, os.Getpid()) } if status.StartedAt != now { t.Errorf("version is %v expected %v", status.StartedAt, now) } if status.NumberGoroutines != runtime.NumGoroutine() { t.Errorf("number of goroutines is %v expected %v", status.StartedAt, now) } if status.MemoryAlloc != "0B" { t.Errorf("memory allocated is %v, expected to be %v", status.MemoryAlloc, "0.00MB") } }
func sendPacket(conn net.PacketConn, destination *net.IPAddr, payload []byte, seq int) { packet := make([]byte, len(payload)+8) packet[0] = 8 packet[1] = 0 packet[4] = uint8(os.Getpid() >> 8) packet[5] = uint8(os.Getpid() & 0xff) packet[6] = uint8(seq >> 8) packet[7] = uint8(seq & 0xff) copy(packet[8:], payload) cklen := len(packet) cksum := uint32(0) for i := 0; i < cklen-1; i += 2 { cksum += uint32(packet[i+1])<<8 | uint32(packet[i]) } if cklen&1 == 1 { cksum += uint32(packet[cklen-1]) } cksum = (cksum >> 16) + (cksum & 0xffff) cksum = cksum + (cksum >> 16) packet[2] ^= uint8(^cksum & 0xff) packet[3] ^= uint8(^cksum >> 8) _, err := conn.WriteTo(packet, destination) if err != nil { panic(err) } }
func processMetrics() { var ( g = metrics.NewGauge() fg = metrics.NewGauge() memg = metrics.NewGauge() ) metrics.DefaultRegistry.Register("goroutines", g) metrics.DefaultRegistry.Register("fds", fg) metrics.DefaultRegistry.Register("memory-used", memg) collect := func() { // update number of goroutines g.Update(int64(runtime.NumGoroutine())) // collect the number of open fds fds, err := osutils.GetOpenFds(os.Getpid()) if err != nil { logrus.WithField("error", err).Error("containerd: get open fd count") } fg.Update(int64(fds)) // get the memory used m := sigar.ProcMem{} if err := m.Get(os.Getpid()); err != nil { logrus.WithField("error", err).Error("containerd: get pid memory information") } memg.Update(int64(m.Size)) } go func() { collect() for range time.Tick(30 * time.Second) { collect() } }() }
// Wait for 10 consecutive responses from our own pid. // // This prevents flaky tests that arise from the fact that we have the // perfectly acceptable (read: not a bug) condition where both the new and the // old servers are accepting requests. In fact the amount of time both are // accepting at the same time and the number of requests that flip flop between // them is unbounded and in the hands of the various kernels our code tends to // run on. // // In order to combat this, we wait for 10 successful responses from our own // pid. This is a somewhat reliable way to ensure the old server isn't // serving anymore. func wait(wg *sync.WaitGroup, url string) { var success int defer wg.Done() for { res, err := http.Get(url) if err == nil { // ensure it isn't a response from a previous instance defer res.Body.Close() var r response if err := json.NewDecoder(res.Body).Decode(&r); err != nil { log.Fatalf("Error decoding json: %s", err) } if r.Pid == os.Getpid() { success++ if success == 10 { return } continue } } else { success = 0 // we expect connection refused if !strings.HasSuffix(err.Error(), "connection refused") { e2 := json.NewEncoder(os.Stderr).Encode(&response{ Error: err.Error(), Pid: os.Getpid(), }) if e2 != nil { log.Fatalf("Error writing error json: %s", e2) } } } } }
func main() { sigChan := make(chan os.Signal) log.Println("pid==", os.Getpid()) pid := os.Getpid() process, err := os.FindProcess(pid) if err != nil { log.Println(err) } signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT) for { select { case sig := <-sigChan: switch sig { case syscall.SIGHUP: log.Println("SIGNAL SIGHUP") case syscall.SIGINT: log.Println("SIGNAL SIGINT") process.Kill() } } } }
func TestPidFile(t *testing.T) { opts := DefaultTestOptions tmpDir, err := ioutil.TempDir("", "_gnatsd") if err != nil { t.Fatal("Could not create tmp dir") } defer os.RemoveAll(tmpDir) file, err := ioutil.TempFile(tmpDir, "gnatsd:pid_") file.Close() opts.PidFile = file.Name() s := RunServer(&opts) s.Shutdown() buf, err := ioutil.ReadFile(opts.PidFile) if err != nil { t.Fatalf("Could not read pid_file: %v", err) } if len(buf) <= 0 { t.Fatal("Expected a non-zero length pid_file") } pid := 0 fmt.Sscanf(string(buf), "%d", &pid) if pid != os.Getpid() { t.Fatalf("Expected pid to be %d, got %d\n", os.Getpid(), pid) } }
func TestIsPortBound(t *testing.T) { port := "8080" go func() { err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil) if err != nil { t.Fatal(err) } }() maxTry := 10 for i := 0; i < maxTry; i++ { pid, err := IsPortBound(port, []int{os.Getpid()}) if err != nil { t.Fatal(err) } if pid == -1 { continue //port not bound yet } //port bound if pid != os.Getpid() { t.Fatal("expect port to be bound by %d, got %d", os.Getpid(), pid) } else { return // ok } } t.Fatal("port never bound :(") }
func TestInitd(t *testing.T) { t.Parallel() l, err := detectInitd("./") assert.Nil(t, err) assert.NotNil(t, l) assert.Equal(t, "init.d", l.Name()) // service does not exist st, err := l.LookupService("apache2") assert.NotNil(t, err) assert.Equal(t, err.(*ServiceError).Err.Error(), "No such service") assert.Nil(t, st) // service exists but pidfile doesn't st, err = l.LookupService("mysql") assert.Nil(t, err) assert.NotNil(t, st) assert.Equal(t, 0, st.Pid) assert.Equal(t, Down, st.Status) // Need to be able to kill -0 the PID and our own process // is the only one we can be sure of. i := l.(*Initd) i.pidParser = func(_ []byte) (int, error) { return os.Getpid(), nil } // service exists and pidfile exists st, err = l.LookupService("redis") assert.Nil(t, err) assert.Equal(t, os.Getpid(), st.Pid) assert.Equal(t, Up, st.Status) }
//prog(state) runs in a child process func prog(state overseer.State) { // pp.Println(state) log.Println("Prog: start PID: ", os.Getpid(), os.Getppid()) log.Println("Building date: ", buildDate) log.Printf("app (%s) listening at %s...", state.ID, state.Listener.Addr()) http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Println("Get handle from ", r.RemoteAddr, r.RequestURI) log.Println("PID=", os.Getpid()) fmt.Fprintln(w, "<h1>Test overseer server</h1>") fmt.Fprintln(w, `<a href="https://github.com/jpillora/overseer">Overseer home page</a>`) fmt.Fprintf(w, "<p>Build date: %s</p>", buildDate) counter++ fmt.Fprintf(w, "<p>My app (%s) says hello %d times</p>\n", state.ID, counter) fmt.Fprintf(w, "<p>PID=%d, PPID=%d</p>\n", os.Getpid(), os.Getppid()) fmt.Fprintf(w, "<p>Application: %s</p>\n", os.Args[0]) fmt.Fprintf(w, "<hr/><p>Args: %v</p>", os.Args[1:]) fmt.Fprintln(w, "<hr/><ul>\n") for _, env := range os.Environ() { fmt.Fprintf(w, "<li>Env: %v</li>\n", env) } fmt.Fprintln(w, "</ul>\n") })) http.Serve(state.Listener, nil) log.Println("Stop server ", os.Getpid()) }
func main() { lf, err := os.OpenFile(lfn, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) if err == nil { // good // 10 digit pid seems to be a standard for lock files fmt.Fprintf(lf, "%10d", os.Getpid()) lf.Close() defer os.Remove(lfn) } else { // problem fmt.Println(err) // dig deeper lf, err = os.Open(lfn) if err != nil { return } defer lf.Close() fmt.Println("inspecting lock file...") b10 := make([]byte, 10) _, err = lf.Read(b10) if err != nil { fmt.Println(err) return } pid, err := strconv.Atoi(strings.TrimSpace(string(b10))) if err != nil { fmt.Println(err) return } fmt.Println("lock file created by pid", pid) return } fmt.Println(os.Getpid(), "running...") time.Sleep(1e10) }
func TestIngest(t *testing.T) { type obj map[string]interface{} if testing.Verbose() { logp.LogInit(logp.LOG_DEBUG, "", false, true, []string{"elasticsearch"}) } index := fmt.Sprintf("beats-test-ingest-%d", os.Getpid()) pipeline := fmt.Sprintf("beats-test-pipeline-%d", os.Getpid()) pipelineBody := obj{ "description": "Test pipeline", "processors": []obj{ { "lowercase": obj{ "field": "testfield", }, }, }, } client := GetTestingElasticsearch() _, _, err := client.DeletePipeline(pipeline, nil) _, resp, err := client.CreatePipeline(pipeline, nil, pipelineBody) if err != nil { t.Fatal(err) } if !resp.Acknowledged { t.Fatalf("Test pipeline %v not created", pipeline) } params := map[string]string{"refresh": "true"} _, resp, err = client.Ingest(index, "test", pipeline, "1", params, obj{ "testfield": "TEST", }) if err != nil { t.Fatalf("Ingest() returns error: %s", err) } if !resp.Created { t.Errorf("Ingest() fails: %s", resp) } // get _source field from indexed document _, docBody, err := client.apiCall("GET", index, "test", "1/_source", "", nil, nil) if err != nil { t.Fatal(err) } doc := struct { Field string `json:"testfield"` }{} err = json.Unmarshal(docBody, &doc) if err != nil { t.Fatal(err) } assert.Equal(t, "test", doc.Field) }
func (v *loggerPlus) Println(ctx Context, a ...interface{}) { if ctx == nil { a = append([]interface{}{fmt.Sprintf("[%v]", os.Getpid())}, a...) } else { a = append([]interface{}{fmt.Sprintf("[%v][%v]", os.Getpid(), ctx.Cid())}, a...) } v.logger.Println(a...) }
// GetTotalUsedFds Returns the number of used File Descriptors by // reading it via /proc filesystem. func GetTotalUsedFds() int { if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { logrus.Errorf("Error opening /proc/%d/fd: %s", os.Getpid(), err) } else { return len(fds) } return -1 }
func TestNsenterValidPaths(t *testing.T) { args := []string{"nsenter-exec"} parent, child, err := newPipe() if err != nil { t.Fatalf("failed to create pipe %v", err) } namespaces := []string{ // join pid ns of the current process fmt.Sprintf("/proc/%d/ns/pid", os.Getpid()), } cmd := &exec.Cmd{ Path: os.Args[0], Args: args, ExtraFiles: []*os.File{child}, Env: []string{"_LIBCONTAINER_INITPIPE=3"}, Stdout: os.Stdout, Stderr: os.Stderr, } if err := cmd.Start(); err != nil { t.Fatalf("nsenter failed to start %v", err) } // write cloneFlags r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) r.AddData(&libcontainer.Int32msg{ Type: libcontainer.CloneFlagsAttr, Value: uint32(syscall.CLONE_NEWNET), }) r.AddData(&libcontainer.Bytemsg{ Type: libcontainer.NsPathsAttr, Value: []byte(strings.Join(namespaces, ",")), }) if _, err := io.Copy(parent, bytes.NewReader(r.Serialize())); err != nil { t.Fatal(err) } decoder := json.NewDecoder(parent) var pid *pid if err := decoder.Decode(&pid); err != nil { dir, _ := ioutil.ReadDir(fmt.Sprintf("/proc/%d/ns", os.Getpid())) for _, d := range dir { t.Log(d.Name()) } t.Fatalf("%v", err) } if err := cmd.Wait(); err != nil { t.Fatalf("nsenter exits with a non-zero exit status") } p, err := os.FindProcess(pid.Pid) if err != nil { t.Fatalf("%v", err) } p.Wait() }
func main() { flag.Parse() regex, err := regexp.Compile(*regexStr) if err != nil { fmt.Printf("Error compiling regular expression \"%s\":\n"+ " %s\n", *regexStr, err) os.Exit(1) } if regex.NumSubexp() > 1 { fmt.Printf("Can't handle more than one subexpression in the regular "+ " expression \"%s\"\n", *regexStr, err) os.Exit(1) } if *branchName == "" { fmt.Printf("You must specify a branch to compare against using -b.\n") os.Exit(1) } il := newIgnoreList() if *ignoreFile != "" { err = il.ReadIgnoreFile(*ignoreFile, regex) if err != nil { fmt.Printf("error reading ignore file: %s\n", err) os.Exit(1) } } fileNames := []string{ fmt.Sprintf("/tmp/jirafun.1.%d", os.Getpid()), fmt.Sprintf("/tmp/jirafun.2.%d", os.Getpid())} defer os.Remove(fileNames[0]) defer os.Remove(fileNames[1]) err = gitCommand(fileNames[1], "git", "rev-list", "--pretty=oneline", *branchName) if err != nil { fmt.Print(err) os.Exit(1) } err = gitCommand(fileNames[0], "git", "rev-list", "--pretty=oneline", "HEAD") if err != nil { fmt.Print(err) os.Exit(1) } refLogs := []*RefLog{NewRefLog(regex), NewRefLog(regex)} err = refLogs[0].LoadFile(fileNames[0], il) if err != nil { fmt.Print(err) os.Exit(1) } err = refLogs[1].LoadFile(fileNames[1], il) if err != nil { fmt.Print(err) os.Exit(1) } missing := refLogs[0].GetMissing(refLogs[1]) fmt.Print(missing.String()) }
func main() { // Prepare the HTTP server server := &http.Server{ Addr: "127.0.0.1:8081", } metricsPort := "8082" flag.StringVar(&metricsPort, "mport", metricsPort, "metrics service port") flag.StringVar(&server.Addr, "addr", server.Addr, "http service address (TCP address or absolute path for UNIX socket)") origin := flag.String("origin", "", "websocket server checks Origin headers against this scheme://host[:port]") logpath := flag.String("log", "", "Log file (absolute path)") flag.Parse() if strings.HasPrefix(*logpath, "/") { logf, err := os.OpenFile(*logpath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { log.Fatalf("error opening log file: %v", err) } defer func() { log.Printf("********** pid %d stopping **********", os.Getpid()) logf.Close() }() if err = syscall.Dup2(int(logf.Fd()), syscall.Stdout); err != nil { log.Fatalf("error redirecting stdout to file: %v", err) } if err = syscall.Dup2(int(logf.Fd()), syscall.Stderr); err != nil { log.Fatalf("error redirecting stderr to file: %v", err) } log.SetFlags(log.Ldate | log.Lmicroseconds | log.LUTC) log.Printf("********** pid %d starting **********", os.Getpid()) } // Initialize metrics registry with expected stats go startMetrics(metricsPort) incr("websockets", 0) // number of connected websockets incr("channels", 0) // number of subscribed channels mark("postmsgs", 0) // rate of POST messages mark("websocketmsgs", 0) // rate of WS messages mark("drops", 0) // rate of messages sent to nobody mark("sends", 0) // rate of messages sent to somebody // Start the server server.Handler = newHandler(*origin) http.Handle("/", server.Handler) if strings.HasPrefix(server.Addr, "/") { ln, err := net.Listen("unix", server.Addr) if err != nil { panic(err) } closeListenerOnSignals(ln) server.Serve(ln) } else { server.ListenAndServe() } }
func run() int { flag.Parse() runtime := flag.Args()[1] // e.g. runc dir := flag.Args()[2] // bundlePath for run, processPath for exec containerId := flag.Args()[3] signals := make(chan os.Signal, 100) signal.Notify(signals, syscall.SIGCHLD) fd3 := os.NewFile(3, "/proc/self/fd/3") logFile := fmt.Sprintf("/proc/%d/fd/4", os.Getpid()) logFD := os.NewFile(4, "/proc/self/fd/4") syncPipe := os.NewFile(5, "/proc/self/fd/5") pidFilePath := filepath.Join(dir, "pidfile") stdin, stdout, stderr, winsz := openPipes(dir) syncPipe.Write([]byte{0}) var runcStartCmd *exec.Cmd if *tty { ttySlave := setupTty(stdin, stdout, pidFilePath, winsz, garden.WindowSize{Rows: *rows, Columns: *cols}) runcStartCmd = exec.Command(runtime, "-debug", "-log", logFile, "exec", "-d", "-tty", "-console", ttySlave.Name(), "-p", fmt.Sprintf("/proc/%d/fd/0", os.Getpid()), "-pid-file", pidFilePath, containerId) } else { runcStartCmd = exec.Command(runtime, "-debug", "-log", logFile, "exec", "-p", fmt.Sprintf("/proc/%d/fd/0", os.Getpid()), "-d", "-pid-file", pidFilePath, containerId) runcStartCmd.Stdin = stdin runcStartCmd.Stdout = stdout runcStartCmd.Stderr = stderr } // we need to be the subreaper so we can wait on the detached container process system.SetSubreaper(os.Getpid()) if err := runcStartCmd.Start(); err != nil { fd3.Write([]byte{2}) return 2 } var status syscall.WaitStatus var rusage syscall.Rusage _, err := syscall.Wait4(runcStartCmd.Process.Pid, &status, 0, &rusage) check(err) // Start succeeded but Wait4 failed, this can only be a programmer error logFD.Close() // No more logs from runc so close fd fd3.Write([]byte{byte(status.ExitStatus())}) if status.ExitStatus() != 0 { return 3 // nothing to wait for, container didn't launch } containerPid, err := parsePid(pidFilePath) check(err) return waitForContainerToExit(dir, containerPid, signals) }
func handler(w http.ResponseWriter, r *http.Request) { duration, err := time.ParseDuration(r.FormValue("duration")) if err != nil { http.Error(w, err.Error(), 400) return } fmt.Fprintf(w, "going to sleep %s with pid %d\n", duration, os.Getpid()) w.(http.Flusher).Flush() time.Sleep(duration) fmt.Fprintf(w, "slept %s with pid %d\n", duration, os.Getpid()) }
/****************************************************************************** * 概述: 事件监听初始化 * 函数名: Monitor * 返回值: error * 参数列表: 参数名 参数类型 取值范围 描述 * *******************************************************************************/ func (this *ZmqSocket) Monitor() error { addr1 := fmt.Sprintf("inproc://monitor.rep%d_%d", os.Getpid(), this.mserial) if err := this.mreqSocket.Monitor(addr1, zmq4.EVENT_CLOSED|zmq4.EVENT_DISCONNECTED|zmq4.EVENT_CONNECTED); err != nil { log4.Error("Req Monitor(%s) Failed,%s", addr1, err.Error()) return err } s1, err0 := this.mzmq.Mcontext.NewSocket(zmq4.PAIR) if err0 != nil { log4.Error("NewSocket Failed,%s", err0.Error()) return err0 } if err := s1.SetRcvtimeo(0); err != nil { log4.Error("SetRcvtimeo Failed,%s", err.Error()) return err } if err := s1.Connect(addr1); err != nil { log4.Error("Connect Failed,%s", err.Error()) return err } this.mmons1 = s1 if !strings.Contains(runtime.GOOS, "windows") { this.mpoller.Add(this.mmons1, zmq4.POLLIN) } else { this.mreqOK = true } addr2 := fmt.Sprintf("inproc://monitor.sub%d_%d", os.Getpid(), this.mserial) if err := this.msubSocket.Monitor(addr2, zmq4.EVENT_CLOSED|zmq4.EVENT_DISCONNECTED|zmq4.EVENT_CONNECTED); err != nil { log4.Error("Sub Monitor(%s) Failed,%s", addr2, err.Error()) return err } s2, err1 := this.mzmq.Mcontext.NewSocket(zmq4.PAIR) if err1 != nil { log4.Error("NewSocket Failed,%s", err1.Error()) return err1 } if err := s2.SetRcvtimeo(0); err != nil { log4.Error("SetRcvtimeo Failed,%s", err.Error()) return err } if err := s2.Connect(addr2); err != nil { log4.Error("Connect Failed,%s", err.Error()) return err } this.mmons2 = s2 if !strings.Contains(runtime.GOOS, "windows") { this.mpoller.Add(this.mmons2, zmq4.POLLIN) } else { this.msubOK = true } return nil }
func TestSendSinkNoRoute(t *testing.T) { var sink mockReceiver r := NewRouter(&sink) if err := r.Send([]byte("hello"), nil); err != nil { t.Fatal(err) } a, b, err := os.Pipe() if err != nil { t.Fatal(err) } defer a.Close() defer b.Close() if err := r.Send([]byte("world"), a); err != nil { t.Fatal(err) } if len(sink) != 2 { t.Fatalf("%#v\n", sink) } if string(sink[0].payload) != "hello" { t.Fatalf("%#v\n", sink) } if sink[0].attachment != nil { t.Fatalf("%#v\n", sink) } if string(sink[1].payload) != "world" { t.Fatalf("%#v\n", sink) } if sink[1].attachment == nil || sink[1].attachment.Fd() > 42 || sink[1].attachment.Fd() < 0 { t.Fatalf("%v\n", sink) } var tasks sync.WaitGroup tasks.Add(2) go func() { defer tasks.Done() fmt.Printf("[%d] Reading from '%d'\n", os.Getpid(), sink[1].attachment.Fd()) data, err := ioutil.ReadAll(sink[1].attachment) if err != nil { t.Fatal(err) } if string(data) != "foo bar\n" { t.Fatalf("%v\n", string(data)) } }() go func() { defer tasks.Done() fmt.Printf("[%d] writing to '%d'\n", os.Getpid(), a.Fd()) if _, err := fmt.Fprintf(b, "foo bar\n"); err != nil { t.Fatal(err) } b.Close() }() tasks.Wait() }
// Serve will serve the given http.Servers and will monitor for signals // allowing for graceful termination (SIGTERM) or restart (SIGUSR2). func Serve(servers ...*http.Server) error { a := newApp(servers) // Acquire Listeners if err := a.listen(); err != nil { return err } // Some useful logging. if *verbose { if didInherit { if ppid == 1 { log.Printf("Listening on init activated %s", pprintAddr(a.listeners)) } else { const msg = "Graceful handoff of %s with new pid %d and old pid %d" log.Printf(msg, pprintAddr(a.listeners), os.Getpid(), ppid) } } else { const msg = "Serving %s with pid %d" log.Printf(msg, pprintAddr(a.listeners), os.Getpid()) } } // Start serving. a.serve() // Close the parent if we inherited and it wasn't init that started us. if didInherit && ppid != 1 { if err := syscall.Kill(ppid, syscall.SIGTERM); err != nil { return fmt.Errorf("failed to close parent: %s", err) } } waitdone := make(chan struct{}) go func() { defer close(waitdone) a.wait() }() select { case err := <-a.errors: if err == nil { panic("unexpected nil error") } return err case <-waitdone: if *verbose { log.Printf("Exiting pid %d.", os.Getpid()) } return nil } }
// getAPI server instance func getAPIServer(conf api.Config, apiHandler http.Handler) (*http.Server, error) { // Minio server config httpServer := &http.Server{ Addr: conf.Address, Handler: apiHandler, MaxHeaderBytes: 1 << 20, } if conf.TLS { var err error httpServer.TLSConfig = &tls.Config{} httpServer.TLSConfig.Certificates = make([]tls.Certificate, 1) httpServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(conf.CertFile, conf.KeyFile) if err != nil { return nil, iodine.New(err, nil) } } host, port, err := net.SplitHostPort(conf.Address) if err != nil { return nil, iodine.New(err, nil) } var hosts []string switch { case host != "": hosts = append(hosts, host) default: addrs, err := net.InterfaceAddrs() if err != nil { return nil, iodine.New(err, nil) } for _, addr := range addrs { if addr.Network() == "ip+net" { host := strings.Split(addr.String(), "/")[0] if ip := net.ParseIP(host); ip.To4() != nil { hosts = append(hosts, host) } } } } for _, host := range hosts { if conf.TLS { fmt.Printf("Starting minio server on: https://%s:%s, PID: %d\n", host, port, os.Getpid()) } else { fmt.Printf("Starting minio server on: http://%s:%s, PID: %d\n", host, port, os.Getpid()) } } return httpServer, nil }
func main() { runtime.GOMAXPROCS(1) log.SetFlags(log.LstdFlags | log.Lmicroseconds) flag.Parse() maybeSubcommand() cfg := config.LoadConfig(*configPath) log.Printf("config:\n%#v", *cfg) log.Printf("PID: %d", os.Getpid()) ioutil.WriteFile("/var/run/pesho.pid", []byte(fmt.Sprintf("%d", os.Getpid())), 0644) d, err := door.NewFromConfig(cfg.Door) if err != nil { log.Fatalf("Could not init door GPIOs: %v", err) } b, err := newButtons(cfg.Buttons.Red, cfg.Buttons.Green) if err != nil { log.Fatalf("Could not init button GPIOs: %v", err) } p := &pesho{ door: d, closeOnce: &sync.Once{}, dying: make(chan struct{}), } go p.interruptHandler() p.workers.Add(1) go p.httpServer(cfg.Web) p.workers.Add(1) go p.stateMonitor() p.workers.Add(1) go p.hangupHandler() p.workers.Add(1) go p.buttonHandler(b) if len(cfg.NotificationURL) != 0 { log.Printf("Sending notifications at %s", cfg.NotificationURL) p.workers.Add(1) go p.webNotifier(cfg.NotificationURL, cfg.SecretNotificationToken) } p.workers.Wait() }
func TestGetLockFilePid(t *testing.T) { f := createTestLock(t) defer os.Remove(f.Name()) defer f.Close() pid, err := GetLockFilePid(f.Name()) if err != nil { t.Fatal("Expected no error while getting PID, got:", err) } if pid != os.Getpid() { t.Errorf("Invalid PID: expected %v but got %v", os.Getpid(), pid) } }
func NewGpkg(loglevel string) *Gpkg { gpkg := &Gpkg{} gpkg.Logger = NewLogger("", LevelFromString(loglevel)) gvm := NewGvm(gpkg.Logger) gpkg.Gvm = gvm rand.Seed(time.Now().Unix()) if os.Getpid() != -1 { gpkg.tmpdir = filepath.Join(os.Getenv("GVM_ROOT"), "tmp", strconv.Itoa(os.Getpid())) } else { gpkg.tmpdir = filepath.Join(os.Getenv("GVM_ROOT"), "tmp", strconv.Itoa(rand.Int())) } return gpkg }
func TestFindProcess(t *testing.T) { p, err := FindProcessByPid(os.Getpid()) if err != nil { t.Fatalf("err: %s", err) } if p == nil { t.Fatal("should have process") } if p.Pid() != os.Getpid() { t.Fatalf("bad: %#v", p.Pid()) } }
func (this *graceImplement) listenAndServeGrace(httpPort string, handler http.Handler) error { //倾听端口 this.graceNet = &gracenet.Net{} listener, err := this.graceNet.Listen("tcp", httpPort) if err != nil { return err } if didInherit { if ppid == 1 { globalBasic.Log.Debug("Listening on init activated %v", httpPort) } else { globalBasic.Log.Debug("Graceful handoff of %v with new pid %v and old pid %v", httpPort, os.Getpid(), ppid) } } else { globalBasic.Log.Debug("Serving %s with pid %d", httpPort, os.Getpid()) } //对外服务 httpServer := &httpdown.HTTP{} this.graceServer = httpServer.Serve(&http.Server{ Addr: httpPort, Handler: handler, }, listener) //关闭父级进程 if didInherit && ppid != 1 { if err := syscall.Kill(ppid, syscall.SIGTERM); err != nil { return fmt.Errorf("failed to close parent: %s", err) } } //等待服务器结束 errorEvent := make(chan error) waitEvent := make(chan bool) go func() { defer close(waitEvent) this.waitServerStop(errorEvent) }() select { case err := <-errorEvent: if err == nil { panic("unexpected nil error") } return err case <-waitEvent: globalBasic.Log.Debug("Exiting pid %v.", os.Getpid()) return nil } }