[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

C extension question

snacktime

9/18/2006 5:58:00 PM

So I'm making some headway on a kerberos 5 extension for ruby. It's
limited at the moment to authorizing a user, changing a user password,
creating principals, and deleting principals, but it's working. Now
I'm trying to refactor it a bit and need some assistance. I've never
really coded in C before so bear with me..

In kerberos when doing an administration function I first need to
initialize the system with the credentials of an administrative user
like so, with handle being a void pointer initialized to NULL. The
following kerberos function will fill handle with a handle for the
connection which I can use in subsequent calls to other kadm5
functions.

kadm5_init_with_password(auser, apass, KADM5_ADMIN_SERVICE, NULL,
KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &handle);

Now what I'd like is to return that handle to ruby and be able to pass
it back into my C extension when it's needed, such as when needing to
call the following kerberos function.

kadm5_create_principal(handle, &princ, mask, pass);

So how would I do this? If I understand void pointers correctly,
handle could be any type after the call to kadm5_init_with_password,
so it seems I would want to check it's type after it's set, then find
the right type/structure to convert it to or wrap it in before passing
it back to ruby? Not that I know how to do that:)

Chris

5 Answers

Aria Stewart

9/18/2006 6:44:00 PM

0

On Tue, 2006-09-19 at 03:39 +0900, Francis Cianfrocca wrote:
> On 9/18/06, snacktime <snacktime@gmail.com> wrote:
> >
> > In kerberos when doing an administration function I first need to
> > initialize the system with the credentials of an administrative user
> > like so, with handle being a void pointer initialized to NULL. The
> > following kerberos function will fill handle with a handle for the
> > connection which I can use in subsequent calls to other kadm5
> > functions.
> >
> > kadm5_init_with_password(auser, apass, KADM5_ADMIN_SERVICE, NULL,
> > KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &handle);
> >
> > Now what I'd like is to return that handle to ruby and be able to pass
> > it back into my C extension when it's needed, such as when needing to
> > call the following kerberos function.
> >
> > kadm5_create_principal(handle, &princ, mask, pass);
> >
> > So how would I do this? If I understand void pointers correctly,
> > handle could be any type after the call to kadm5_init_with_password,
> > so it seems I would want to check it's type after it's set, then find
> > the right type/structure to convert it to or wrap it in before passing
> > it back to ruby? Not that I know how to do that:)


> Void* is almost always the same size as the native integer. (There is
> legitimate controversy over this point but you can depend on it for all ends
> and intents.)

Better to wrap it as a data type in Ruby, which gives you a ruby VALUE
which references the native data. There's a simple macro to grab the
original pointer given the VALUE.

DEC Alpha doesn't necessarily have sizeof(int) == sizeof(void *), so
please don't assume so. I hate fixing code that does that. ;-)

Aria (A kerberos user, too!)


snacktime

9/18/2006 7:15:00 PM

0

> Better to wrap it as a data type in Ruby, which gives you a ruby VALUE
> which references the native data. There's a simple macro to grab the
> original pointer given the VALUE.
>
> DEC Alpha doesn't necessarily have sizeof(int) == sizeof(void *), so
> please don't assume so. I hate fixing code that does that. ;-)
>
> Aria (A kerberos user, too!)

Well I'll do the grunt work and then when I release it I'll accept
patches from those with more C experience than I have. I actually
can't remember if I ever wrote a C program before, but I've been
meaning to learn it so I figured this was as good a project as any
since we have some use for kerberos bindings.

snacktime

9/18/2006 7:49:00 PM

0

One more unrelated question. I'm trying to think of the best way to
do the interface, particularly how to access error messages and what
to return to the caller. For most functions the caller just needs to
know if the function returned true, or if there was an error a way to
get the error message. So, I could for example return 0 on success or
the error message number on failure. Or I could return true/false,
store any error message number in a C global variable, and then have a
function which returns the text error message if the original function
returned false.

The latter seems more intuitive. For example

krb = Krb5.new
if krb.authenticate_with_password(user,pass)
# authenticated
else
p krb.errstr
end

As opposed to:

res = krb.authenticate(user,pass)
if res == 0
# authenticated
else
p krb.errstr(res)
end

And in the case where a method returns a handle that will be used
later, I'm thinking return the handle on success, and on failure
return nil and make the error available via krb.errstr?

Chris

Francis Cianfrocca

9/18/2006 7:58:00 PM

0

On 9/18/06, snacktime <snacktime@gmail.com> wrote:
> One more unrelated question. I'm trying to think of the best way to
> do the interface, particularly how to access error messages and what
> to return to the caller. For most functions the caller just needs to
> know if the function returned true, or if there was an error a way to
> get the error message. So, I could for example return 0 on success or
> the error message number on failure. Or I could return true/false,
> store any error message number in a C global variable, and then have a
> function which returns the text error message if the original function
> returned false.
>
> The latter seems more intuitive. For example

> And in the case where a method returns a handle that will be used
> later, I'm thinking return the handle on success, and on failure
> return nil and make the error available via krb.errstr?
>

I'm guessing because I haven't seen your code but I'd say it's much
more Ruby-esque to return a boolean value rather than a zero (which
Ruby evaluates true). Hiding the error string behind an accessor makes
sense if it will be accessed infrequently. You do have to remember to
clear it on *every* call into your extension.

Why make your user touch the handle at all? Can you hide it inside
your Krb5 objects with instance_eval, and just supply it yourself when
you need to pass it to the kerb library?

snacktime

9/18/2006 8:48:00 PM

0

> Why make your user touch the handle at all? Can you hide it inside
> your Krb5 objects with instance_eval, and just supply it yourself when
> you need to pass it to the kerb library?
>
>
I'm not picturing this for some reason, can you elaborate?

Chris