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  }