Howto make something like Errno::##, for my C ext, or do I need to?

I'm wrapping a library, it returns its errors as numbers (many of them,
too many to wrap even automatically), and I don't know how to raise
exceptions.

I've looked at how ruby deals with unix error numbers. I guess I
could cut-n-paste all the code to that my extension does the same... but
that seems wrong, somehow.

What I'd really like to do is have only one error class, but raise
objects as exceptions, with the objects @errno set to the value,
I'd do this in ruby like this:

  class MyErr < StandardError
    attr_reader :eno
    def initialize(eno); @eno = eno; end
  end

  ...
    raise MyError.new(35)

Looking at the exception raising APIs in README.EXT, I can't quite see
how to do this.

Does anybody have any suggestions?

Thanks a lot,
Sam

···

--
http://www.certicom.com

Sam Roberts wrote:

I'm wrapping a library, it returns its errors as numbers (many of

them,

too many to wrap even automatically), and I don't know how to raise
exceptions.

I've looked at how ruby deals with unix error numbers. I guess I
could cut-n-paste all the code to that my extension does the same...

but

that seems wrong, somehow.

What I'd really like to do is have only one error class, but raise
objects as exceptions, with the objects @errno set to the value,
I'd do this in ruby like this:

  class MyErr < StandardError
    attr_reader :eno
    def initialize(eno); @eno = eno; end
  end

  ...
    raise MyError.new(35)

Looking at the exception raising APIs in README.EXT, I can't quite

see

how to do this.

In short:
rb_exc_raise(my_err_new(eno));

You probably want to have the ability to add a message to your error
objects so you may want to do:
rb_exc_raise(my_err_new("msg", eno));

or define a function like

static void
raise_my_err(int eno, const char *fmt, ...)
{
    va_list args;
    char buf[BUFSIZ];

    va_init_list(args, fmt);
    vsnprintf(buf, BUFSIZ, fmt, args);
    va_end(args);
    rb_exc_raise(my_err_new(buf, eno));
}

most of the above is a copy and paste from code in error.c. I think
your new function would look something like this:

static VALUE
my_err_new(const char *buf, int eno)
{
  VALUE self = rb_exc_new2(cMyErr, buf);
  rb_iv_set(self, "@eno", INT2FIX(eno));
  return self;
}

-Charlie