PORTING:

All os-specific code resides in C source and header files in the os
subdirectory. The source file for a particular os is linked to "OS.c"
in the toplevel directory of the distribution by code in a hints file,
which can also set any preprocessor DEFINES needed by a particular
version of the operating system in case the hints mechanism doesn't
have fine enough granularity. I have tried to design the API for this
module as simply and portably as possible. Ideally, the os-specific
code should be self-contained and trivially useable from any language.

An os-specific module needs to implement two functions with these
prototypes: 

char* OS_initialize();
void OS_get_table();

OS_initialize() performs any one-time initialization the module needs
to do, such as setting global variables, and can check for error
conditions (e.g. permissions to access /dev/kmem, /proc mounted
etc.). If it detects a fatal error condition, it should return a
pointer to a statically allocated error string, which is passed on to
Perl's croak() function. Otherwise, it should return a null pointer.
OS_initialize is called once, by the Proc::ProcessTable::new() method.

OS_get_table is called by the Proc::ProcessTable::table() method to
iterate over the process table. For every process, OS_get_table() must
call the function bless_into_proc(), which is defined in
ProcessTable.xs.  bless_into_proc() creates a new
Proc::ProcessTable::Process object for the process (implemented as a
hash) and adds it to the array that is returned by
Proc::ProcessTable::table(). bless_into_proc() has the following
prototype: 

void bless_into_proc(char* format, char** fields, ...)

The "format" argument is a string that contains format specifiers for
each of the fields. Any field that is not an int or a long
(e.g. float) must be converted and passed as a string.  When no valid
value was obtained for a field, the format character is capitalized to
indicate that the field value should be ignored by bless_into_proc(),
which will insert an "undef" value into the hash for that field.  The
possible format specifiers are:

"s" for a char*
"S" for a char* to be ignored
"i" for int 
"I" for int to be ignored
"l" for long
"L" for long to be ignored
"j" for long long
"J" for long long to be ignored
"V" for perl scalar value (like a reference to an array)

The fields argument is a pointer to a list of field
names. The variable argument list contains the field values. Note that
fields which are to be ignored must still have a placeholder to keep
the lists in sync.

It would be nice to maintain some consistency in the fields returned
(process object attributes) across operating systems; ideally some
minimal set of fields would be supported for all operating systems,
with whatever other information is useful and easy to gather. Field
names at least should be consistent, as should the names for process
states as far as possible. PLEASE make the basic field names as
consistent as possible with those listed in the "README.linux" file in
the distribution so that scripts will work across operating systems. 

These fields have some special handling:

ttynum		The tty device number. When this is returned,
		bless_into_proc performs a lookup of the device name 
		and a "ttydev" field is added. The mapping of tty
		device names to numbers is done at initialization time.

state		Process state. I prefer to return a string instead of 
		a char, since the single char states don't have a
		consistent meaning across OS's. For linux, I use
		"run", "sleep", "uwait", "zombie" and "stop".

See "os/Linux.c" for an example.

For warnings/exceptions in OS code, please use ppt_warn() and
ppt_croak(). These call perl's warn and croak functions, and thus play
nice with perl's exception handling mechanism. Both functions take
printf() style arguments.
