import ("syscall""os")// Detach detaches the current program by forking and exiting the parent.// It returns an error only if it was unable to fork.func Detach() os.Error {r1, r2, err1 := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)if err1 != 0 {return os.NewSyscallError("fork", int(err1))}// On Darwin:// r1 = child pid in both parent and child.// r2 = 0 in parent, 1 in child.// Normal Unix:// r1 = 0 in child.if (syscall.OS == "darwin" && r2 == 1) || r1 == 0 {return nil}syscall.RawSyscall(syscall.SYS_EXIT, 0, 0, 0)// This really should not be possible...panic("Exit failed")}
> With the caveat that I don't need to worry about Windows, is there a better
> way than this to have a program detach itself?
You usually want to have the child call setsid. Otherwise you can still
get signals from the controlling terminal of the parent.
Ian
On Wed, Oct 19, 2011 at 04:43:15PM -0700, Paul Borman wrote:
> With the caveat that I don't need to worry about Windows, is there a
> better way than this to have a program detach itself?
You need to fork, setpgid nad fork again... and only all that if there
is only one goroutine, with appropriate locking.
I have a rough idea on how this *might* work for Mac OS/Linux but it's
not properly implemented yet.
Maybe this weekend.
> With the caveat that I don't need to worry about Windows, is there a
> better way than this to have a program detach itself?
You need to fork, setpgid nad fork again... and only all that if there
> No reason to keep forking, a single setsid is all you need before you
> return. I didn't add it in because you can do that after Detach returns
> (and in my case I actually don't have to worry about the signals).
you want to reparent to init not the controlling process
> So, this should teach me to program at 30,000 feet.
go-wiki?
If any threads have started - and that's always a possibility -
your program will get very confused and basically stop working
if you make the parent exit and have the child continue.
Russ
Yes. In fact that's now enabled at tip.
We'll no doubt do something for daemonize at some point,
but it is not trivial.
Russ