Hi all,

Ruby 1.6.7 on Solaris 8.

I'm working on a Ruby extension for the 'ps' command.  I've got a
working version for Linux (at home), but I'm hitting a snag with my
Solaris version.  It compiles, it runs - then it core dumps.  The
problem appears to be something it doesn't like about the way I create
my return struct.  There are some debug printf statements in there.  It
appears to core dump the moment it tries to return a rb_struct.  Any
ideas?  Something wrong with the way I create the struct?  Some malloc
that needs doing?

Here's the source, plus a simple extconf.rb and test.rb

Thanks much.

Dan

---------------

# extconf.rb
require 'mkmf'
create_makefile('sys/proctable')

# test.rb
require 'sys/proctable'
include Sys

ProcTable.ps do |p|
   puts "Pid: " + p.pid.to_s
   puts "PPid: " + p.ppid.to_s
end


/***************************************************
 * Solaris specific code for the Ruby ps extension
 ***************************************************/
#include "ruby.h"
#include <stdio.h>
#include <dirent.h>
#include <procfs.h>
#include <sys/param.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#ifdef __cplusplus
extern "C"
{
#endif

VALUE cProcTable, sProcStruct;

static void proctable_free(void *p)
{
   free(p);
}

static VALUE proctable_getprocstruct(struct psinfo *p)
{
   printf("Creating proc struct\n");
   return rb_struct_new(sProcStruct,
      UINT2NUM(p->pr_pid),
      UINT2NUM(p->pr_ppid)
   );
}

static VALUE proctable_ps()
{
   DIR *procdir;
   struct dirent *procdirp;
   int psdata;
   char pathbuf[MAXPATHLEN];
   struct psinfo p;

   if( (procdir = opendir( "/proc" )) == NULL ) return;

   while( (procdirp = readdir(procdir)) != NULL )
   {
      printf("In the loop...\n");
      /* Only look at this file if it's a proc id; that is, all numbers
*/
      if( strtok(procdirp->d_name, "0123456789") != NULL ){ continue; }
      printf("We're looking at numbered dirs...\n");

      /* Construct path of the form /proc/proc_number */
      strcpy( pathbuf, "/proc/");
      strcat( pathbuf, procdirp->d_name );

      strcat( pathbuf, "/psinfo" ); /* Solaris 2.6+ has process info
here */
      printf("Directory is now: %s\n",pathbuf);

      if( (psdata = open( pathbuf, O_RDONLY )) == -1 ) continue;

      read(psdata, (void *) &p, sizeof(struct psinfo) );
      printf("Data read into psdata struct\n");
      printf("Pid: %lu\n",p.pr_pid);

      close(psdata);

      printf("psdata closed\n");
      if( rb_block_given_p() )
      {
         VALUE temp = proctable_getprocstruct(&p);
         /*rb_yield( proctable_getprocstruct(&p) );*/
         printf("Struct created\n");
         rb_yield(temp);
      }
      printf("Yo - we ain't making it here\n");
   }
   closedir(procdir);
}

void Init_proctable()
{
   VALUE sys_mSys;

   sys_mSys = rb_define_module("Sys");
   cProcTable = rb_define_class_under(sys_mSys, "ProcTable",
rb_cObject);

   rb_struct_define("ProcTable::ProcStruct","pid","ppid",0);
   /*rb_global_variable(&sProcStruct);*/

   rb_define_singleton_method(cProcTable, "ps", proctable_ps, 0);
}

#ifdef __cplusplus
}
#endif