On Mon, Jan 19, 2004 at 10:40:35PM +0000 Nick Ing-Simmons wrote:
> Tassilo Parseval <[EMAIL PROTECTED]> writes:
> >> >> > 
> >> >> >     PerlIO *io;
> >> >> >     char mode[8];
> >> >> >     PerlIO_intmode2str(O_RDONLY|O_NONBLOCK, mode, NULL);
> >> >> >     io = PerlIO_fdopen(self->fd, mode);
>    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.
> 
> Fine - and you have opened it and got the fd.

Eventually, yes, I have. :-))

> PerlIO_fdopen then takes that already open fd and associates
> a PerlIO * with it. PerlIO_intmde2str takes O_RDONLY and turns it 
> into stdio-like "r". Stdio and PerlIO have no way to represent O_NONBLOCK
> so (having now looked) it just ignores it.

My concern was with PerIO_fdopen(). I didn't know whether perl would
reuse the fd (and simply sort of wrap it in a PerlIO) or duplicate it.
In case of duping, ignoring O_NONBLOCK would be bad.

The problem with fd-versus-FILE IO is eventually what bothers me. I now
have a module that works on top of file-descriptors. But it exports one
via the PerlIO mechanism and it seems to work. But I first have to check
that it really works before I start throwing my hat into the air.

> >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. 
> 
> Any chance some other process had the CDROM in use "this morning"?

Hmmh, no, I don't think so. Also, the linux kernel in theory allows
concurrent access to a CDROM drive.  My constructor (which opens the
drive) returns undef when opening fails. And it didn't in this case.
Njah, I guess this will forever remain a mystery.

> >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);
> 
> You do have: 
>  PerlIO *PerlIO_fdopen(int fd, const char *);
> 
> What seems to be troubling us is getting a glob ref from one of those
> so what we want is 
> 
> SV *PerlIO_perlhandle(PerlIO *f);

As I've figured out in this thread, the PerlIO* typemap contains the
code that does this conversion. So now I just have to memorize where I
can look it up. 

> >Going the other way (XSUB gets a glob-ref and needs FILE*/fd) isn't
> >always smooth either. 
> 
> 
> First step is to get the IO *  Perl_sv2io() does that.
> Next you get your PerlIO * - you have a choice of two the one for output
> and the one for input (often same but not for sockets or (some) ttys).
> 
> Getting a FILE * isn't smooth, but we have an API for that.
> Getting a fd is just PerlIO_fileno(PerlIO *f)

That reads amazingly simple as you describe it. Good that I can from now
on look it up for future reference.

> >For that purpose, I made two macros:
> >
> >    #ifdef _WIN32
> >    # define PerlIO_exportFILE(f,fl) ((FILE*)(f))
> >    #endif
> 
> >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*.
> 
> It was on perl5.6 - not on perl5.8.

Bah! That means I have to change one of my modules. Quite
unsurprisingly, the branch of the code that converted a glob-ref to a
FILE* was not covered by the tests. :-(

> >    #define sv_to_file(sv) (PerlIO_exportFILE(IoIFP(sv_2io(sv)), NULL))
> >
> That is "okay" anywhere with perl5.8+ - but please read the PODs.
> In perl5.8+ there isn't necessarily a FILE * in normal perl IO.
> So the above may have to 
> 
>     FILE *stdio = fdopen(PerlIO_fileno(pio),mode))

Sigh, so not even my non-Win32 path is necessarily right.

Anyway, Nick, thanks for your patient attempts to explain this book
with 7^7 seals to me. I think I'm now able to find a way through this
muddle somehow.

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