okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

Aly Raffaufrefactor(cli): extract local daemon lifecycled9c1a13

main
1.3 KiB46 linesraw
1//go:build unix
2
3package localdaemon
4
5import (
6	"errors"
7	"os"
8	"os/exec"
9	"syscall"
10)
11
12// detach starts the daemon in its own session so closing the launching
13// terminal (SIGHUP to its process group) does not take the daemon down.
14func detach(cmd *exec.Cmd) {
15	cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
16}
17
18// passFileLimit gives the daemon the open-file limit this process runs with.
19// Go raises its own soft limit at startup but starts children with the
20// original one, 256 on macOS: too few for a daemon holding client
21// connections, kernels and databases. Setting the limit explicitly, even to
22// the value it already has, makes every later child inherit it.
23func passFileLimit() {
24	var limit syscall.Rlimit
25	if syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit) == nil {
26		_ = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit)
27	}
28}
29
30func processAlive(pid int) bool {
31	if pid <= 0 {
32		return false
33	}
34	err := syscall.Kill(pid, 0)
35	return err == nil || errors.Is(err, syscall.EPERM)
36}
37
38func tryLauncherLock(file *os.File) (bool, error) {
39	err := syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
40	if errors.Is(err, syscall.EWOULDBLOCK) || errors.Is(err, syscall.EAGAIN) {
41		return false, nil
42	}
43	return err == nil, err
44}
45
46func endpointRefused(err error) bool { return errors.Is(err, syscall.ECONNREFUSED) }