downmovies 发表于 2018-9-20 08:01:03

用golang启动一个daemon

1 package main  

2  
3 import (
  
4   "fmt"
  
5   "log"
  
6   "os"
  
7   "runtime"
  
8   "syscall"
  
9   "time"
  
10 )
  
11
  
12 func daemon(nochdir, noclose int) int {
  
13   var ret, ret2 uintptr
  
14   var err syscall.Errno
  
15
  
16   darwin := runtime.GOOS == "darwin"
  
17
  
18   // already a daemon
  
19   if syscall.Getppid() == 1 {
  
20         return 0
  
21   }
  
22
  
23   // fork off the parent process
  
24   ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
  
25   if err != 0 {
  
26         return -1
  
27   }
  
28
  
29   // failure
  
30   if ret2 < 0 {
  
31         os.Exit(-1)
  
32   }
  
33
  
34   // handle exception for darwin
  
35   if darwin && ret2 == 1 {
  
36         ret = 0
  
37   }
  
38
  
39   // if we got a good PID, then we call exit the parent process.
  
40   if ret > 0 {
  
41         os.Exit(0)
  
42   }
  
43
  
44   /* Change the file mode mask */
  
45   _ = syscall.Umask(0)
  
46
  
47   // create a new SID for the child process
  
48   s_ret, s_errno := syscall.Setsid()
  
49   if s_errno != nil {
  
50         log.Printf("Error: syscall.Setsid errno: %d", s_errno)
  
51   }
  
52   if s_ret < 0 {
  
53         return -1
  
54   }
  
55
  
56   if nochdir == 0 {
  
57         os.Chdir("/")
  
58   }
  
59
  
60   if noclose == 0 {
  
61         f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
  
62         if e == nil {
  
63             fd := f.Fd()
  
64             syscall.Dup2(int(fd), int(os.Stdin.Fd()))
  
65             syscall.Dup2(int(fd), int(os.Stdout.Fd()))
  
66             syscall.Dup2(int(fd), int(os.Stderr.Fd()))
  
67         }
  
68   }
  
69
  
70   return 0
  
71 }
  
72
  
73 func main() {
  
74   daemon(0, 1)
  
75   for {
  
76         fmt.Println("hello")
  
77         time.Sleep(1 * time.Second)
  
78   }
  
79
  
80 }


页: [1]
查看完整版本: 用golang启动一个daemon