In Ruby, a call to Process.setsid
fails with "Operation not permitted" error if it's run as non-superuser. Try:
$ irb
irb(main):001:0> Process.setsid
Errno::EPERM: Operation not permitted
from (irb):1:in `setsid'
from (irb):1
from ~/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
Or, it fails with the same error if I change the uid or the process using Process.uid=
method. It works fine if I run the Ruby program as root, and I do not change the UID of the process during runtime.
However, in Ubuntu's or some other distro's shell, the setsid
(reference: http://linux.die.net/man/2/setsid ) program does not require superuser privileges.
I understand that stdsid
resets the program's session, which is also useful when daemonizing a process. In my code, I'm attempting to change the UID as well as daemonize it, while also resetting the session.
Hence, I'm curious why Process.setsid
requires the said privileges, while the setsid
program on most UNIX like OSes does not.
Process.setsid is a thin wrap around POSIX setsid(2) whose man page says:
Errors
EPERM
The process group ID of any process equals the PID of the calling process. Thus, in particular, setsid() fails if the calling process is already a process group leader.
When your program runs, it's already a group leader. When deamonizing, you're expected to fork a new process for your daemon. Process.setsid
works without EPERM error after you fork:
$ irb
irb> Process.setsid
Errno::EPERM: Operation not permitted
from (irb):1:in `setsid'
from (irb):1
from /Users/dbenhur/.rbenv/versions/1.9.3-p194/bin/irb:12:in `<main>'
irb> fork { Process.setsid }
=> 3359
Take a look at Rexec or unicorn for examples of POSIX daemonization in Ruby.
The setsid(1) program doesn't get an EPERM error because it forks before calling setsid(2). See line 31 here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With