Tassilo Parseval <[EMAIL PROTECTED]> writes:
>On Mon, Jan 19, 2004 at 02:46:46AM -0800 Gisle Aas wrote:
>> Tassilo von Parseval <[EMAIL PROTECTED]> writes:
>> 
>> > I was experimenting with something like
>> > 
>> >     PerlIO *io;
>> >     char mode[8];
>> >     PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL);
>> >     io = PerlIO_fdopen(self->fd, mode);
>> > 
>> > but I can't even figure out whether this works because I don't know how
>> > to turn a PerlIO* thingy into an SV. Actually, I don't know what to do
>> > with this PerlIO stuff at all. According to perlapio.pod, this is the
>> > thing to work with when doing I/O from XS. But there is not a single
>> > indication anywhere how to turn an SV into a PerlIO and vice versa.
>> 
>> The standard perl typemap have this OUTPUT entry for PerlIO:
>> 
>> T_INOUT
>>         {
>>             GV *gv = newGVgen("$Package");
>>             if ( do_open(gv, "+<&", 3, FALSE, 0, 0, $var) )
>>                 sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
>>             else
>>                 $arg = &PL_sv_undef;
>>         }
>
>Thank you, this helps. But, hmmh, unfortunately it doesn't yet solve all
>my problems. My first attempt:
>
>    PerlIO*
>    fh (self)
>            CDROM *self;
>        PREINIT:
>            char mode[8];
>            PerlIO *io;
>        CODE:
>        {
>            PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL);

The O_NONBLOCK _may_ be confusing it.
And as thing is already open doesn't contribute much.

>            io = PerlIO_fdopen(self->fd, mode);
>            RETVAL = io;
>        }
>        OUTPUT:
>            RETVAL
>
>This returns me something that is blessed into my class, but it is
>apparently not a filehandle. 

Looking at C code out of xsubpp would help us here.
These typemaps are a little fragile - for example 
if you are using perl5.6 things are rather different.

If the PerlIO_fdopen() has failed it isn't clear typemap 
will always return undef

>When trying to do
>
>    my $fh = $cd->fh;
>    ioctl($fh, CDROMEJECT, 0);
>
>perl will complain about $fh not being a GLOB-reference.

Which would be the case for an undef - i.e. a failed 
fdopen().

>
>I now do it this way and this seems to work:
>
>    void
>    fh (self)
>            CDROM *self;
>        PREINIT:
>            char mode[8];
>            GV *gv;
>            STLLEN modlen;
>        CODE:
>        {
>            modlen = sprintf(mode, "<&%i", self->fd);
>            gv = newGVgen("Device::CDROM");
>            do_openn(gv, mode, modlen, FALSE, O_RDONLY|O_NONBLOCK, 0, Nullfp, 
> (SV**)NULL, 0);
>            sv_setsv(ST(0), sv_2mortal(newRV((SV*)gv)));
>            XSRETURN(1);
>        }
>    
>I am not extremely happy with this since it looks like cheating. Also I
>am not sure whether it is legitimate to use do_openn() since it is not
>in the public API (although this typemap you mentioned does something
>similar).

The typemap uses an icky legacy interface which isn't really 
in the public API either. 

It would be good to _design_ an XS/PerlIO API - what do you 
want to be able to do?

>
>Anyway, even though this appears to work, I don't understand PerlIO at
>all.
>
>Tassilo

Reply via email to