[C ext to Ruby] returning a pipe ???

U

unbewusst

i'm writting a RubyCocoa application for synchronizing folders of a
computer to folders of an usb key.

to let the user not bored, because it could takes time, i have a log
window where i print the messages coming from rsync.

on another side, i need the call to rsync to have root privileges,
then i'm writing a tinu ruby module in C to get the root privileges
for rsync.

the way it is done, for the time being :

C side:
+-----+

if ( myStatus != errAuthorizationSuccess ) break;
{
FILE *myCommunicationsPipe = NULL;
char myReadBuffer[ LINE_MAX ];

myFlags = kAuthorizationFlagDefaults;

myStatus = AuthorizationExecuteWithPrivileges( myAuthorizationRef,
myToolPath, myFlags,
myArguments,
&myCommunicationsPipe );
if ( bufferOut != NULL )
{
if ( myStatus == errAuthorizationSuccess )
{
int i = 0;
int len;
while ( fgets( myReadBuffer, LINE_MAX, myCommunicationsPipe ) )
{
bufferOut[ i ] = strdup( myReadBuffer );
len = strlen( bufferOut[ i ] );
bufferOut[ i ] += len - 1;
*bufferOut[ i ] = 0; // ~= chomp
bufferOut[ i ] -= len - 1;
i++;
}
bufferOut[ i ] = NULL;
}
}
}

C ext to Ruby side:
+-----------------+

VALUE ary = rb_ary_new2( LINES_MAX );
i = 0;
while( bufferOut[ i ] != NULL)
{
rb_ary_push( ary, (VALUE) rb_str_new2( bufferOut[ i ] ) );
i++;
}

return ary;


obviously, it works but i'm not satisfied of the returned result
because the user gets an array of it's whole at a time, where i would
prefer continously outputting the values (string in this case)


then i wonder if there is a way somehow to return the
"myCommunicationsPipe" above directly (more directly) from C to ruby.

something like IO.popen...

BUT, i've tried IO.popen in my RubyCocoa app it doesn't work as
expected, i get the whole result at a time intead of having the
results in a line by nline basis...


some light about that ?
 
P

Paul Brannan

then i wonder if there is a way somehow to return the
"myCommunicationsPipe" above directly (more directly) from C to ruby.

something like IO.popen...

I see at least two options:

- Use the macros in rubyio.h to wrap the FILE* that you already have.
This is "cheating" the ruby API a bit, since you'd be accessing
structures that I don't think Matz intended for us to access
directly.

- Use IO#fdopen to re-open the pipe once it is opened.

Paul
 
U

unbewusst

I see at least two options:

- Use the macros in rubyio.h to wrap the FILE* that you already have.
This is "cheating" the ruby API a bit, since you'd be accessing
structures that I don't think Matz intended for us to access
directly.

- Use IO#fdopen to re-open the pipe once it is opened.

Paul



Luc Heinriwh gave me yesterday a third solution perfectly working,
from C ext to Ruby side i return : INT2FIX( fileno(myPipe))

and on ruby side i can use it as a standard IO pipe...

that's all very simple and efficient ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top