On Wed, Jan 21, 2004 at 09:20:40AM +0000 Nick Ing-Simmons wrote:

> Tassilo Parseval <[EMAIL PROTECTED]> writes:
> >> 
> >> AFAIK a dup()ed fd inherits the non-blocking-ness along with 
> >> all the other kernel level attributes like file position.
> >
> >As I've read in the PODs now, PerlIO_fdopen() will not dup the handle
> >(since fdopen wont do it) and so I can't use it. 
> 
> As you have descended to this OS level layer anyway what is wrong 
> with calling PerlLIO_dup() yourself?

Ah, there is a dup() and dup2() macro in XSUB.h. I missed it because it
isn't mentioned in any of the PODs.

> I am assuming that dup is essential to avoid double-close issues?
> What else is going to close it? Can that close be supressed leaving 
> perl to do the close()?

It could. I would just need to bless the returned GLOB-ref into a class
of my own and define a close() and DESTROY() method for it (both will do
nothing).

There is even a way to avoid exporting a Perl handle at all, I just
realized. I just do it because my module doesn't handle all ioctls (I
have no DVD-drive so I don't implement those as I couldn't test them).

But instead of letting the user do

    ioctl($cdrom->fh, DVD_READ_STRUCT, $packed_string);

I could change the interface to

    $cdrom->ioctl(DVD_READ_STRUCT, $packed_string);

and inside ioctl():

    ioctl(self, op, data) 
            CROM *self;
            int op;
            SV* data;
        CODE:
            ...
            ioctl(self->fd, op, SvPVX(data)); /* after the appropriate checks of 
'data' */
            ...

Thus I could avoid any perlio issues.

> >perlapio.pod mentions
> >"dup" only once (in PerlIO_reopen) and that doesn't help:
> >
> >   Perl prefers to "dup" the new low-level descriptor to the descrip-
> >   tor used by the existing PerlIO. This may become the behaviour of
> >   this function in the future.
> 
> PerlIO is trying to hide numeric fd level as a POSIX specific 
> OS feature. Win32 IO could be a lot more efficient if we could 
> get perl to loose its numeric fd fixation. On Win32 IO has 
> a "Handle" which is a pointer-sized thing and values are 
> non-consecutive.   
> 
> >
> >I've come to the conclusion that I will use the "<&$fd" trick and use
> >do_openn() because thus I can pass 'Nullfp' as the PerlIO* argument.
> 
> Fine. The only reason I can see for not adding do_openn() to public 
> API is its interface is insanely complex and flexible.

A few macros could be built on top of it, like:

    gvref_from_fd(fd,sv)   { \  
        char mode[8];   \
        STRLEN len = sprintf(mode, "<&%i", (fd)); \
        GV *gv = newGVgen("main");  \
        do_openn(gv, mode, len, FALSE, mode, 0, Nullfp, (SV**)NULL, 0); \
        sv_setsv((sv), sv_2mortal(newRV((SV*)gv)));   \
        }

As I understand the perl source, do_openn() is almost almighty and is
used for everything open-related in Perl.

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