gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/system/service/service_systemd_notify_linux.go (about) 1 package svc 2 3 import ( 4 "gitee.com/sy_183/go-common/strings/unsafe" 5 "net" 6 "os" 7 "syscall" 8 ) 9 10 //func SystemdPidNotifyWithFds(pid int, unsetEnvironment bool, state string, fds []int) error { 11 // address := os.Getenv("NOTIFY_SOCKET") 12 // if address == "" { 13 // return nil 14 // } 15 // 16 // defer func() { 17 // if unsetEnvironment { 18 // assert.MustSuccess(os.Unsetenv("NOTIFY_SOCKET")) 19 // } 20 // }() 21 // 22 // if state == "" { 23 // return syscall.EINVAL 24 // } 25 // addr := assert.Must(net.ResolveUnixAddr("unixgram", address)) 26 // conn, err := net.DialUnix("unixgram", nil, addr) 27 // if err != nil { 28 // return err 29 // } 30 // 31 // curPid := os.Getpid() 32 // uid := os.Getuid() 33 // gid := os.Getgid() 34 // sendUcred := (pid != 0 && pid != curPid) || uid != os.Geteuid() || gid != os.Getegid() 35 // 36 // if len(fds) > 0 || sendUcred { 37 // var fdsCmsgSpace, ucredCmsgSpace int 38 // if len(fds) > 0 { 39 // fdsCmsgSpace = syscall.CmsgSpace(int(unsafe.Sizeof(int32(0))) * len(fds)) 40 // } 41 // if sendUcred { 42 // ucredCmsgSpace = syscall.CmsgSpace(int(unsafe.Sizeof(syscall.Ucred{}))) 43 // } 44 // msgControl := make([]byte, fdsCmsgSpace+ucredCmsgSpace) 45 // 46 // p := msgControl 47 // cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&p[0])) 48 // if len(fds) > 0 { 49 // cmsg.Level = syscall.SOL_SOCKET 50 // cmsg.Type = syscall.SCM_RIGHTS 51 // cmsg.Len = uint64(syscall.CmsgLen(int(unsafe.Sizeof(int32(0))) * len(fds))) 52 // p = p[unsafe.Sizeof(syscall.Cmsghdr{}):] 53 // for _, fd := range fds { 54 // binary.LittleEndian.PutUint32(p, uint32(fd)) 55 // p = p[unsafe.Sizeof(uint32(0)):] 56 // } 57 // } 58 // if sendUcred { 59 // p = msgControl[fdsCmsgSpace:] 60 // cmsg = (*syscall.Cmsghdr)(unsafe.Pointer(&p[0])) 61 // cmsg.Level = syscall.SOL_SOCKET 62 // cmsg.Type = syscall.SCM_CREDENTIALS 63 // cmsg.Len = uint64(syscall.CmsgLen(int(unsafe.Sizeof(syscall.Ucred{})))) 64 // p = p[unsafe.Sizeof(syscall.Cmsghdr{}):] 65 // ucred := (*syscall.Ucred)(unsafe.Pointer(&p[0])) 66 // ucred.Pid = int32(pid) 67 // if pid == 0 { 68 // ucred.Pid = int32(curPid) 69 // } 70 // ucred.Uid = uint32(uid) 71 // ucred.Gid = uint32(gid) 72 // } 73 // 74 // _, _, err := conn.WriteMsgUnix(uns.StringToBytes(state), msgControl, addr) 75 // if err != nil { 76 // if sendUcred { 77 // if len(fds) > 0 { 78 // _, _, err := conn.WriteMsgUnix(uns.StringToBytes(state), msgControl[:fdsCmsgSpace], addr) 79 // return err 80 // } 81 // _, _, err = conn.WriteMsgUnix(uns.StringToBytes(state), nil, addr) 82 // return err 83 // } 84 // return err 85 // } 86 // } 87 // 88 // _, _, err = conn.WriteMsgUnix(uns.StringToBytes(state), nil, addr) 89 // return err 90 //} 91 // 92 //func SystemdPidNotify(pid int, unsetEnvironment bool, state string) error { 93 // return SystemdPidNotifyWithFds(pid, unsetEnvironment, state, nil) 94 //} 95 96 // SystemdNotify function notify service manager about start-up completion and 97 // other service status changes 98 func SystemdNotify(state string) error { 99 address := os.Getenv("NOTIFY_SOCKET") 100 if address == "" { 101 return nil 102 } 103 104 if state == "" { 105 return syscall.EINVAL 106 } 107 addr, err := net.ResolveUnixAddr("unixgram", address) 108 if err != nil { 109 return err 110 } 111 conn, err := net.DialUnix("unixgram", nil, addr) 112 if err != nil { 113 return err 114 } 115 _, err = conn.Write(unsafe.Bytes(state)) 116 return err 117 }