Extern "C" of prep_stdio

Im trying to handover a pipe from C++ to ruby.

Im doing this in order to make the functions available to C++.

extern “C” {
#include <rubyio.h> // rb_fdopen

static VALUE prep_stdio(FILE *, int, VALUE);

} // extern “C”

So far so good… this compiles without problems.

I want to do the same as in “io.c”
w = prep_stdio(rb_fdopen(pipes[1], “w”), FMODE_WRITABLE|FMODE_SYNC, rb_cIO);

But if I try compiling this, then G++ complains about the externed
prep_stdio…

gmake
g++ main.cpp -lc_r -I/home/neoneye/install/language/ruby-1.8.0 /home/neoneye/install/language/ruby-1.8.0/libruby-static.a -lcrypt -Wall #-fpermissive
main.cpp: In function int main(int, char**)': main.cpp:116: warning: unused variable FILEfd’
/usr/include/g++/streambuf: At top level:
main.cpp:15: `VALUE prep_stdio(FILE
, int, long unsigned int)’ used but never
defined
gmake: *** [all] Fejl 1

Is there anyone around which knows how to extern “C” rubys internals ?

···


Simon Strandgaard

Im doing this in order to make the functions available to C++.

a static method in C is like a private method in C++, you can’t access
it.

w = prep_stdio(rb_fdopen(pipes[1], "w"), FMODE_WRITABLE|FMODE_SYNC, rb_cIO);  

Why you dont use IO::pipe ?

Guy Decoux

Im doing this in order to make the functions available to C++.

a static method in C is like a private method in C++, you can’t access
it.

What a shame… there is so many nice functions within ruby which I want
to use. Should I submit a RCR: removal of static ?

The static C functions seems to be visible (nm libruby-static.a)…

w = prep_stdio(rb_fdopen(pipes[1], "w"), FMODE_WRITABLE|FMODE_SYNC, rb_cIO);  

Why you dont use IO::pipe ?

Long story… The first thing I tried was IO::pipe. I got much help,
but could not figure out how to do it.
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/70770

So I decided to give it a shot in C++.

···

On Fri, 09 May 2003 23:27:42 +0900, ts wrote:


Simon Strandgaard

Long story.. The first thing I tried was IO::pipe.

IO::new don't do what you want ?

pigeon% ri IO::new
---------------------------------------------------------------- IO::new
     IO.new( anInteger, aModeString ) -> aFile

···

------------------------------------------------------------------------
     Returns a new File object (a stream) for the given integer file
     descriptor and mode string. See also IO#fileno.
        a = IO.new(2,"w") # '2' is standard error
        $stderr.puts "Hello"
        a.puts "World"
     produces:
        Hello
        World

pigeon%

Guy Decoux

IO::new don’t do what you want ?

Im trying out IO::new right now… But no data is going through the pipe?

ruby_init();
ruby_init_loadpath();
ruby_options(argc, argv);

/* FILE fd = rb_fdopen(pipes[1], “w”);
int mode = FMODE_WRITABLE|FMODE_SYNC;
VALUE klass = rb_cIO;
VALUE w = prep_stdio(fd, mode, klass);
/

VALUE params[2];
params[0] = INT2FIX(pipes[1]);
params[1] = rb_str_new2("w");
VALUE klass = rb_path2class("IO"); 
VALUE w = rb_class_new_instance(2, params, klass);

rb_defout = rb_stdout = rb_stderr = w;   // Is this correct ???

ruby_run();

cat run.sh
…/a.out -e ‘puts “hello”; system(“ls”); sleep 5’

How do I redirect stdout/stderr ?

···

On Sat, 10 May 2003 00:07:34 +0900, ts wrote:


Simon Strandgaard

[[ spamassassin definetely think that you are a spammer :-)) ]]

VALUE w = rb_class_new_instance(2, params, klass);

rb_defout = rb_stdout = rb_stderr = w; // Is this correct ???

no, you must call IO#reopen

Guy Decoux

in several of the recent threads on io redirection i have been admonished for
suggesting the use of reopen and told to use assignment

$defout = $stdout = $stderr = redirected_io_object

instead.

now, i personally have had much better luck using #reopen, but i’m curious as
to your rational. since using reopen can cause a broken pipe to
feeder/feeding processes, and it makes it harder to restore io objects to
original condition (though not by much).

am i the only one out here who thinks an RCR for a suite of common redirect
methods seems reasonable? there are few topics which have caused so much
confusion/discussion on this list - well, maybe ‘class << self’… :wink:

-a

···

On Sat, 10 May 2003, ts wrote:

[[ spamassassin definetely think that you are a spammer :-)) ]]

VALUE w = rb_class_new_instance(2, params, klass);
rb_defout = rb_stdout = rb_stderr = w;   // Is this correct ???

no, you must call IO#reopen

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

now, i personally have had much better luck using #reopen, but i'm curious as
to your rational.

No rational,

pigeon% cat a.c
#include <ruby.h>

int main()
{
    int pipes[2], count;
    VALUE params[2], w;
    char str[512];
    FILE *fd;

    if ((fd = fopen("aaa", "w")) == NULL) {
        exit(1);
    }
    if (pipe(pipes) == -1) {
        exit(1);
    }
    ruby_init();
    ruby_init_loadpath();

    params[0] = INT2FIX(pipes[1]);
    params[1] = rb_str_new2("w");
    w = rb_class_new_instance(2, params, rb_path2class("IO"));

    rb_funcall(rb_defout, rb_intern("reopen"), 1, w);
    rb_funcall(rb_stderr, rb_intern("reopen"), 1, w);
    rb_eval_string("$stderr.puts 'aa'; puts 'hello'; system('ls a.c xx')");
    count = read(pipes[0], str, 512);
    if (count >= 0) {
        fprintf(fd, "<<\n%*.*s>>\n", count, count, str);
    }
    fclose(fd);
    return 0;
}
pigeon%

pigeon% a.out
pigeon%

pigeon% cat aaa
<<
aa
hello
ls: xx: No such file or directory
a.c

pigeon%

Guy Decoux

now, i personally have had much better luck using #reopen, but i’m curious as
to your rational.

No rational,

i doubt that :wink:

pigeon% cat a.c
#include <ruby.h>

int main()
{
int pipes[2], count;
VALUE params[2], w;
char str[512];
FILE *fd;

if ((fd = fopen("aaa", "w")) == NULL) {
    exit(1);
}
if (pipe(pipes) == -1) {
    exit(1);
}
ruby_init();
ruby_init_loadpath();

params[0] = INT2FIX(pipes[1]);
params[1] = rb_str_new2("w");
w = rb_class_new_instance(2, params, rb_path2class("IO"));

rb_funcall(rb_defout, rb_intern("reopen"), 1, w);
rb_funcall(rb_stderr, rb_intern("reopen"), 1, w);
rb_eval_string("$stderr.puts 'aa'; puts 'hello'; system('ls a.c xx')");
count = read(pipes[0], str, 512);
if (count >= 0) {
    fprintf(fd, "<<\n%*.*s>>\n", count, count, str);
}
fclose(fd);
return 0;

}
pigeon%

pigeon% a.out
pigeon%

pigeon% cat aaa
<<
aa
hello
ls: xx: No such file or directory
a.c

pigeon%

guy - you rock.

you do realize the pain we all have gone through trying to accomplish that!?
:wink:

one thing which is curious to me is that simply redirecting fd 1 and 2 from
within C using dup/dup2 seems to redirect some of ruby’s output, but not all
of it. i hadn’t considered (didn’t know about) rb_defout, etc., but am a
little suprised that direct manipulation of fd 0,1,2 before calling
ruby_init() did not accomplish the task of ‘complete’ ruby redirection…

i guess i really don’t understand the relationship between low level io (fd
0,1,2), C stdio (FILE *), and ruby’s interface/use of these but it certainly
seems like it should be possible to setup ALL redirection in pure C, without
using and of the libruby methods, but i am probably wrong.

in anycase, i’ll save this bit of code.

-a

···

On Sat, 10 May 2003, ts wrote:

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

[snip the best example I’ve ever gotten!]

Guy Decoux

You rock! I have been working hard to accomplish this.
I am very thankful for the rescue… Thanks

···

On Sat, 10 May 2003 03:04:12 +0900, ts wrote:


Simon Strandgaard