summaryrefslogtreecommitdiffstats
path: root/upstream/fedora-rawhide/man1/perliol.1
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/fedora-rawhide/man1/perliol.1')
-rw-r--r--upstream/fedora-rawhide/man1/perliol.11074
1 files changed, 1074 insertions, 0 deletions
diff --git a/upstream/fedora-rawhide/man1/perliol.1 b/upstream/fedora-rawhide/man1/perliol.1
new file mode 100644
index 00000000..1ef5a0ca
--- /dev/null
+++ b/upstream/fedora-rawhide/man1/perliol.1
@@ -0,0 +1,1074 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PERLIOL 1"
+.TH PERLIOL 1 2024-01-25 "perl v5.38.2" "Perl Programmers Reference Guide"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+perliol \- C API for Perl's implementation of IO in Layers.
+.SH SYNOPSIS
+.IX Header "SYNOPSIS"
+.Vb 2
+\& /* Defining a layer ... */
+\& #include <perliol.h>
+.Ve
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+This document describes the behavior and implementation of the PerlIO
+abstraction described in perlapio when \f(CW\*(C`USE_PERLIO\*(C'\fR is defined.
+.SS "History and Background"
+.IX Subsection "History and Background"
+The PerlIO abstraction was introduced in perl5.003_02 but languished as
+just an abstraction until perl5.7.0. However during that time a number
+of perl extensions switched to using it, so the API is mostly fixed to
+maintain (source) compatibility.
+.PP
+The aim of the implementation is to provide the PerlIO API in a flexible
+and platform neutral manner. It is also a trial of an "Object Oriented
+C, with vtables" approach which may be applied to Raku.
+.SS "Basic Structure"
+.IX Subsection "Basic Structure"
+PerlIO is a stack of layers.
+.PP
+The low levels of the stack work with the low-level operating system
+calls (file descriptors in C) getting bytes in and out, the higher
+layers of the stack buffer, filter, and otherwise manipulate the I/O,
+and return characters (or bytes) to Perl. Terms \fIabove\fR and \fIbelow\fR
+are used to refer to the relative positioning of the stack layers.
+.PP
+A layer contains a "vtable", the table of I/O operations (at C level
+a table of function pointers), and status flags. The functions in the
+vtable implement operations like "open", "read", and "write".
+.PP
+When I/O, for example "read", is requested, the request goes from Perl
+first down the stack using "read" functions of each layer, then at the
+bottom the input is requested from the operating system services, then
+the result is returned up the stack, finally being interpreted as Perl
+data.
+.PP
+The requests do not necessarily go always all the way down to the
+operating system: that's where PerlIO buffering comes into play.
+.PP
+When you do an \fBopen()\fR and specify extra PerlIO layers to be deployed,
+the layers you specify are "pushed" on top of the already existing
+default stack. One way to see it is that "operating system is
+on the left" and "Perl is on the right".
+.PP
+What exact layers are in this default stack depends on a lot of
+things: your operating system, Perl version, Perl compile time
+configuration, and Perl runtime configuration. See PerlIO,
+"PERLIO" in perlrun, and open for more information.
+.PP
+\&\fBbinmode()\fR operates similarly to \fBopen()\fR: by default the specified
+layers are pushed on top of the existing stack.
+.PP
+However, note that even as the specified layers are "pushed on top"
+for \fBopen()\fR and \fBbinmode()\fR, this doesn't mean that the effects are
+limited to the "top": PerlIO layers can be very 'active' and inspect
+and affect layers also deeper in the stack. As an example there
+is a layer called "raw" which repeatedly "pops" layers until
+it reaches the first layer that has declared itself capable of
+handling binary data. The "pushed" layers are processed in left-to-right
+order.
+.PP
+\&\fBsysopen()\fR operates (unsurprisingly) at a lower level in the stack than
+\&\fBopen()\fR. For example in Unix or Unix-like systems \fBsysopen()\fR operates
+directly at the level of file descriptors: in the terms of PerlIO
+layers, it uses only the "unix" layer, which is a rather thin wrapper
+on top of the Unix file descriptors.
+.SS "Layers vs Disciplines"
+.IX Subsection "Layers vs Disciplines"
+Initial discussion of the ability to modify IO streams behaviour used
+the term "discipline" for the entities which were added. This came (I
+believe) from the use of the term in "sfio", which in turn borrowed it
+from "line disciplines" on Unix terminals. However, this document (and
+the C code) uses the term "layer".
+.PP
+This is, I hope, a natural term given the implementation, and should
+avoid connotations that are inherent in earlier uses of "discipline"
+for things which are rather different.
+.SS "Data Structures"
+.IX Subsection "Data Structures"
+The basic data structure is a PerlIOl:
+.PP
+.Vb 3
+\& typedef struct _PerlIO PerlIOl;
+\& typedef struct _PerlIO_funcs PerlIO_funcs;
+\& typedef PerlIOl *PerlIO;
+\&
+\& struct _PerlIO
+\& {
+\& PerlIOl * next; /* Lower layer */
+\& PerlIO_funcs * tab; /* Functions for this layer */
+\& U32 flags; /* Various flags for state */
+\& };
+.Ve
+.PP
+A \f(CW\*(C`PerlIOl *\*(C'\fR is a pointer to the struct, and the \fIapplication\fR
+level \f(CW\*(C`PerlIO *\*(C'\fR is a pointer to a \f(CW\*(C`PerlIOl *\*(C'\fR \- i.e. a pointer
+to a pointer to the struct. This allows the application level \f(CW\*(C`PerlIO *\*(C'\fR
+to remain constant while the actual \f(CW\*(C`PerlIOl *\*(C'\fR underneath
+changes. (Compare perl's \f(CW\*(C`SV *\*(C'\fR which remains constant while its
+\&\f(CW\*(C`sv_any\*(C'\fR field changes as the scalar's type changes.) An IO stream is
+then in general represented as a pointer to this linked-list of
+"layers".
+.PP
+It should be noted that because of the double indirection in a \f(CW\*(C`PerlIO *\*(C'\fR,
+a \f(CW\*(C`&(perlio\->next)\*(C'\fR "is" a \f(CW\*(C`PerlIO *\*(C'\fR, and so to some degree
+at least one layer can use the "standard" API on the next layer down.
+.PP
+A "layer" is composed of two parts:
+.IP 1. 4
+The functions and attributes of the "layer class".
+.IP 2. 4
+The per-instance data for a particular handle.
+.SS "Functions and Attributes"
+.IX Subsection "Functions and Attributes"
+The functions and attributes are accessed via the "tab" (for table)
+member of \f(CW\*(C`PerlIOl\*(C'\fR. The functions (methods of the layer "class") are
+fixed, and are defined by the \f(CW\*(C`PerlIO_funcs\*(C'\fR type. They are broadly the
+same as the public \f(CW\*(C`PerlIO_xxxxx\*(C'\fR functions:
+.PP
+.Vb 10
+\& struct _PerlIO_funcs
+\& {
+\& Size_t fsize;
+\& char * name;
+\& Size_t size;
+\& IV kind;
+\& IV (*Pushed)(pTHX_ PerlIO *f,
+\& const char *mode,
+\& SV *arg,
+\& PerlIO_funcs *tab);
+\& IV (*Popped)(pTHX_ PerlIO *f);
+\& PerlIO * (*Open)(pTHX_ PerlIO_funcs *tab,
+\& PerlIO_list_t *layers, IV n,
+\& const char *mode,
+\& int fd, int imode, int perm,
+\& PerlIO *old,
+\& int narg, SV **args);
+\& IV (*Binmode)(pTHX_ PerlIO *f);
+\& SV * (*Getarg)(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
+\& IV (*Fileno)(pTHX_ PerlIO *f);
+\& PerlIO * (*Dup)(pTHX_ PerlIO *f,
+\& PerlIO *o,
+\& CLONE_PARAMS *param,
+\& int flags)
+\& /* Unix\-like functions \- cf sfio line disciplines */
+\& SSize_t (*Read)(pTHX_ PerlIO *f, void *vbuf, Size_t count);
+\& SSize_t (*Unread)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
+\& SSize_t (*Write)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
+\& IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int whence);
+\& Off_t (*Tell)(pTHX_ PerlIO *f);
+\& IV (*Close)(pTHX_ PerlIO *f);
+\& /* Stdio\-like buffered IO functions */
+\& IV (*Flush)(pTHX_ PerlIO *f);
+\& IV (*Fill)(pTHX_ PerlIO *f);
+\& IV (*Eof)(pTHX_ PerlIO *f);
+\& IV (*Error)(pTHX_ PerlIO *f);
+\& void (*Clearerr)(pTHX_ PerlIO *f);
+\& void (*Setlinebuf)(pTHX_ PerlIO *f);
+\& /* Perl\*(Aqs snooping functions */
+\& STDCHAR * (*Get_base)(pTHX_ PerlIO *f);
+\& Size_t (*Get_bufsiz)(pTHX_ PerlIO *f);
+\& STDCHAR * (*Get_ptr)(pTHX_ PerlIO *f);
+\& SSize_t (*Get_cnt)(pTHX_ PerlIO *f);
+\& void (*Set_ptrcnt)(pTHX_ PerlIO *f,STDCHAR *ptr,SSize_t cnt);
+\& };
+.Ve
+.PP
+The first few members of the struct give a function table size for
+compatibility check "name" for the layer, the size to \f(CW\*(C`malloc\*(C'\fR for the per-instance data,
+and some flags which are attributes of the class as whole (such as whether it is a buffering
+layer), then follow the functions which fall into four basic groups:
+.IP 1. 4
+Opening and setup functions
+.IP 2. 4
+Basic IO operations
+.IP 3. 4
+Stdio class buffering options.
+.IP 4. 4
+Functions to support Perl's traditional "fast" access to the buffer.
+.PP
+A layer does not have to implement all the functions, but the whole
+table has to be present. Unimplemented slots can be NULL (which will
+result in an error when called) or can be filled in with stubs to
+"inherit" behaviour from a "base class". This "inheritance" is fixed
+for all instances of the layer, but as the layer chooses which stubs
+to populate the table, limited "multiple inheritance" is possible.
+.SS "Per-instance Data"
+.IX Subsection "Per-instance Data"
+The per-instance data are held in memory beyond the basic PerlIOl
+struct, by making a PerlIOl the first member of the layer's struct
+thus:
+.PP
+.Vb 10
+\& typedef struct
+\& {
+\& struct _PerlIO base; /* Base "class" info */
+\& STDCHAR * buf; /* Start of buffer */
+\& STDCHAR * end; /* End of valid part of buffer */
+\& STDCHAR * ptr; /* Current position in buffer */
+\& Off_t posn; /* Offset of buf into the file */
+\& Size_t bufsiz; /* Real size of buffer */
+\& IV oneword; /* Emergency buffer */
+\& } PerlIOBuf;
+.Ve
+.PP
+In this way (as for perl's scalars) a pointer to a PerlIOBuf can be
+treated as a pointer to a PerlIOl.
+.SS "Layers in action."
+.IX Subsection "Layers in action."
+.Vb 8
+\& table perlio unix
+\& | |
+\& +\-\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-+
+\& PerlIO \->| |\-\-\->| next |\-\-\->| NULL |
+\& +\-\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-+
+\& | | | buffer | | fd |
+\& +\-\-\-\-\-\-\-\-\-\-\-+ | | +\-\-\-\-\-\-\-\-+
+\& | | +\-\-\-\-\-\-\-\-\-\-+
+.Ve
+.PP
+The above attempts to show how the layer scheme works in a simple case.
+The application's \f(CW\*(C`PerlIO *\*(C'\fR points to an entry in the table(s)
+representing open (allocated) handles. For example the first three slots
+in the table correspond to \f(CW\*(C`stdin\*(C'\fR,\f(CW\*(C`stdout\*(C'\fR and \f(CW\*(C`stderr\*(C'\fR. The table
+in turn points to the current "top" layer for the handle \- in this case
+an instance of the generic buffering layer "perlio". That layer in turn
+points to the next layer down \- in this case the low-level "unix" layer.
+.PP
+The above is roughly equivalent to a "stdio" buffered stream, but with
+much more flexibility:
+.IP \(bu 4
+If Unix level \f(CW\*(C`read\*(C'\fR/\f(CW\*(C`write\*(C'\fR/\f(CW\*(C`lseek\*(C'\fR is not appropriate for (say)
+sockets then the "unix" layer can be replaced (at open time or even
+dynamically) with a "socket" layer.
+.IP \(bu 4
+Different handles can have different buffering schemes. The "top"
+layer could be the "mmap" layer if reading disk files was quicker
+using \f(CW\*(C`mmap\*(C'\fR than \f(CW\*(C`read\*(C'\fR. An "unbuffered" stream can be implemented
+simply by not having a buffer layer.
+.IP \(bu 4
+Extra layers can be inserted to process the data as it flows through.
+This was the driving need for including the scheme in perl 5.7.0+ \- we
+needed a mechanism to allow data to be translated between perl's
+internal encoding (conceptually at least Unicode as UTF\-8), and the
+"native" format used by the system. This is provided by the
+":encoding(xxxx)" layer which typically sits above the buffering layer.
+.IP \(bu 4
+A layer can be added that does "\en" to CRLF translation. This layer
+can be used on any platform, not just those that normally do such
+things.
+.SS "Per-instance flag bits"
+.IX Subsection "Per-instance flag bits"
+The generic flag bits are a hybrid of \f(CW\*(C`O_XXXXX\*(C'\fR style flags deduced
+from the mode string passed to \f(CWPerlIO_open()\fR, and state bits for
+typical buffer layers.
+.IP PERLIO_F_EOF 4
+.IX Item "PERLIO_F_EOF"
+End of file.
+.IP PERLIO_F_CANWRITE 4
+.IX Item "PERLIO_F_CANWRITE"
+Writes are permitted, i.e. opened as "w" or "r+" or "a", etc.
+.IP PERLIO_F_CANREAD 4
+.IX Item "PERLIO_F_CANREAD"
+Reads are permitted i.e. opened "r" or "w+" (or even "a+" \- ick).
+.IP PERLIO_F_ERROR 4
+.IX Item "PERLIO_F_ERROR"
+An error has occurred (for \f(CWPerlIO_error()\fR).
+.IP PERLIO_F_TRUNCATE 4
+.IX Item "PERLIO_F_TRUNCATE"
+Truncate file suggested by open mode.
+.IP PERLIO_F_APPEND 4
+.IX Item "PERLIO_F_APPEND"
+All writes should be appends.
+.IP PERLIO_F_CRLF 4
+.IX Item "PERLIO_F_CRLF"
+Layer is performing Win32\-like "\en" mapped to CR,LF for output and CR,LF
+mapped to "\en" for input. Normally the provided "crlf" layer is the only
+layer that need bother about this. \f(CWPerlIO_binmode()\fR will mess with this
+flag rather than add/remove layers if the \f(CW\*(C`PERLIO_K_CANCRLF\*(C'\fR bit is set
+for the layers class.
+.IP PERLIO_F_UTF8 4
+.IX Item "PERLIO_F_UTF8"
+Data written to this layer should be UTF\-8 encoded; data provided
+by this layer should be considered UTF\-8 encoded. Can be set on any layer
+by ":utf8" dummy layer. Also set on ":encoding" layer.
+.IP PERLIO_F_UNBUF 4
+.IX Item "PERLIO_F_UNBUF"
+Layer is unbuffered \- i.e. write to next layer down should occur for
+each write to this layer.
+.IP PERLIO_F_WRBUF 4
+.IX Item "PERLIO_F_WRBUF"
+The buffer for this layer currently holds data written to it but not sent
+to next layer.
+.IP PERLIO_F_RDBUF 4
+.IX Item "PERLIO_F_RDBUF"
+The buffer for this layer currently holds unconsumed data read from
+layer below.
+.IP PERLIO_F_LINEBUF 4
+.IX Item "PERLIO_F_LINEBUF"
+Layer is line buffered. Write data should be passed to next layer down
+whenever a "\en" is seen. Any data beyond the "\en" should then be
+processed.
+.IP PERLIO_F_TEMP 4
+.IX Item "PERLIO_F_TEMP"
+File has been \f(CWunlink()\fRed, or should be deleted on \f(CWclose()\fR.
+.IP PERLIO_F_OPEN 4
+.IX Item "PERLIO_F_OPEN"
+Handle is open.
+.IP PERLIO_F_FASTGETS 4
+.IX Item "PERLIO_F_FASTGETS"
+This instance of this layer supports the "fast \f(CW\*(C`gets\*(C'\fR" interface.
+Normally set based on \f(CW\*(C`PERLIO_K_FASTGETS\*(C'\fR for the class and by the
+existence of the function(s) in the table. However a class that
+normally provides that interface may need to avoid it on a
+particular instance. The "pending" layer needs to do this when
+it is pushed above a layer which does not support the interface.
+(Perl's \f(CWsv_gets()\fR does not expect the streams fast \f(CW\*(C`gets\*(C'\fR behaviour
+to change during one "get".)
+.SS "Methods in Detail"
+.IX Subsection "Methods in Detail"
+.IP fsize 4
+.IX Item "fsize"
+.Vb 1
+\& Size_t fsize;
+.Ve
+.Sp
+Size of the function table. This is compared against the value PerlIO
+code "knows" as a compatibility check. Future versions \fImay\fR be able
+to tolerate layers compiled against an old version of the headers.
+.IP name 4
+.IX Item "name"
+.Vb 1
+\& char * name;
+.Ve
+.Sp
+The name of the layer whose \fBopen()\fR method Perl should invoke on
+\&\fBopen()\fR. For example if the layer is called APR, you will call:
+.Sp
+.Vb 1
+\& open $fh, ">:APR", ...
+.Ve
+.Sp
+and Perl knows that it has to invoke the \fBPerlIOAPR_open()\fR method
+implemented by the APR layer.
+.IP size 4
+.IX Item "size"
+.Vb 1
+\& Size_t size;
+.Ve
+.Sp
+The size of the per-instance data structure, e.g.:
+.Sp
+.Vb 1
+\& sizeof(PerlIOAPR)
+.Ve
+.Sp
+If this field is zero then \f(CW\*(C`PerlIO_pushed\*(C'\fR does not malloc anything
+and assumes layer's Pushed function will do any required layer stack
+manipulation \- used to avoid malloc/free overhead for dummy layers.
+If the field is non-zero it must be at least the size of \f(CW\*(C`PerlIOl\*(C'\fR,
+\&\f(CW\*(C`PerlIO_pushed\*(C'\fR will allocate memory for the layer's data structures
+and link new layer onto the stream's stack. (If the layer's Pushed
+method returns an error indication the layer is popped again.)
+.IP kind 4
+.IX Item "kind"
+.Vb 1
+\& IV kind;
+.Ve
+.RS 4
+.IP \(bu 4
+PERLIO_K_BUFFERED
+.Sp
+The layer is buffered.
+.IP \(bu 4
+PERLIO_K_RAW
+.Sp
+The layer is acceptable to have in a binmode(FH) stack \- i.e. it does not
+(or will configure itself not to) transform bytes passing through it.
+.IP \(bu 4
+PERLIO_K_CANCRLF
+.Sp
+Layer can translate between "\en" and CRLF line ends.
+.IP \(bu 4
+PERLIO_K_FASTGETS
+.Sp
+Layer allows buffer snooping.
+.IP \(bu 4
+PERLIO_K_MULTIARG
+.Sp
+Used when the layer's \fBopen()\fR accepts more arguments than usual. The
+extra arguments should come not before the \f(CW\*(C`MODE\*(C'\fR argument. When this
+flag is used it's up to the layer to validate the args.
+.RE
+.RS 4
+.RE
+.IP Pushed 4
+.IX Item "Pushed"
+.Vb 1
+\& IV (*Pushed)(pTHX_ PerlIO *f,const char *mode, SV *arg);
+.Ve
+.Sp
+The only absolutely mandatory method. Called when the layer is pushed
+onto the stack. The \f(CW\*(C`mode\*(C'\fR argument may be NULL if this occurs
+post-open. The \f(CW\*(C`arg\*(C'\fR will be non\-\f(CW\*(C`NULL\*(C'\fR if an argument string was
+passed. In most cases this should call \f(CWPerlIOBase_pushed()\fR to
+convert \f(CW\*(C`mode\*(C'\fR into the appropriate \f(CW\*(C`PERLIO_F_XXXXX\*(C'\fR flags in
+addition to any actions the layer itself takes. If a layer is not
+expecting an argument it need neither save the one passed to it, nor
+provide \f(CWGetarg()\fR (it could perhaps \f(CW\*(C`Perl_warn\*(C'\fR that the argument
+was un-expected).
+.Sp
+Returns 0 on success. On failure returns \-1 and should set errno.
+.IP Popped 4
+.IX Item "Popped"
+.Vb 1
+\& IV (*Popped)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Called when the layer is popped from the stack. A layer will normally
+be popped after \f(CWClose()\fR is called. But a layer can be popped
+without being closed if the program is dynamically managing layers on
+the stream. In such cases \f(CWPopped()\fR should free any resources
+(buffers, translation tables, ...) not held directly in the layer's
+struct. It should also \f(CWUnread()\fR any unconsumed data that has been
+read and buffered from the layer below back to that layer, so that it
+can be re-provided to what ever is now above.
+.Sp
+Returns 0 on success and failure. If \f(CWPopped()\fR returns \fItrue\fR then
+\&\fIperlio.c\fR assumes that either the layer has popped itself, or the
+layer is super special and needs to be retained for other reasons.
+In most cases it should return \fIfalse\fR.
+.IP Open 4
+.IX Item "Open"
+.Vb 1
+\& PerlIO * (*Open)(...);
+.Ve
+.Sp
+The \f(CWOpen()\fR method has lots of arguments because it combines the
+functions of perl's \f(CW\*(C`open\*(C'\fR, \f(CW\*(C`PerlIO_open\*(C'\fR, perl's \f(CW\*(C`sysopen\*(C'\fR,
+\&\f(CW\*(C`PerlIO_fdopen\*(C'\fR and \f(CW\*(C`PerlIO_reopen\*(C'\fR. The full prototype is as
+follows:
+.Sp
+.Vb 6
+\& PerlIO * (*Open)(pTHX_ PerlIO_funcs *tab,
+\& PerlIO_list_t *layers, IV n,
+\& const char *mode,
+\& int fd, int imode, int perm,
+\& PerlIO *old,
+\& int narg, SV **args);
+.Ve
+.Sp
+Open should (perhaps indirectly) call \f(CWPerlIO_allocate()\fR to allocate
+a slot in the table and associate it with the layers information for
+the opened file, by calling \f(CW\*(C`PerlIO_push\*(C'\fR. The \fIlayers\fR is an
+array of all the layers destined for the \f(CW\*(C`PerlIO *\*(C'\fR, and any
+arguments passed to them, \fIn\fR is the index into that array of the
+layer being called. The macro \f(CW\*(C`PerlIOArg\*(C'\fR will return a (possibly
+\&\f(CW\*(C`NULL\*(C'\fR) SV * for the argument passed to the layer.
+.Sp
+Where a layer opens or takes ownership of a file descriptor, that layer is
+responsible for getting the file descriptor's close-on-exec flag into the
+correct state. The flag should be clear for a file descriptor numbered
+less than or equal to \f(CW\*(C`PL_maxsysfd\*(C'\fR, and set for any file descriptor
+numbered higher. For thread safety, when a layer opens a new file
+descriptor it should if possible open it with the close-on-exec flag
+initially set.
+.Sp
+The \fImode\fR string is an "\f(CWfopen()\fR\-like" string which would match
+the regular expression \f(CW\*(C`/^[I#]?[rwa]\e+?[bt]?$/\*(C'\fR.
+.Sp
+The \f(CW\*(AqI\*(Aq\fR prefix is used during creation of \f(CW\*(C`stdin\*(C'\fR..\f(CW\*(C`stderr\*(C'\fR via
+special \f(CW\*(C`PerlIO_fdopen\*(C'\fR calls; the \f(CW\*(Aq#\*(Aq\fR prefix means that this is
+\&\f(CW\*(C`sysopen\*(C'\fR and that \fIimode\fR and \fIperm\fR should be passed to
+\&\f(CW\*(C`PerlLIO_open3\*(C'\fR; \f(CW\*(Aqr\*(Aq\fR means \fBr\fRead, \f(CW\*(Aqw\*(Aq\fR means \fBw\fRrite and
+\&\f(CW\*(Aqa\*(Aq\fR means \fBa\fRppend. The \f(CW\*(Aq+\*(Aq\fR suffix means that both reading and
+writing/appending are permitted. The \f(CW\*(Aqb\*(Aq\fR suffix means file should
+be binary, and \f(CW\*(Aqt\*(Aq\fR means it is text. (Almost all layers should do
+the IO in binary mode, and ignore the b/t bits. The \f(CW\*(C`:crlf\*(C'\fR layer
+should be pushed to handle the distinction.)
+.Sp
+If \fIold\fR is not \f(CW\*(C`NULL\*(C'\fR then this is a \f(CW\*(C`PerlIO_reopen\*(C'\fR. Perl itself
+does not use this (yet?) and semantics are a little vague.
+.Sp
+If \fIfd\fR not negative then it is the numeric file descriptor \fIfd\fR,
+which will be open in a manner compatible with the supplied mode
+string, the call is thus equivalent to \f(CW\*(C`PerlIO_fdopen\*(C'\fR. In this case
+\&\fInargs\fR will be zero.
+The file descriptor may have the close-on-exec flag either set or clear;
+it is the responsibility of the layer that takes ownership of it to get
+the flag into the correct state.
+.Sp
+If \fInargs\fR is greater than zero then it gives the number of arguments
+passed to \f(CW\*(C`open\*(C'\fR, otherwise it will be 1 if for example
+\&\f(CW\*(C`PerlIO_open\*(C'\fR was called. In simple cases SvPV_nolen(*args) is the
+pathname to open.
+.Sp
+If a layer provides \f(CWOpen()\fR it should normally call the \f(CWOpen()\fR
+method of next layer down (if any) and then push itself on top if that
+succeeds. \f(CW\*(C`PerlIOBase_open\*(C'\fR is provided to do exactly that, so in
+most cases you don't have to write your own \f(CWOpen()\fR method. If this
+method is not defined, other layers may have difficulty pushing
+themselves on top of it during open.
+.Sp
+If \f(CW\*(C`PerlIO_push\*(C'\fR was performed and open has failed, it must
+\&\f(CW\*(C`PerlIO_pop\*(C'\fR itself, since if it's not, the layer won't be removed
+and may cause bad problems.
+.Sp
+Returns \f(CW\*(C`NULL\*(C'\fR on failure.
+.IP Binmode 4
+.IX Item "Binmode"
+.Vb 1
+\& IV (*Binmode)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Optional. Used when \f(CW\*(C`:raw\*(C'\fR layer is pushed (explicitly or as a result
+of binmode(FH)). If not present layer will be popped. If present
+should configure layer as binary (or pop itself) and return 0.
+If it returns \-1 for error \f(CW\*(C`binmode\*(C'\fR will fail with layer
+still on the stack.
+.IP Getarg 4
+.IX Item "Getarg"
+.Vb 2
+\& SV * (*Getarg)(pTHX_ PerlIO *f,
+\& CLONE_PARAMS *param, int flags);
+.Ve
+.Sp
+Optional. If present should return an SV * representing the string
+argument passed to the layer when it was
+pushed. e.g. ":encoding(ascii)" would return an SvPV with value
+"ascii". (\fIparam\fR and \fIflags\fR arguments can be ignored in most
+cases)
+.Sp
+\&\f(CW\*(C`Dup\*(C'\fR uses \f(CW\*(C`Getarg\*(C'\fR to retrieve the argument originally passed to
+\&\f(CW\*(C`Pushed\*(C'\fR, so you must implement this function if your layer has an
+extra argument to \f(CW\*(C`Pushed\*(C'\fR and will ever be \f(CW\*(C`Dup\*(C'\fRed.
+.IP Fileno 4
+.IX Item "Fileno"
+.Vb 1
+\& IV (*Fileno)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Returns the Unix/Posix numeric file descriptor for the handle. Normally
+\&\f(CWPerlIOBase_fileno()\fR (which just asks next layer down) will suffice
+for this.
+.Sp
+Returns \-1 on error, which is considered to include the case where the
+layer cannot provide such a file descriptor.
+.IP Dup 4
+.IX Item "Dup"
+.Vb 2
+\& PerlIO * (*Dup)(pTHX_ PerlIO *f, PerlIO *o,
+\& CLONE_PARAMS *param, int flags);
+.Ve
+.Sp
+XXX: Needs more docs.
+.Sp
+Used as part of the "clone" process when a thread is spawned (in which
+case param will be non-NULL) and when a stream is being duplicated via
+\&'&' in the \f(CW\*(C`open\*(C'\fR.
+.Sp
+Similar to \f(CW\*(C`Open\*(C'\fR, returns PerlIO* on success, \f(CW\*(C`NULL\*(C'\fR on failure.
+.IP Read 4
+.IX Item "Read"
+.Vb 1
+\& SSize_t (*Read)(pTHX_ PerlIO *f, void *vbuf, Size_t count);
+.Ve
+.Sp
+Basic read operation.
+.Sp
+Typically will call \f(CW\*(C`Fill\*(C'\fR and manipulate pointers (possibly via the
+API). \f(CWPerlIOBuf_read()\fR may be suitable for derived classes which
+provide "fast gets" methods.
+.Sp
+Returns actual bytes read, or \-1 on an error.
+.IP Unread 4
+.IX Item "Unread"
+.Vb 2
+\& SSize_t (*Unread)(pTHX_ PerlIO *f,
+\& const void *vbuf, Size_t count);
+.Ve
+.Sp
+A superset of stdio's \f(CWungetc()\fR. Should arrange for future reads to
+see the bytes in \f(CW\*(C`vbuf\*(C'\fR. If there is no obviously better implementation
+then \f(CWPerlIOBase_unread()\fR provides the function by pushing a "fake"
+"pending" layer above the calling layer.
+.Sp
+Returns the number of unread chars.
+.IP Write 4
+.IX Item "Write"
+.Vb 1
+\& SSize_t (*Write)(PerlIO *f, const void *vbuf, Size_t count);
+.Ve
+.Sp
+Basic write operation.
+.Sp
+Returns bytes written or \-1 on an error.
+.IP Seek 4
+.IX Item "Seek"
+.Vb 1
+\& IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int whence);
+.Ve
+.Sp
+Position the file pointer. Should normally call its own \f(CW\*(C`Flush\*(C'\fR
+method and then the \f(CW\*(C`Seek\*(C'\fR method of next layer down.
+.Sp
+Returns 0 on success, \-1 on failure.
+.IP Tell 4
+.IX Item "Tell"
+.Vb 1
+\& Off_t (*Tell)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Return the file pointer. May be based on layers cached concept of
+position to avoid overhead.
+.Sp
+Returns \-1 on failure to get the file pointer.
+.IP Close 4
+.IX Item "Close"
+.Vb 1
+\& IV (*Close)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Close the stream. Should normally call \f(CWPerlIOBase_close()\fR to flush
+itself and close layers below, and then deallocate any data structures
+(buffers, translation tables, ...) not held directly in the data
+structure.
+.Sp
+Returns 0 on success, \-1 on failure.
+.IP Flush 4
+.IX Item "Flush"
+.Vb 1
+\& IV (*Flush)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Should make stream's state consistent with layers below. That is, any
+buffered write data should be written, and file position of lower layers
+adjusted for data read from below but not actually consumed.
+(Should perhaps \f(CWUnread()\fR such data to the lower layer.)
+.Sp
+Returns 0 on success, \-1 on failure.
+.IP Fill 4
+.IX Item "Fill"
+.Vb 1
+\& IV (*Fill)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+The buffer for this layer should be filled (for read) from layer
+below. When you "subclass" PerlIOBuf layer, you want to use its
+\&\fI_read\fR method and to supply your own fill method, which fills the
+PerlIOBuf's buffer.
+.Sp
+Returns 0 on success, \-1 on failure.
+.IP Eof 4
+.IX Item "Eof"
+.Vb 1
+\& IV (*Eof)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Return end-of-file indicator. \f(CWPerlIOBase_eof()\fR is normally sufficient.
+.Sp
+Returns 0 on end-of-file, 1 if not end-of-file, \-1 on error.
+.IP Error 4
+.IX Item "Error"
+.Vb 1
+\& IV (*Error)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Return error indicator. \f(CWPerlIOBase_error()\fR is normally sufficient.
+.Sp
+Returns 1 if there is an error (usually when \f(CW\*(C`PERLIO_F_ERROR\*(C'\fR is set),
+0 otherwise.
+.IP Clearerr 4
+.IX Item "Clearerr"
+.Vb 1
+\& void (*Clearerr)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Clear end-of-file and error indicators. Should call \f(CWPerlIOBase_clearerr()\fR
+to set the \f(CW\*(C`PERLIO_F_XXXXX\*(C'\fR flags, which may suffice.
+.IP Setlinebuf 4
+.IX Item "Setlinebuf"
+.Vb 1
+\& void (*Setlinebuf)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Mark the stream as line buffered. \f(CWPerlIOBase_setlinebuf()\fR sets the
+PERLIO_F_LINEBUF flag and is normally sufficient.
+.IP Get_base 4
+.IX Item "Get_base"
+.Vb 1
+\& STDCHAR * (*Get_base)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Allocate (if not already done so) the read buffer for this layer and
+return pointer to it. Return NULL on failure.
+.IP Get_bufsiz 4
+.IX Item "Get_bufsiz"
+.Vb 1
+\& Size_t (*Get_bufsiz)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Return the number of bytes that last \f(CWFill()\fR put in the buffer.
+.IP Get_ptr 4
+.IX Item "Get_ptr"
+.Vb 1
+\& STDCHAR * (*Get_ptr)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Return the current read pointer relative to this layer's buffer.
+.IP Get_cnt 4
+.IX Item "Get_cnt"
+.Vb 1
+\& SSize_t (*Get_cnt)(pTHX_ PerlIO *f);
+.Ve
+.Sp
+Return the number of bytes left to be read in the current buffer.
+.IP Set_ptrcnt 4
+.IX Item "Set_ptrcnt"
+.Vb 2
+\& void (*Set_ptrcnt)(pTHX_ PerlIO *f,
+\& STDCHAR *ptr, SSize_t cnt);
+.Ve
+.Sp
+Adjust the read pointer and count of bytes to match \f(CW\*(C`ptr\*(C'\fR and/or \f(CW\*(C`cnt\*(C'\fR.
+The application (or layer above) must ensure they are consistent.
+(Checking is allowed by the paranoid.)
+.SS Utilities
+.IX Subsection "Utilities"
+To ask for the next layer down use PerlIONext(PerlIO *f).
+.PP
+To check that a PerlIO* is valid use PerlIOValid(PerlIO *f). (All
+this does is really just to check that the pointer is non-NULL and
+that the pointer behind that is non-NULL.)
+.PP
+PerlIOBase(PerlIO *f) returns the "Base" pointer, or in other words,
+the \f(CW\*(C`PerlIOl*\*(C'\fR pointer.
+.PP
+PerlIOSelf(PerlIO* f, type) return the PerlIOBase cast to a type.
+.PP
+Perl_PerlIO_or_Base(PerlIO* f, callback, base, failure, args) either
+calls the \fIcallback\fR from the functions of the layer \fIf\fR (just by
+the name of the IO function, like "Read") with the \fIargs\fR, or if
+there is no such callback, calls the \fIbase\fR version of the callback
+with the same args, or if the f is invalid, set errno to EBADF and
+return \fIfailure\fR.
+.PP
+Perl_PerlIO_or_fail(PerlIO* f, callback, failure, args) either calls
+the \fIcallback\fR of the functions of the layer \fIf\fR with the \fIargs\fR,
+or if there is no such callback, set errno to EINVAL. Or if the f is
+invalid, set errno to EBADF and return \fIfailure\fR.
+.PP
+Perl_PerlIO_or_Base_void(PerlIO* f, callback, base, args) either calls
+the \fIcallback\fR of the functions of the layer \fIf\fR with the \fIargs\fR,
+or if there is no such callback, calls the \fIbase\fR version of the
+callback with the same args, or if the f is invalid, set errno to
+EBADF.
+.PP
+Perl_PerlIO_or_fail_void(PerlIO* f, callback, args) either calls the
+\&\fIcallback\fR of the functions of the layer \fIf\fR with the \fIargs\fR, or if
+there is no such callback, set errno to EINVAL. Or if the f is
+invalid, set errno to EBADF.
+.SS "Implementing PerlIO Layers"
+.IX Subsection "Implementing PerlIO Layers"
+If you find the implementation document unclear or not sufficient,
+look at the existing PerlIO layer implementations, which include:
+.IP \(bu 4
+C implementations
+.Sp
+The \fIperlio.c\fR and \fIperliol.h\fR in the Perl core implement the
+"unix", "perlio", "stdio", "crlf", "utf8", "byte", "raw", "pending"
+layers, and also the "mmap" and "win32" layers if applicable.
+(The "win32" is currently unfinished and unused, to see what is used
+instead in Win32, see "Querying the layers of filehandles" in PerlIO .)
+.Sp
+PerlIO::encoding, PerlIO::scalar, PerlIO::via in the Perl core.
+.Sp
+PerlIO::gzip and APR::PerlIO (mod_perl 2.0) on CPAN.
+.IP \(bu 4
+Perl implementations
+.Sp
+PerlIO::via::QuotedPrint in the Perl core and PerlIO::via::* on CPAN.
+.PP
+If you are creating a PerlIO layer, you may want to be lazy, in other
+words, implement only the methods that interest you. The other methods
+you can either replace with the "blank" methods
+.PP
+.Vb 2
+\& PerlIOBase_noop_ok
+\& PerlIOBase_noop_fail
+.Ve
+.PP
+(which do nothing, and return zero and \-1, respectively) or for
+certain methods you may assume a default behaviour by using a NULL
+method. The Open method looks for help in the 'parent' layer.
+The following table summarizes the behaviour:
+.PP
+.Vb 1
+\& method behaviour with NULL
+\&
+\& Clearerr PerlIOBase_clearerr
+\& Close PerlIOBase_close
+\& Dup PerlIOBase_dup
+\& Eof PerlIOBase_eof
+\& Error PerlIOBase_error
+\& Fileno PerlIOBase_fileno
+\& Fill FAILURE
+\& Flush SUCCESS
+\& Getarg SUCCESS
+\& Get_base FAILURE
+\& Get_bufsiz FAILURE
+\& Get_cnt FAILURE
+\& Get_ptr FAILURE
+\& Open INHERITED
+\& Popped SUCCESS
+\& Pushed SUCCESS
+\& Read PerlIOBase_read
+\& Seek FAILURE
+\& Set_cnt FAILURE
+\& Set_ptrcnt FAILURE
+\& Setlinebuf PerlIOBase_setlinebuf
+\& Tell FAILURE
+\& Unread PerlIOBase_unread
+\& Write FAILURE
+\&
+\& FAILURE Set errno (to EINVAL in Unixish, to LIB$_INVARG in VMS)
+\& and return \-1 (for numeric return values) or NULL (for
+\& pointers)
+\& INHERITED Inherited from the layer below
+\& SUCCESS Return 0 (for numeric return values) or a pointer
+.Ve
+.SS "Core Layers"
+.IX Subsection "Core Layers"
+The file \f(CW\*(C`perlio.c\*(C'\fR provides the following layers:
+.IP """unix""" 4
+.IX Item """unix"""
+A basic non-buffered layer which calls Unix/POSIX \f(CWread()\fR, \f(CWwrite()\fR,
+\&\f(CWlseek()\fR, \f(CWclose()\fR. No buffering. Even on platforms that distinguish
+between O_TEXT and O_BINARY this layer is always O_BINARY.
+.IP """perlio""" 4
+.IX Item """perlio"""
+A very complete generic buffering layer which provides the whole of
+PerlIO API. It is also intended to be used as a "base class" for other
+layers. (For example its \f(CWRead()\fR method is implemented in terms of
+the \f(CWGet_cnt()\fR/\f(CWGet_ptr()\fR/\f(CWSet_ptrcnt()\fR methods).
+.Sp
+"perlio" over "unix" provides a complete replacement for stdio as seen
+via PerlIO API. This is the default for USE_PERLIO when system's stdio
+does not permit perl's "fast gets" access, and which do not
+distinguish between \f(CW\*(C`O_TEXT\*(C'\fR and \f(CW\*(C`O_BINARY\*(C'\fR.
+.IP """stdio""" 4
+.IX Item """stdio"""
+A layer which provides the PerlIO API via the layer scheme, but
+implements it by calling system's stdio. This is (currently) the default
+if system's stdio provides sufficient access to allow perl's "fast gets"
+access and which do not distinguish between \f(CW\*(C`O_TEXT\*(C'\fR and \f(CW\*(C`O_BINARY\*(C'\fR.
+.IP """crlf""" 4
+.IX Item """crlf"""
+A layer derived using "perlio" as a base class. It provides Win32\-like
+"\en" to CR,LF translation. Can either be applied above "perlio" or serve
+as the buffer layer itself. "crlf" over "unix" is the default if system
+distinguishes between \f(CW\*(C`O_TEXT\*(C'\fR and \f(CW\*(C`O_BINARY\*(C'\fR opens. (At some point
+"unix" will be replaced by a "native" Win32 IO layer on that platform,
+as Win32's read/write layer has various drawbacks.) The "crlf" layer is
+a reasonable model for a layer which transforms data in some way.
+.IP """mmap""" 4
+.IX Item """mmap"""
+If Configure detects \f(CWmmap()\fR functions this layer is provided (with
+"perlio" as a "base") which does "read" operations by \fBmmap()\fRing the
+file. Performance improvement is marginal on modern systems, so it is
+mainly there as a proof of concept. It is likely to be unbundled from
+the core at some point. The "mmap" layer is a reasonable model for a
+minimalist "derived" layer.
+.IP """pending""" 4
+.IX Item """pending"""
+An "internal" derivative of "perlio" which can be used to provide
+\&\fBUnread()\fR function for layers which have no buffer or cannot be
+bothered. (Basically this layer's \f(CWFill()\fR pops itself off the stack
+and so resumes reading from layer below.)
+.IP """raw""" 4
+.IX Item """raw"""
+A dummy layer which never exists on the layer stack. Instead when
+"pushed" it actually pops the stack removing itself, it then calls
+Binmode function table entry on all the layers in the stack \- normally
+this (via PerlIOBase_binmode) removes any layers which do not have
+\&\f(CW\*(C`PERLIO_K_RAW\*(C'\fR bit set. Layers can modify that behaviour by defining
+their own Binmode entry.
+.IP """utf8""" 4
+.IX Item """utf8"""
+Another dummy layer. When pushed it pops itself and sets the
+\&\f(CW\*(C`PERLIO_F_UTF8\*(C'\fR flag on the layer which was (and now is once more)
+the top of the stack.
+.PP
+In addition \fIperlio.c\fR also provides a number of \f(CWPerlIOBase_xxxx()\fR
+functions which are intended to be used in the table slots of classes
+which do not need to do anything special for a particular method.
+.SS "Extension Layers"
+.IX Subsection "Extension Layers"
+Layers can be made available by extension modules. When an unknown layer
+is encountered the PerlIO code will perform the equivalent of :
+.PP
+.Vb 1
+\& use PerlIO \*(Aqlayer\*(Aq;
+.Ve
+.PP
+Where \fIlayer\fR is the unknown layer. \fIPerlIO.pm\fR will then attempt to:
+.PP
+.Vb 1
+\& require PerlIO::layer;
+.Ve
+.PP
+If after that process the layer is still not defined then the \f(CW\*(C`open\*(C'\fR
+will fail.
+.PP
+The following extension layers are bundled with perl:
+.IP """:encoding""" 4
+.IX Item """:encoding"""
+.Vb 1
+\& use Encoding;
+.Ve
+.Sp
+makes this layer available, although \fIPerlIO.pm\fR "knows" where to
+find it. It is an example of a layer which takes an argument as it is
+called thus:
+.Sp
+.Vb 1
+\& open( $fh, "<:encoding(iso\-8859\-7)", $pathname );
+.Ve
+.IP """:scalar""" 4
+.IX Item """:scalar"""
+Provides support for reading data from and writing data to a scalar.
+.Sp
+.Vb 1
+\& open( $fh, "+<:scalar", \e$scalar );
+.Ve
+.Sp
+When a handle is so opened, then reads get bytes from the string value
+of \fR\f(CI$scalar\fR\fI\fR, and writes change the value. In both cases the position
+in \fI\fR\f(CI$scalar\fR\fI\fR starts as zero but can be altered via \f(CW\*(C`seek\*(C'\fR, and
+determined via \f(CW\*(C`tell\*(C'\fR.
+.Sp
+Please note that this layer is implied when calling \fBopen()\fR thus:
+.Sp
+.Vb 1
+\& open( $fh, "+<", \e$scalar );
+.Ve
+.IP """:via""" 4
+.IX Item """:via"""
+Provided to allow layers to be implemented as Perl code. For instance:
+.Sp
+.Vb 2
+\& use PerlIO::via::StripHTML;
+\& open( my $fh, "<:via(StripHTML)", "index.html" );
+.Ve
+.Sp
+See PerlIO::via for details.
+.SH TODO
+.IX Header "TODO"
+Things that need to be done to improve this document.
+.IP \(bu 4
+Explain how to make a valid fh without going through \fBopen()\fR(i.e. apply
+a layer). For example if the file is not opened through perl, but we
+want to get back a fh, like it was opened by Perl.
+.Sp
+How PerlIO_apply_layera fits in, where its docs, was it made public?
+.Sp
+Currently the example could be something like this:
+.Sp
+.Vb 8
+\& PerlIO *foo_to_PerlIO(pTHX_ char *mode, ...)
+\& {
+\& char *mode; /* "w", "r", etc */
+\& const char *layers = ":APR"; /* the layer name */
+\& PerlIO *f = PerlIO_allocate(aTHX);
+\& if (!f) {
+\& return NULL;
+\& }
+\&
+\& PerlIO_apply_layers(aTHX_ f, mode, layers);
+\&
+\& if (f) {
+\& PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
+\& /* fill in the st struct, as in _open() */
+\& st\->file = file;
+\& PerlIOBase(f)\->flags |= PERLIO_F_OPEN;
+\&
+\& return f;
+\& }
+\& return NULL;
+\& }
+.Ve
+.IP \(bu 4
+fix/add the documentation in places marked as XXX.
+.IP \(bu 4
+The handling of errors by the layer is not specified. e.g. when $!
+should be set explicitly, when the error handling should be just
+delegated to the top layer.
+.Sp
+Probably give some hints on using \fBSETERRNO()\fR or pointers to where they
+can be found.
+.IP \(bu 4
+I think it would help to give some concrete examples to make it easier
+to understand the API. Of course I agree that the API has to be
+concise, but since there is no second document that is more of a
+guide, I think that it'd make it easier to start with the doc which is
+an API, but has examples in it in places where things are unclear, to
+a person who is not a PerlIO guru (yet).