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.
+The standard typemap offers three variants of PerlIO *:
+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 argument or result
+type in your XS file.
+
+The standard typemap does not contain PerlIO * before perl 5.7,
+but it has the three stream variants. Using a PerlIO * directly
+is not backwards compatible unless you provide your own typemap.
+
+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. Like in our example...
+
+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.
-For PerlIO *'s, we need a typemap because the standard typemap does
-not provide C<PerlIO *>:
+In the C part of the XS file (above the first MODULE line) you
+have
+
+ #define OutputStream PerlIO *
+ or
+ typedef PerlIO * OutputStream;
- PerlIO * T_INOUT
And this is the XS code:
int
perlioputs(s, stream)
char * s
- PerlIO * stream
+ OutputStream stream
CODE:
RETVAL = PerlIO_puts(stream, s);
OUTPUT:
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 *>:
+on a PerlIO *. This means we have to ask the perlio system for a stdio
+C<FILE *>:
int
perliofputs(s, stream)
char * s
- PerlIO * stream
+ OutputStream stream
PREINIT:
FILE *fp = PerlIO_findFILE(stream);
CODE:
This applies to the perlio system only. For versions before 5.7,
C<PerlIO_exportFILE()> is equivalent to C<PerlIO_findFILE()>.
-
-
-Getting fd's from filehandles
-
=head2 Troubleshooting these Examples
As mentioned at the top of this document, if you are having problems with
Reviewed and assisted by Dean Roehrich, Ilya Zakharevich, Andreas Koenig,
and Tim Bunce.
-PerlIO material contributed by Lupe Christoph.
+PerlIO material contributed by Lupe Christoph, with some clarification
+by Nick Ing-Simmons.
=head2 Last Changed