用golang启动一个daemon
用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 }