Checking whether a process exists (unix)

To check whether a process with a given ID is still running on unix, I would
normally use the following C code …

if (kill(pid, 0) == 0)
printf(“alive”);
else
printf(“dead”);

However, the return code from Process.kill() doesn’t seem to match the system
call. Having a cursory look at the source in process.c (version 1.6.7), it
looks like the value returned is the number of kill() calls that were
successfully made.

Does anyone know of a way to achieve what I need … ie, determine whether a
process with the given ID still exists, or will I have to write a small C
extension?

I realise I could do a popen of “ps” and parse the output, but that’s pretty
messy (and expensive) for such a simple task.

Thanks in advance.

Harry O.

As usual, I just realised that I’ve misunderstood the problem. Given the way
Process.kill() works, I should still be able to tell whether the process is
running, because once it’s gone, Process.kill() should return zero.

So, I did a little more investigation and discovered that once the process had
exited, it was still hanging around as a defunct process.

This surprises me somewhat. What I’m doing (in essence) is …

if pid = Kernel.fork.nil?
exec “/bin/sleep”, 30
else
loop do
puts (Process.kill(0, pid) == 1) ? “alive” : "dead"
sleep 10
end
end

I would have thought that once the /bin/sleep had completed, the child process
would disappear, but, as I say, it seems to become a defunct process.
Obviously, I don’t want that.

Any ideas?

When kill() doesn’t actually kill a process, it seems to raise an
Errno::ESRCH exception (on both Ruby-1.6.7 and Ruby-1.7.2).

I’ve been doing this to determine if a process is running:
def is_running(pid)
return Process.getpgid(pid) != -1
end

but this doesn’t work on Ruby 1.7, since it raises an Errno::ESRCH
instead of returning -1. So I have had to modify it to do this:
def is_running(pid)
begin
return Process.getpgid(pid) != -1
rescue Errno::ESRCH
return false
end
end

Paul

···

On Fri, Aug 02, 2002 at 03:41:35AM +0900, Harry Ohlsen wrote:

To check whether a process with a given ID is still running on unix, I would
normally use the following C code …

if (kill(pid, 0) == 0)
printf(“alive”);
else
printf(“dead”);

However, the return code from Process.kill() doesn’t seem to match the system
call. Having a cursory look at the source in process.c (version 1.6.7), it
looks like the value returned is the number of kill() calls that were
successfully made.

Ignore my previous ramblings. I’ve worked it out.

In case it helps someone else …

The process was defunct because the parent hadn’t done a wait() for it. I was
able to change my status checking to the equivalent of

puts (Process.waitpid(pid, Process:WNOHANG) == pid) ? “dead” : “alive”

which works a treat (although, I’ll have to think a bit more about error
cases).

Harry Ohlsen wrote:

Ignore my previous ramblings. I’ve worked it out.

In case it helps someone else …

The process was defunct because the parent hadn’t done a wait() for it. I
was able to change my status checking to the equivalent of

puts (Process.waitpid(pid, Process:WNOHANG) == pid) ? “dead” : “alive”

which works a treat (although, I’ll have to think a bit more about error
cases).

Hi Harry,

I don’t know if you’re interested, but I wrote a Ruby extension to the 'ps’
command called “Sys/ProcTable”. It’s available on the RAA and works for
Linux and Solaris. I hope to have a BSD version working soon as well.

With it, you can check the status (i.e. zombie, active, etc), among other
things.

Regards,

Dan