diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2002-05-08 22:11:21 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2002-05-08 22:11:21 +0000 |
commit | ae45a499be4650b1ac9f50f7721abca27e07dd5f (patch) | |
tree | 1ae42365ed1fde7bf8ae7dc438681d3f2caf4587 /pod | |
parent | 79d429636c0ad8e34ae1ff92342e0d8313415f2b (diff) | |
parent | 22569500a4329ba00826e9a263a1e15c2b24247f (diff) | |
download | perl-ae45a499be4650b1ac9f50f7721abca27e07dd5f.tar.gz |
Integrate perlio:
[ 16496]
Portability and doc tweaks to PerlIO/XS stuff.
We are still "papering over the cracks" a bit,
but now it is good stiff card held on with epoxy.
[ 16495]
PerlIO/XS interface routine and doc updates from
lupe@lupe-christoph.de (Lupe Christoph) in mail
Subject: [For Review] Patch for perlio.c and pods
Message-Id: <20020505084315.GA23900@lupe-christoph.de>
Date: Sun, 5 May 2002 10:43:15 +0200
(Minor tweaks to follow.)
p4raw-link: @16496 on //depot/perlio: 22569500a4329ba00826e9a263a1e15c2b24247f
p4raw-link: @16495 on //depot/perlio: 8dcb57838133afcca1063f491fdd55188f1d84ed
p4raw-id: //depot/perl@16497
Diffstat (limited to 'pod')
-rw-r--r-- | pod/perlapio.pod | 37 | ||||
-rw-r--r-- | pod/perlxstut.pod | 114 |
2 files changed, 134 insertions, 17 deletions
diff --git a/pod/perlapio.pod b/pod/perlapio.pod index 5103504565..a0e4ffaf10 100644 --- a/pod/perlapio.pod +++ b/pod/perlapio.pod @@ -305,25 +305,34 @@ changes in this area. =item B<PerlIO_importFILE(f,flags)> -Used to get a PerlIO * from a FILE *. May need additional arguments, -interface under review. +Used to get a PerlIO * from a FILE *. The flags argument was meant to be used for read vs write vs read/write information. In hindsight it would have been better to make -it a char *mode as in fopen/freopen. +it a char *mode as in fopen/freopen. Flags arecurrently ignored, and +code attempts to empirically determine the mode in which I<f> is open. + +Once called the FILE * should I<ONLY> be closed by calling +C<PerlIO_close()> on the returned PerlIO *. + =item B<PerlIO_exportFILE(f,flags)> -Given a PerlIO * return a 'native' FILE * suitable for passing to code +Given a PerlIO * create a 'native' FILE * suitable for passing to code expecting to be compiled and linked with ANSI C I<stdio.h>. +The flags argument was meant to be used for read vs write vs +read/write information. In hindsight it would have been better to make +it a char *mode as in fopen/freopen. Flags are ignored and the +FILE * is opened in same mode as the PerlIO *. -The fact that such a FILE * has been 'exported' is recorded, and may -affect future PerlIO operations on the original PerlIO *. - -=item B<PerlIO_findFILE(f)> +The fact that such a FILE * has been 'exported' is recorded, (normally by +pushing a new :stdio "layer" onto the PerlIO *), which may affect future +PerlIO operations on the original PerlIO *. +You should not call C<fclose()> on the file unless you call +C<PerlIO_releaseFILE()> to disassociate it from the the PerlIO *. -Returns previously 'exported' FILE * (if any). Placeholder until -interface is fully defined. +Calling this function repeatedly will create a FILE * on each call +(and will push an :stdio layer each time as well). =item B<PerlIO_releaseFILE(p,f)> @@ -331,6 +340,14 @@ Calling PerlIO_releaseFILE informs PerlIO that all use of FILE * is complete. It is removed from list of 'exported' FILE *s, and associated PerlIO * should revert to original behaviour. +=item B<PerlIO_findFILE(f)> + +Returns a native FILE * used by a stdio layer. If there is none, it +will create one with PerlIO_exportFILE. In either case the FILE * +should be considered at belonging to PerlIO subsystem and should +only be closed by calling C<PerlIO_close()>. + + =back =head2 "Fast gets" Functions diff --git a/pod/perlxstut.pod b/pod/perlxstut.pod index 4ce0597341..c7723af887 100644 --- a/pod/perlxstut.pod +++ b/pod/perlxstut.pod @@ -798,7 +798,7 @@ passing three pieces of information for each argument listed. The first piece is the order of that argument relative to the others (first, second, etc). The second is the type of argument, and consists of the type declaration of the argument (e.g., int, char*, etc). The third piece is -the calling convention for the argument in the call to the library function. +the calling convention for the argument in the call to the library function. While Perl passes arguments to functions by reference, C passes arguments by value; to implement a C function which modifies data @@ -928,7 +928,7 @@ See L<perlpod> for more information about the pod format. =head2 Installing your Extension Once your extension is complete and passes all its tests, installing it -is quite simple: you simply run "make install". You will either need +is quite simple: you simply run "make install". You will either need to have write permission into the directories where Perl is installed, or ask your system administrator to run the make for you. @@ -1117,7 +1117,7 @@ Mytest.xs: OUTPUT: RETVAL -And add the following code to test.pl, while incrementing the "1..11" +And add the following code to test.pl, while incrementing the "1..11" string in the BEGIN block to "1..13": $results = Mytest::multi_statfs([ '/', '/blech' ]); @@ -1204,9 +1204,106 @@ XPUSH args AND set RETVAL AND assign return value to array Setting $! -=head2 EXAMPLE 9 (Coming Soon) +=head2 EXAMPLE 9 Passing open files to XSes -Getting fd's from filehandles +You would think passing files to an XS is difficult, with all the +typeglobs and stuff. Well, it isn't. + +Suppose that for some strange reason we need a wrapper around the +standard C library function C<fputs()>. This is all we need: + + #define PERLIO_NOT_STDIO 0 + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + #include <stdio.h> + + int + fputs(s, stream) + char * s + FILE * stream + +The real work is done in the standard typemap. + +B<But> you loose all the fine stuff done by the perlio layers. This +calls the stdio function C<fputs()>, which knows nothing about them. + +For PerlIO *'s, there considered to be three kinds in the +standard typemap C<InputStream> (T_IN), C<InOutStream> (T_INOUT) and +C<OutputStream> (T_OUT), a bare C<PerlIO *> is considered a T_INOUT. +If it matters in your code (see below for why it might) #define or typedef +one of the specific names and use that as the type in your XS file. + +For streams coming I<from> perl the main difference is that +C<OutputStream> will get the output PerlIO * - which may make +a difference on a socket. + +For streams being handed I<to> perl a new file handle is created +(i.e. a reference to a new glob) and associated with the PerlIO * +provided. If the read/write state of the PerlIO * is not correct then you +may get errors or warnings from when the file handle is used. +So if you opened the PerlIO * as "w" it should really be an +C<OutputStream> if open as "r" it should be an C<InputStream>. + +Now, suppose you want to use perlio layers in your XS. We'll use the +perlio C<PerlIO_puts()> function as an example. + +In the C part of the XS file (above the first MODULE line) you +have + + #define OutputStream PerlIO * + or + typedef PerlIO * OutputStream; + + +And this is the XS code: + + int + perlioputs(s, stream) + char * s + OutputStream stream + CODE: + RETVAL = PerlIO_puts(stream, s); + OUTPUT: + RETVAL + +We have to use a C<CODE> section because C<PerlIO_puts()> has the arguments +reversed compared to C<fputs()>, and we want to keep the arguments the same. + +Wanting to explore this thoroughly, we want to use the stdio C<fputs()> +on an explicit PerlIO *. This means we have to ask the perlio system +for a stdio C<FILE *>: + + int + perliofputs(s, stream) + char * s + PerlIO * stream + PREINIT: + FILE *fp = PerlIO_findFILE(stream); + CODE: + if (fp != (FILE*) 0) { + RETVAL = fputs(s, fp); + } else { + RETVAL = -1; + } + OUTPUT: + RETVAL + +(We also using bare PerlIO * as the type - so we get the I<input> +PerlIO * of a socket - if this is undesirable use typedef or #define +as above.) + +Note: C<PerlIO_findFILE()> will search the layers for a stdio +layer. If it can't find one, it will call C<PerlIO_exportFILE()> to +generate a new stdio C<FILE>. Please only call C<PerlIO_exportFILE()> if +you want a I<new> C<FILE>. It will generate one on each call and push a +new stdio layer. So don't call it repeatedly on the same +file. C<PerlIO()>_findFILE will retrieve the stdio layer once it has been +generated by C<PerlIO_exportFILE()>. + +This applies to the perlio system only. For versions before 5.7, +C<PerlIO_exportFILE()> is equivalent to C<PerlIO_findFILE()>. =head2 Troubleshooting these Examples @@ -1241,7 +1338,7 @@ to use the following line: =item * -This document assumes that the executable named "perl" is Perl version 5. +This document assumes that the executable named "perl" is Perl version 5. Some systems may have installed Perl version 5 as "perl5". =back @@ -1258,6 +1355,9 @@ Jeff Okamoto <F<okamoto@corp.hp.com>> Reviewed and assisted by Dean Roehrich, Ilya Zakharevich, Andreas Koenig, and Tim Bunce. +PerlIO material contributed by Lupe Christoph, with some clarification +by Nick Ing-Simmons. + =head2 Last Changed -1999/11/30 +2002/05/08 |