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