summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Ing-Simmons <nik@tiuk.ti.com>2002-05-08 17:56:43 +0000
committerNick Ing-Simmons <nik@tiuk.ti.com>2002-05-08 17:56:43 +0000
commit8dcb57838133afcca1063f491fdd55188f1d84ed (patch)
tree4c0e1fd2b11ca232b972b6b1e7957708e011016c
parentef9da7543400a2b6afaa028ae2ebbbc64cd7ceb0 (diff)
downloadperl-8dcb57838133afcca1063f491fdd55188f1d84ed.tar.gz
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-id: //depot/perlio@16495
-rw-r--r--perlio.c11
-rw-r--r--pod/perlapio.pod10
-rw-r--r--pod/perlxstut.pod91
3 files changed, 100 insertions, 12 deletions
diff --git a/perlio.c b/perlio.c
index bcfa2568e2..e6d0908fae 100644
--- a/perlio.c
+++ b/perlio.c
@@ -2433,10 +2433,14 @@ PerlIO_importFILE(FILE *stdio, int fl)
dTHX;
PerlIO *f = NULL;
if (stdio) {
+ int mode = fcntl(fileno(stdio), F_GETFL);
PerlIOStdio *s =
PerlIOSelf(PerlIO_push
(aTHX_(f = PerlIO_allocate(aTHX)), &PerlIO_stdio,
- "r+", Nullsv), PerlIOStdio);
+ (mode&O_ACCMODE) == O_RDONLY ? "r"
+ : (mode&O_ACCMODE) == O_WRONLY ? "w"
+ : "r+",
+ Nullsv), PerlIOStdio);
s->stdio = stdio;
}
return f;
@@ -2828,11 +2832,12 @@ PerlIO_exportFILE(PerlIO *f, int fl)
{
dTHX;
FILE *stdio;
+ char buf[8];
PerlIO_flush(f);
- stdio = fdopen(PerlIO_fileno(f), "r+");
+ stdio = fdopen(PerlIO_fileno(f), PerlIO_modestr(f,buf));
if (stdio) {
PerlIOStdio *s =
- PerlIOSelf(PerlIO_push(aTHX_ f, &PerlIO_stdio, "r+", Nullsv),
+ PerlIOSelf(PerlIO_push(aTHX_ f, &PerlIO_stdio, buf, Nullsv),
PerlIOStdio);
s->stdio = stdio;
}
diff --git a/pod/perlapio.pod b/pod/perlapio.pod
index 5103504565..22128db978 100644
--- a/pod/perlapio.pod
+++ b/pod/perlapio.pod
@@ -314,16 +314,18 @@ it a char *mode as in fopen/freopen.
=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 fact that such a FILE * has been 'exported' is recorded, and may
affect future PerlIO operations on the original PerlIO *.
+Calling this function repeatedly will create a FILE * on each call.
+
=item B<PerlIO_findFILE(f)>
-Returns previously 'exported' FILE * (if any). Placeholder until
-interface is fully defined.
+Returns a native FILE * used by a stdio layer. If there is none, it
+will create one with PerlIO_exportFILE.
=item B<PerlIO_releaseFILE(p,f)>
@@ -331,6 +333,8 @@ 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.
+(Currently a noop.)
+
=back
=head2 "Fast gets" Functions
diff --git a/pod/perlxstut.pod b/pod/perlxstut.pod
index 4ce0597341..a697ecb7d1 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,7 +1204,84 @@ 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
+
+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.
+
+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 *>:
+
+ PerlIO * T_INOUT
+
+And this is the XS code:
+
+ int
+ perlioputs(s, stream)
+ char * s
+ PerlIO * 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
+
+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()>.
+
+
Getting fd's from filehandles
@@ -1241,7 +1318,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 +1335,8 @@ 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.
+
=head2 Last Changed
-1999/11/30
+2002/05/08