There's a subtle bug in the sys-proctable library that inspired me to attempt rewrites for the various platforms in pure Ruby. I've decided the loss in speed is heavily outweighed by the ease of maintenance.
Unlike Linux, Solaris stores process information in a binary format under /proc/<pid>/psinfo. Having done lots of pure Ruby win32-api programming now, I've become accustomed to unraveling binary data.
There was one problem, however. Solaris stores command line arguments for any given process in a separate file, /proc/<pid>/as. This file is special sparse file, and you can't use a standard IO seek & read because you need to read without moving the file pointer. You have to use something like lseek or pread. Ruby supports neither.
So, I updated my io-extra library to wrap both pread and pwrite, and used that. While using my current C code as a guideline (printing out addresses mostly), I also discovered a bug in the C version. Ugh.
Anyway, here's the final solution, which I also posted to ruby-talk:
require 'io/extra'
# Mozilla on Solaris. Adjust pid as needed.
#
# ps -ef shows "/bin/ksh", "-p", and "/usr/sfw/bin/mozilla"
#
pid = 2253
# Unravel some info we need from the psinfo struct
psinfo = IO.read("/proc/#{pid}/psinfo")
pr_argc = psinfo[188, 4].unpack("L")[0]
pr_argv = psinfo[192, 4].unpack("L")[0]
# Second, get our initial address from /proc/<pid>/as
fd = File.open("/proc/#{pid}/as")
addr = IO.pread(fd.fileno, pr_argc * 4, pr_argv).unpack("L")[0]
# Third, get each command argument, incrementing the address as
# needed. I've hard coded the read limit at 128. Adjust as needed.
0.upto(pr_argc - 1){ |i|
data = IO.pread(fd.fileno, 128, addr)
addr += data.length + 1 # Add 1 for the space
p data
}
# Finally, close our file descriptor
fd.close