This document describes the behavior and implementation of the PerlIO abstraction described in the perlapio manpage when USE_PERLIO is defined (and USE_SFIO is not).
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 perl6.
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 the PerlIO manpage, PERLIO in the perlrun manpage, and the open manpage for more information.
A PerlIOl * is a pointer to the struct, and the application level PerlIO * is a pointer to a PerlIOl * - i.e. a pointer to a pointer to the struct. This allows the application level PerlIO * to remain constant while the actual PerlIOl * underneath changes. (Compare perl's SV * which remains constant while its sv_any 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''.
It should be noted that because of the double indirection in a PerlIO *, a &(perlio->next) ``is'' a PerlIO *, and so to some degree at least one layer can use the ``standard'' API on the next layer down.
The above attempts to show how the layer scheme works in a simple case. The application's PerlIO * points to an entry in the table(s) representing open (allocated) handles. For example the first three slots in the table correspond to stdin,stdout and stderr. 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 lowlevel ``unix'' layer.
If Unix level read/write/lseek is not appropriate for (say) sockets then the ``unix'' layer can be replaced (at open time or even dynamically) with a ``socket'' layer.
Different handles can have different buffering schemes. The ``top'' layer could be the ``mmap'' layer if reading disk files was quicker using mmap than read. An ``unbuffered'' stream can be implemented simply by not having a buffer layer.
Layer is performing Win32-like ``\n'' mapped to CR,LF for output and CR,LF mapped to ``\n'' for input. Normally the provided ``crlf'' layer is the only layer that need bother about this. PerlIO_binmode() will mess with this flag rather than add/remove layers if the PERLIO_K_CANCRLF bit is set for the layers class.
Open should (perhaps indirectly) call PerlIO_allocate() to allocate a slot in the table and associate it with the layers information for the opened file, by calling PerlIO_push. The layers AV is an array of all the layers destined for the PerlIO *, and any arguments passed to them, n is the index into that array of the layer being called. The macro PerlIOArg will return a (possibly NULL) SV * for the argument passed to the layer.
The mode string is an ``fopen()-like'' string which would match the regular expression /^[I#]?[rwa]\+?[bt]?$/.
Having said all that translation-only layers do not need to provide Open() at all, but rather leave the opening to a lower level layer and wait to be ``pushed''. If a layer does provide Open() it should normally call the Open() method of next layer down (if any) and then push itself on top if that succeeds.
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 open.
Typically will call Fill and manipulate pointers (possibly via the API). PerlIOBuf_read() may be suitable for derived classes which provide ``fast gets'' methods.
A superset of stdio's ungetc(). Should arrange for future reads to see the bytes in vbuf. If there is no obviously better implementation then PerlIOBase_unread() provides the function by pushing a ``fake'' ``pending'' layer above the calling layer.
PerlIOBase(PerlIO *f) returns the ``Base'' pointer, or in other words, the PerlIOl* pointer.
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 Read() method is implemented in terms of the Get_cnt()/Get_ptr()/Set_ptrcnt() methods).
``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 O_TEXT and O_BINARY.
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 O_TEXT and O_BINARY.
A layer derived using ``perlio'' as a base class. It provides Win32-like ``\n'' 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 O_TEXT and O_BINARY 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.
If Configure detects mmap() functions this layer is provided (with ``perlio'' as a ``base'') which does ``read'' operations by mmap()ing 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.
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 PERLIO_K_RAW bit set. Layers can modify that behaviour by defining their own Binmode entry.
See the PerlIO::via manpage for details.