On Mon, Jan 19, 2004 at 05:43:19PM +0000 Nick Ing-Simmons wrote:
> 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.

Unfortunately, the O_NONBLOCK is essential in my case as this module
provides access to all the ioctls of a CDROM-drive as permitted by the
kernel. Otherwise I couldn't open a drive with no CD in it.

What you say makes sense however. I even think that PerlIO_intmode2str()
completely ignores O_NONBLOCK. It handles the basic stuff (O_RDONLY,
O_RDWR, O_WRONLY) and some other things irrelevant for me (O_BINARY in
particular).

> >            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

I was just trying to reproduce the result of using the typemap. What was
returned was not undef according to Devel::Peek. The funny thing now is:
The above, which didn't work this morning, now works! I am seriously
confused. I don't quite trust this. Now I just have to get rid of the
blessing which is both unnecessary and causes DESTROY to fail.

> >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?

It'd be nice having a bridge between Perl filehandles (that is,
references to globs) and C handles (both file-descriptors and FILE*).
Often C libraries work on filehandles but exposing those to pure Perl as
glob-references is tricky. In particular, I wish we had

    PerlIO *PerlIO_importfd(int fd, int mode);

Going the other way (XSUB gets a glob-ref and needs FILE*/fd) isn't
always smooth either. For that purpose, I made two macros:

    #ifdef _WIN32
    # define PerlIO_exportFILE(f,fl) ((FILE*)(f))
    #endif

    #define sv_to_file(sv) (PerlIO_exportFILE(IoIFP(sv_2io(sv)), NULL))

Especially the _WIN32 branch is fishy. But it was on this list that
someone said that on windows a PerlIO* would just be an alias for FILE*.

Other than that, I think that perlio itself is ok as long as you create
your PerlIO*'s inside XS and don't try to expose them to the outer
world.

Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

Reply via email to