     1			/*
     2			 * perlio.c Copyright (c) 1996-2005, Nick Ing-Simmons You may distribute
     3			 * under the terms of either the GNU General Public License or the
     4			 * Artistic License, as specified in the README file.
     5			 */
     6			
     7			/*
     8			 * Hour after hour for nearly three weary days he had jogged up and down,
     9			 * over passes, and through long dales, and across many streams.
    10			 */
    11			
    12			/* This file contains the functions needed to implement PerlIO, which
    13			 * is Perl's private replacement for the C stdio library. This is used
    14			 * by default unless you compile with -Uuseperlio or run with
    15			 * PERLIO=:stdio (but don't do this unless you know what you're doing)
    16			 */
    17			
    18			/*
    19			 * If we have ActivePerl-like PERL_IMPLICIT_SYS then we need a dTHX to get
    20			 * at the dispatch tables, even when we do not need it for other reasons.
    21			 * Invent a dSYS macro to abstract this out
    22			 */
    23			#ifdef PERL_IMPLICIT_SYS
    24			#define dSYS dTHX
    25			#else
    26			#define dSYS dNOOP
    27			#endif
    28			
    29			#define VOIDUSED 1
    30			#ifdef PERL_MICRO
    31			#   include "uconfig.h"
    32			#else
    33			#   include "config.h"
    34			#endif
    35			
    36			#define PERLIO_NOT_STDIO 0
    37			#if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
    38			/*
    39			 * #define PerlIO FILE
    40			 */
    41			#endif
    42			/*
    43			 * This file provides those parts of PerlIO abstraction
    44			 * which are not #defined in perlio.h.
    45			 * Which these are depends on various Configure #ifdef's
    46			 */
    47			
    48			#include "EXTERN.h"
    49			#define PERL_IN_PERLIO_C
    50			#include "perl.h"
    51			
    52			#ifdef PERL_IMPLICIT_CONTEXT
    53			#undef dSYS
    54			#define dSYS dTHX
    55			#endif
    56			
    57			#include "XSUB.h"
    58			
    59			#define PERLIO_MAX_REFCOUNTABLE_FD 2048
    60			
    61			#ifdef __Lynx__
    62			/* Missing proto on LynxOS */
    63			int mkstemp(char*);
    64			#endif
    65			
    66			/* Call the callback or PerlIOBase, and return failure. */
    67			#define Perl_PerlIO_or_Base(f, callback, base, failure, args) 	\
    68				if (PerlIOValid(f)) {					\
    69					const PerlIO_funcs *tab = PerlIOBase(f)->tab;	\
    70					if (tab && tab->callback)			\
    71						return (*tab->callback) args;		\
    72					else						\
    73						return PerlIOBase_ ## base args;	\
    74				}							\
    75				else							\
    76					SETERRNO(EBADF, SS_IVCHAN);			\
    77				return failure
    78			
    79			/* Call the callback or fail, and return failure. */
    80			#define Perl_PerlIO_or_fail(f, callback, failure, args) 	\
    81				if (PerlIOValid(f)) {					\
    82					const PerlIO_funcs *tab = PerlIOBase(f)->tab;	\
    83					if (tab && tab->callback)			\
    84						return (*tab->callback) args;		\
    85					SETERRNO(EINVAL, LIB_INVARG);			\
    86				}							\
    87				else							\
    88					SETERRNO(EBADF, SS_IVCHAN);			\
    89				return failure
    90			
    91			/* Call the callback or PerlIOBase, and be void. */
    92			#define Perl_PerlIO_or_Base_void(f, callback, base, args) 	\
    93				if (PerlIOValid(f)) {					\
    94					const PerlIO_funcs *tab = PerlIOBase(f)->tab;	\
    95					if (tab && tab->callback)			\
    96						(*tab->callback) args;			\
    97					else						\
    98						PerlIOBase_ ## base args;		\
    99				}							\
   100				else							\
   101					SETERRNO(EBADF, SS_IVCHAN)
   102			
   103			/* Call the callback or fail, and be void. */
   104			#define Perl_PerlIO_or_fail_void(f, callback, args) 		\
   105				if (PerlIOValid(f)) {					\
   106					const PerlIO_funcs *tab = PerlIOBase(f)->tab;	\
   107					if (tab && tab->callback)			\
   108						(*tab->callback) args;			\
   109					else						\
   110						SETERRNO(EINVAL, LIB_INVARG);		\
   111				}							\
   112				else							\
   113					SETERRNO(EBADF, SS_IVCHAN)
   114			
   115			#ifndef USE_SFIO
   116			int
   117			perlsio_binmode(FILE *fp, int iotype, int mode)
   118	      ######    {
   119			    /*
   120			     * This used to be contents of do_binmode in doio.c
   121			     */
   122			#ifdef DOSISH
   123			#  if defined(atarist) || defined(__MINT__)
   124			    if (!fflush(fp)) {
   125				if (mode & O_BINARY)
   126				    ((FILE *) fp)->_flag |= _IOBIN;
   127				else
   128				    ((FILE *) fp)->_flag &= ~_IOBIN;
   129				return 1;
   130			    }
   131			    return 0;
   132			#  else
   133			    dTHX;
   134			#ifdef NETWARE
   135			    if (PerlLIO_setmode(fp, mode) != -1) {
   136			#else
   137			    if (PerlLIO_setmode(fileno(fp), mode) != -1) {
   138			#endif
   139			#    if defined(WIN32) && defined(__BORLANDC__)
   140				/*
   141				 * The translation mode of the stream is maintained independent of
   142				 * the translation mode of the fd in the Borland RTL (heavy
   143				 * digging through their runtime sources reveal).  User has to set
   144				 * the mode explicitly for the stream (though they don't document
   145				 * this anywhere). GSAR 97-5-24
   146				 */
   147				fseek(fp, 0L, 0);
   148				if (mode & O_BINARY)
   149				    fp->flags |= _F_BIN;
   150				else
   151				    fp->flags &= ~_F_BIN;
   152			#    endif
   153				return 1;
   154			    }
   155			    else
   156				return 0;
   157			#  endif
   158			#else
   159			#  if defined(USEMYBINMODE)
   160			    dTHX;
   161			    if (my_binmode(fp, iotype, mode) != FALSE)
   162				return 1;
   163			    else
   164				return 0;
   165			#  else
   166	      ######        PERL_UNUSED_ARG(fp);
   167	      ######        PERL_UNUSED_ARG(iotype);
   168	      ######        PERL_UNUSED_ARG(mode);
   169	      ######        return 1;
   170			#  endif
   171			#endif
   172			}
   173			#endif /* sfio */
   174			
   175			#ifndef O_ACCMODE
   176			#define O_ACCMODE 3             /* Assume traditional implementation */
   177			#endif
   178			
   179			int
   180			PerlIO_intmode2str(int rawmode, char *mode, int *writing)
   181	        3053    {
   182	        3053        const int result = rawmode & O_ACCMODE;
   183	        3053        int ix = 0;
   184	        3053        int ptype;
   185	        3053        switch (result) {
   186			    case O_RDONLY:
   187	          28    	ptype = IoTYPE_RDONLY;
   188	          28    	break;
   189			    case O_WRONLY:
   190	          20    	ptype = IoTYPE_WRONLY;
   191	          20    	break;
   192			    case O_RDWR:
   193			    default:
   194	        3005    	ptype = IoTYPE_RDWR;
   195	        3053    	break;
   196			    }
   197	        3053        if (writing)
   198	        3053    	*writing = (result != O_RDONLY);
   199			
   200	        3053        if (result == O_RDONLY) {
   201	          28    	mode[ix++] = 'r';
   202			    }
   203			#ifdef O_APPEND
   204	        3025        else if (rawmode & O_APPEND) {
   205	      ######    	mode[ix++] = 'a';
   206	      ######    	if (result != O_WRONLY)
   207	      ######    	    mode[ix++] = '+';
   208			    }
   209			#endif
   210			    else {
   211	        3025    	if (result == O_WRONLY)
   212	          20    	    mode[ix++] = 'w';
   213				else {
   214	        3005    	    mode[ix++] = 'r';
   215	        3005    	    mode[ix++] = '+';
   216				}
   217			    }
   218	        3053        if (rawmode & O_BINARY)
   219	        3053    	mode[ix++] = 'b';
   220	        3053        mode[ix] = '\0';
   221	        3053        return ptype;
   222			}
   223			
   224			#ifndef PERLIO_LAYERS
   225			int
   226			PerlIO_apply_layers(pTHX_ PerlIO *f, const char *mode, const char *names)
   227			{
   228			    if (!names || !*names
   229			        || strEQ(names, ":crlf")
   230			        || strEQ(names, ":raw")
   231			        || strEQ(names, ":bytes")
   232			       ) {
   233				return 0;
   234			    }
   235			    Perl_croak(aTHX_ "Cannot apply \"%s\" in non-PerlIO perl", names);
   236			    /*
   237			     * NOTREACHED
   238			     */
   239			    return -1;
   240			}
   241			
   242			void
   243			PerlIO_destruct(pTHX)
   244			{
   245			}
   246			
   247			int
   248			PerlIO_binmode(pTHX_ PerlIO *fp, int iotype, int mode, const char *names)
   249			{
   250			#ifdef USE_SFIO
   251			    PERL_UNUSED_ARG(iotype);
   252			    PERL_UNUSED_ARG(mode);
   253			    PERL_UNUSED_ARG(names);
   254			    return 1;
   255			#else
   256			    return perlsio_binmode(fp, iotype, mode);
   257			#endif
   258			}
   259			
   260			PerlIO *
   261			PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
   262			{
   263			#if defined(PERL_MICRO) || defined(SYMBIAN)
   264			    return NULL;
   265			#else
   266			#ifdef PERL_IMPLICIT_SYS
   267			    return PerlSIO_fdupopen(f);
   268			#else
   269			#ifdef WIN32
   270			    return win32_fdupopen(f);
   271			#else
   272			    if (f) {
   273				const int fd = PerlLIO_dup(PerlIO_fileno(f));
   274				if (fd >= 0) {
   275				    char mode[8];
   276				    int omode = fcntl(fd, F_GETFL);
   277			#ifdef DJGPP
   278				    omode = djgpp_get_stream_mode(f);
   279			#endif
   280				    PerlIO_intmode2str(omode,mode,NULL);
   281				    /* the r+ is a hack */
   282				    return PerlIO_fdopen(fd, mode);
   283				}
   284				return NULL;
   285			    }
   286			    else {
   287				SETERRNO(EBADF, SS_IVCHAN);
   288			    }
   289			#endif
   290			    return NULL;
   291			#endif
   292			#endif
   293			}
   294			
   295			
   296			/*
   297			 * De-mux PerlIO_openn() into fdopen, freopen and fopen type entries
   298			 */
   299			
   300			PerlIO *
   301			PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
   302				     int imode, int perm, PerlIO *old, int narg, SV **args)
   303			{
   304			    if (narg) {
   305				if (narg > 1) {
   306				    Perl_croak(aTHX_ "More than one argument to open");
   307				}
   308				if (*args == &PL_sv_undef)
   309				    return PerlIO_tmpfile();
   310				else {
   311				    const char *name = SvPV_nolen_const(*args);
   312				    if (*mode == IoTYPE_NUMERIC) {
   313					fd = PerlLIO_open3(name, imode, perm);
   314					if (fd >= 0)
   315					    return PerlIO_fdopen(fd, mode + 1);
   316				    }
   317				    else if (old) {
   318					return PerlIO_reopen(name, mode, old);
   319				    }
   320				    else {
   321					return PerlIO_open(name, mode);
   322				    }
   323				}
   324			    }
   325			    else {
   326				return PerlIO_fdopen(fd, (char *) mode);
   327			    }
   328			    return NULL;
   329			}
   330			
   331			XS(XS_PerlIO__Layer__find)
   332			{
   333			    dXSARGS;
   334			    if (items < 2)
   335				Perl_croak(aTHX_ "Usage class->find(name[,load])");
   336			    else {
   337				const char *name = SvPV_nolen_const(ST(1));
   338				ST(0) = (strEQ(name, "crlf")
   339					 || strEQ(name, "raw")) ? &PL_sv_yes : &PL_sv_undef;
   340				XSRETURN(1);
   341			    }
   342			}
   343			
   344			
   345			void
   346			Perl_boot_core_PerlIO(pTHX)
   347			{
   348			    newXS("PerlIO::Layer::find", XS_PerlIO__Layer__find, __FILE__);
   349			}
   350			
   351			#endif
   352			
   353			
   354			#ifdef PERLIO_IS_STDIO
   355			
   356			void
   357			PerlIO_init(pTHX)
   358			{
   359			    /*
   360			     * Does nothing (yet) except force this file to be included in perl
   361			     * binary. That allows this file to force inclusion of other functions
   362			     * that may be required by loadable extensions e.g. for
   363			     * FileHandle::tmpfile
   364			     */
   365			}
   366			
   367			#undef PerlIO_tmpfile
   368			PerlIO *
   369			PerlIO_tmpfile(void)
   370			{
   371			    return tmpfile();
   372			}
   373			
   374			#else                           /* PERLIO_IS_STDIO */
   375			
   376			#ifdef USE_SFIO
   377			
   378			#undef HAS_FSETPOS
   379			#undef HAS_FGETPOS
   380			
   381			/*
   382			 * This section is just to make sure these functions get pulled in from
   383			 * libsfio.a
   384			 */
   385			
   386			#undef PerlIO_tmpfile
   387			PerlIO *
   388			PerlIO_tmpfile(void)
   389			{
   390			    return sftmp(0);
   391			}
   392			
   393			void
   394			PerlIO_init(pTHX)
   395			{
   396			    /*
   397			     * Force this file to be included in perl binary. Which allows this
   398			     * file to force inclusion of other functions that may be required by
   399			     * loadable extensions e.g. for FileHandle::tmpfile
   400			     */
   401			
   402			    /*
   403			     * Hack sfio does its own 'autoflush' on stdout in common cases. Flush
   404			     * results in a lot of lseek()s to regular files and lot of small
   405			     * writes to pipes.
   406			     */
   407			    sfset(sfstdout, SF_SHARE, 0);
   408			}
   409			
   410			/* This is not the reverse of PerlIO_exportFILE(), PerlIO_releaseFILE() is. */
   411			PerlIO *
   412			PerlIO_importFILE(FILE *stdio, const char *mode)
   413			{
   414			    const int fd = fileno(stdio);
   415			    if (!mode || !*mode) {
   416				mode = "r+";
   417			    }
   418			    return PerlIO_fdopen(fd, mode);
   419			}
   420			
   421			FILE *
   422			PerlIO_findFILE(PerlIO *pio)
   423			{
   424			    const int fd = PerlIO_fileno(pio);
   425			    FILE * const f = fdopen(fd, "r+");
   426			    PerlIO_flush(pio);
   427			    if (!f && errno == EINVAL)
   428				f = fdopen(fd, "w");
   429			    if (!f && errno == EINVAL)
   430				f = fdopen(fd, "r");
   431			    return f;
   432			}
   433			
   434			
   435			#else                           /* USE_SFIO */
   436			/*======================================================================================*/
   437			/*
   438			 * Implement all the PerlIO interface ourselves.
   439			 */
   440			
   441			#include "perliol.h"
   442			
   443			/*
   444			 * We _MUST_ have <unistd.h> if we are using lseek() and may have large
   445			 * files
   446			 */
   447			#ifdef I_UNISTD
   448			#include <unistd.h>
   449			#endif
   450			#ifdef HAS_MMAP
   451			#include <sys/mman.h>
   452			#endif
   453			
   454			void
   455			PerlIO_debug(const char *fmt, ...)
   456	      931103    {
   457	      931103        va_list ap;
   458			    dSYS;
   459	      931103        va_start(ap, fmt);
   460	      931103        if (!PL_perlio_debug_fd && !PL_tainting && PL_uid == PL_euid && PL_gid == PL_egid) {
   461	        4459            const char *s = PerlEnv_getenv("PERLIO_DEBUG");
   462	        4459    	if (s && *s)
   463	      ######    	    PL_perlio_debug_fd = PerlLIO_open3(s, O_WRONLY | O_CREAT | O_APPEND, 0666);
   464				else
   465	        4459    	    PL_perlio_debug_fd = -1;
   466			    }
   467	      931103        if (PL_perlio_debug_fd > 0) {
   468				dTHX;
   469	      ######    	const char *s = CopFILE(PL_curcop);
   470	      ######    	STRLEN len;
   471			#ifdef USE_ITHREADS
   472				/* Use fixed buffer as sv_catpvf etc. needs SVs */
   473				char buffer[1024];
   474				if (!s)
   475				    s = "(none)";
   476				len = sprintf(buffer, "%.40s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));
   477				vsprintf(buffer+len, fmt, ap);
   478				PerlLIO_write(PL_perlio_debug_fd, buffer, strlen(buffer));
   479			#else
   480	      ######    	SV *sv = newSVpvn("", 0);
   481	      ######    	if (!s)
   482	      ######    	    s = "(none)";
   483	      ######    	Perl_sv_catpvf(aTHX_ sv, "%s:%" IVdf " ", s,
   484					       (IV) CopLINE(PL_curcop));
   485	      ######    	Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap);
   486			
   487	      ######    	s = SvPV_const(sv, len);
   488	      ######    	PerlLIO_write(PL_perlio_debug_fd, s, len);
   489	      ######    	SvREFCNT_dec(sv);
   490			#endif
   491			    }
   492	      931103        va_end(ap);
   493			}
   494			
   495			/*--------------------------------------------------------------------------------------*/
   496			
   497			/*
   498			 * Inner level routines
   499			 */
   500			
   501			/*
   502			 * Table of pointers to the PerlIO structs (malloc'ed)
   503			 */
   504			#define PERLIO_TABLE_SIZE 64
   505			
   506			PerlIO *
   507			PerlIO_allocate(pTHX)
   508	       83232    {
   509			    /*
   510			     * Find a free slot in the table, allocating new table as necessary
   511			     */
   512	       83232        PerlIO **last;
   513	       83232        PerlIO *f;
   514	       83232        last = &PL_perlio;
   515	       83232        while ((f = *last)) {
   516	       78729    	int i;
   517	       78729    	last = (PerlIO **) (f);
   518	      363193    	for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
   519	      363193    	    if (!*++f) {
   520	       78729    		return f;
   521				    }
   522				}
   523			    }
   524	        4503        Newz('I',f,PERLIO_TABLE_SIZE,PerlIO);
   525	        4503        if (!f) {
   526	      ######    	return NULL;
   527			    }
   528	        4503        *last = f;
   529	        4503        return f + 1;
   530			}
   531			
   532			#undef PerlIO_fdupopen
   533			PerlIO *
   534			PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
   535	        1483    {
   536	        1483        if (PerlIOValid(f)) {
   537	        1483    	const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
   538	        1483    	PerlIO_debug("fdupopen f=%p param=%p\n",(void*)f,(void*)param);
   539	        1483    	if (tab && tab->Dup)
   540	        1483    	     return (*tab->Dup)(aTHX_ PerlIO_allocate(aTHX), f, param, flags);
   541				else {
   542	      ######    	     return PerlIOBase_dup(aTHX_ PerlIO_allocate(aTHX), f, param, flags);
   543				}
   544			    }
   545			    else
   546	      ######    	 SETERRNO(EBADF, SS_IVCHAN);
   547			
   548	      ######        return NULL;
   549			}
   550			
   551			void
   552			PerlIO_cleantable(pTHX_ PerlIO **tablep)
   553	        9098    {
   554	        9098        PerlIO *table = *tablep;
   555	        9098        if (table) {
   556	        4549    	int i;
   557	        4549    	PerlIO_cleantable(aTHX_(PerlIO **) & (table[0]));
   558	      291136    	for (i = PERLIO_TABLE_SIZE - 1; i > 0; i--) {
   559	      286587    	    PerlIO *f = table + i;
   560	      286587    	    if (*f) {
   561	       13671    		PerlIO_close(f);
   562				    }
   563				}
   564	        4549    	Safefree(table);
   565	        4549    	*tablep = NULL;
   566			    }
   567			}
   568			
   569			
   570			PerlIO_list_t *
   571			PerlIO_list_alloc(pTHX)
   572	       11077    {
   573	       11077        PerlIO_list_t *list;
   574	       11077        Newz('L', list, 1, PerlIO_list_t);
   575	       11077        list->refcnt = 1;
   576	       11077        return list;
   577			}
   578			
   579			void
   580			PerlIO_list_free(pTHX_ PerlIO_list_t *list)
   581	       94277    {
   582	       94277        if (list) {
   583	       94277    	if (--list->refcnt == 0) {
   584	       11169    	    if (list->array) {
   585	       11166    		IV i;
   586	       63628    		for (i = 0; i < list->cur; i++) {
   587	       52462    		    if (list->array[i].arg)
   588	       11486    			SvREFCNT_dec(list->array[i].arg);
   589					}
   590	       11166    		Safefree(list->array);
   591				    }
   592	       11169    	    Safefree(list);
   593				}
   594			    }
   595			}
   596			
   597			void
   598			PerlIO_list_push(pTHX_ PerlIO_list_t *list, PerlIO_funcs *funcs, SV *arg)
   599	       51956    {
   600	       51956        PerlIO_pair_t *p;
   601	       51956        if (list->cur >= list->len) {
   602	       15577    	list->len += 8;
   603	       15577    	if (list->array)
   604	        4503    	    Renew(list->array, list->len, PerlIO_pair_t);
   605				else
   606	       11074    	    New('l', list->array, list->len, PerlIO_pair_t);
   607			    }
   608	       51956        p = &(list->array[list->cur++]);
   609	       51956        p->funcs = funcs;
   610	       51956        if ((p->arg = arg)) {
   611	       11394    	(void)SvREFCNT_inc(arg);
   612			    }
   613			}
   614			
   615			PerlIO_list_t *
   616			PerlIO_clone_list(pTHX_ PerlIO_list_t *proto, CLONE_PARAMS *param)
   617	      ######    {
   618	      ######        PerlIO_list_t *list = (PerlIO_list_t *) NULL;
   619	      ######        if (proto) {
   620	      ######    	int i;
   621	      ######    	list = PerlIO_list_alloc(aTHX);
   622	      ######    	for (i=0; i < proto->cur; i++) {
   623	      ######    	    SV *arg = Nullsv;
   624	      ######    	    if (proto->array[i].arg)
   625	      ######    		arg = PerlIO_sv_dup(aTHX_ proto->array[i].arg,param);
   626	      ######    	    PerlIO_list_push(aTHX_ list, proto->array[i].funcs, arg);
   627				}
   628			    }
   629	      ######        return list;
   630			}
   631			
   632			void
   633			PerlIO_clone(pTHX_ PerlInterpreter *proto, CLONE_PARAMS *param)
   634	      ######    {
   635			#ifdef USE_ITHREADS
   636			    PerlIO **table = &proto->Iperlio;
   637			    PerlIO *f;
   638			    PL_perlio = NULL;
   639			    PL_known_layers = PerlIO_clone_list(aTHX_ proto->Iknown_layers, param);
   640			    PL_def_layerlist = PerlIO_clone_list(aTHX_ proto->Idef_layerlist, param);
   641			    PerlIO_allocate(aTHX); /* root slot is never used */
   642			    PerlIO_debug("Clone %p from %p\n",aTHX,proto);
   643			    while ((f = *table)) {
   644				    int i;
   645				    table = (PerlIO **) (f++);
   646				    for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
   647					if (*f) {
   648					    (void) fp_dup(f, 0, param);
   649					}
   650					f++;
   651				    }
   652				}
   653			#else
   654	      ######        PERL_UNUSED_ARG(proto);
   655	      ######        PERL_UNUSED_ARG(param);
   656			#endif
   657			}
   658			
   659			void
   660			PerlIO_destruct(pTHX)
   661	        4549    {
   662	        4549        PerlIO **table = &PL_perlio;
   663	        9098        PerlIO *f;
   664			#ifdef USE_ITHREADS
   665			    PerlIO_debug("Destruct %p\n",aTHX);
   666			#endif
   667	        9098        while ((f = *table)) {
   668	        4549    	int i;
   669	        4549    	table = (PerlIO **) (f++);
   670	      291136    	for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
   671	      286587    	    PerlIO *x = f;
   672	      316748    	    PerlIOl *l;
   673	      316748    	    while ((l = *x)) {
   674	       30161    		if (l->tab->kind & PERLIO_K_DESTRUCT) {
   675	          27    		    PerlIO_debug("Destruct popping %s\n", l->tab->name);
   676	          27    		    PerlIO_flush(x);
   677	          27    		    PerlIO_pop(aTHX_ x);
   678					}
   679					else {
   680	       30134    		    x = PerlIONext(x);
   681					}
   682				    }
   683	      286587    	    f++;
   684				}
   685			    }
   686			}
   687			
   688			void
   689			PerlIO_pop(pTHX_ PerlIO *f)
   690	      157094    {
   691	      157094        PerlIOl *l = *f;
   692	      157094        if (l) {
   693	      157094    	PerlIO_debug("PerlIO_pop f=%p %s\n", (void*)f, l->tab->name);
   694	      157094    	if (l->tab->Popped) {
   695				    /*
   696				     * If popped returns non-zero do not free its layer structure
   697				     * it has either done so itself, or it is shared and still in
   698				     * use
   699				     */
   700	      157094    	    if ((*l->tab->Popped) (aTHX_ f) != 0)
   701	      ######    		return;
   702				}
   703	      157094    	*f = l->next;
   704	      157094    	Safefree(l);
   705			    }
   706			}
   707			
   708			/* Return as an array the stack of layers on a filehandle.  Note that
   709			 * the stack is returned top-first in the array, and there are three
   710			 * times as many array elements as there are layers in the stack: the
   711			 * first element of a layer triplet is the name, the second one is the
   712			 * arguments, and the third one is the flags. */
   713			
   714			AV *
   715			PerlIO_get_layers(pTHX_ PerlIO *f)
   716	          13    {
   717	          13         AV *av = newAV();
   718			
   719	          13         if (PerlIOValid(f)) {
   720	          13    	  PerlIOl *l = PerlIOBase(f);
   721			
   722	          47    	  while (l) {
   723	          34    	       SV *name = l->tab && l->tab->name ?
   724	          34    		    newSVpv(l->tab->name, 0) : &PL_sv_undef;
   725	          34    	       SV *arg = l->tab && l->tab->Getarg ?
   726	          34    		    (*l->tab->Getarg)(aTHX_ &l, 0, 0) : &PL_sv_undef;
   727	          34    	       av_push(av, name);
   728	          34    	       av_push(av, arg);
   729	          34    	       av_push(av, newSViv((IV)l->flags));
   730	          34    	       l = l->next;
   731				  }
   732			     }
   733			
   734	          13         return av;
   735			}
   736			
   737			/*--------------------------------------------------------------------------------------*/
   738			/*
   739			 * XS Interface for perl code
   740			 */
   741			
   742			PerlIO_funcs *
   743			PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
   744	       11226    {
   745			    dVAR;
   746	       11226        IV i;
   747	       11226        if ((SSize_t) len <= 0)
   748	        9006    	len = strlen(name);
   749	       36348        for (i = 0; i < PL_known_layers->cur; i++) {
   750	       36305    	PerlIO_funcs *f = PL_known_layers->array[i].funcs;
   751	       36305    	if (memEQ(f->name, name, len) && f->name[len] == 0) {
   752	       11183    	    PerlIO_debug("%.*s => %p\n", (int) len, name, (void*)f);
   753	       11183    	    return f;
   754				}
   755			    }
   756	          43        if (load && PL_subname && PL_def_layerlist
   757				&& PL_def_layerlist->cur >= 2) {
   758	          33    	if (PL_in_load_module) {
   759	      ######    	    Perl_croak(aTHX_ "Recursive call to Perl_load_module in PerlIO_find_layer");
   760	          33    	    return NULL;
   761				} else {
   762	          33    	    SV *pkgsv = newSVpvn("PerlIO", 6);
   763	          33    	    SV *layer = newSVpvn(name, len);
   764	          33    	    CV *cv  = get_cv("PerlIO::Layer::NoWarnings", FALSE);
   765	          33        	    ENTER;
   766	          33    	    SAVEINT(PL_in_load_module);
   767	          33    	    if (cv) {
   768	          33    		SAVEGENERICSV(PL_warnhook);
   769	          33    		(void)SvREFCNT_inc(cv);
   770	          33    		PL_warnhook = (SV *) cv;
   771				    }
   772	          33    	    PL_in_load_module++;
   773				    /*
   774				     * The two SVs are magically freed by load_module
   775				     */
   776	          33    	    Perl_load_module(aTHX_ 0, pkgsv, Nullsv, layer, Nullsv);
   777	          33    	    PL_in_load_module--;
   778	          33    	    LEAVE;
   779	          33    	    return PerlIO_find_layer(aTHX_ name, len, 0);
   780				}
   781			    }
   782	          10        PerlIO_debug("Cannot find %.*s\n", (int) len, name);
   783	          10        return NULL;
   784			}
   785			
   786			#ifdef USE_ATTRIBUTES_FOR_PERLIO
   787			
   788			static int
   789			perlio_mg_set(pTHX_ SV *sv, MAGIC *mg)
   790			{
   791			    if (SvROK(sv)) {
   792				IO *io = GvIOn((GV *) SvRV(sv));
   793				PerlIO *ifp = IoIFP(io);
   794				PerlIO *ofp = IoOFP(io);
   795				Perl_warn(aTHX_ "set %" SVf " %p %p %p", sv, io, ifp, ofp);
   796			    }
   797			    return 0;
   798			}
   799			
   800			static int
   801			perlio_mg_get(pTHX_ SV *sv, MAGIC *mg)
   802			{
   803			    if (SvROK(sv)) {
   804				IO *io = GvIOn((GV *) SvRV(sv));
   805				PerlIO *ifp = IoIFP(io);
   806				PerlIO *ofp = IoOFP(io);
   807				Perl_warn(aTHX_ "get %" SVf " %p %p %p", sv, io, ifp, ofp);
   808			    }
   809			    return 0;
   810			}
   811			
   812			static int
   813			perlio_mg_clear(pTHX_ SV *sv, MAGIC *mg)
   814			{
   815			    Perl_warn(aTHX_ "clear %" SVf, sv);
   816			    return 0;
   817			}
   818			
   819			static int
   820			perlio_mg_free(pTHX_ SV *sv, MAGIC *mg)
   821			{
   822			    Perl_warn(aTHX_ "free %" SVf, sv);
   823			    return 0;
   824			}
   825			
   826			MGVTBL perlio_vtab = {
   827			    perlio_mg_get,
   828			    perlio_mg_set,
   829			    NULL,                       /* len */
   830			    perlio_mg_clear,
   831			    perlio_mg_free
   832			};
   833			
   834			XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
   835			{
   836			    dXSARGS;
   837			    SV *sv = SvRV(ST(1));
   838			    AV *av = newAV();
   839			    MAGIC *mg;
   840			    int count = 0;
   841			    int i;
   842			    sv_magic(sv, (SV *) av, PERL_MAGIC_ext, NULL, 0);
   843			    SvRMAGICAL_off(sv);
   844			    mg = mg_find(sv, PERL_MAGIC_ext);
   845			    mg->mg_virtual = &perlio_vtab;
   846			    mg_magical(sv);
   847			    Perl_warn(aTHX_ "attrib %" SVf, sv);
   848			    for (i = 2; i < items; i++) {
   849				STRLEN len;
   850				const char *name = SvPV_const(ST(i), len);
   851				SV *layer = PerlIO_find_layer(aTHX_ name, len, 1);
   852				if (layer) {
   853				    av_push(av, SvREFCNT_inc(layer));
   854				}
   855				else {
   856				    ST(count) = ST(i);
   857				    count++;
   858				}
   859			    }
   860			    SvREFCNT_dec(av);
   861			    XSRETURN(count);
   862			}
   863			
   864			#endif                          /* USE_ATTIBUTES_FOR_PERLIO */
   865			
   866			SV *
   867			PerlIO_tab_sv(pTHX_ PerlIO_funcs *tab)
   868	          73    {
   869	          73        HV *stash = gv_stashpv("PerlIO::Layer", TRUE);
   870	          73        SV *sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))), stash);
   871	          73        return sv;
   872			}
   873			
   874			XS(XS_PerlIO__Layer__NoWarnings)
   875	          11    {
   876			    /* This is used as a %SIG{__WARN__} handler to supress warnings
   877			       during loading of layers.
   878			     */
   879	          11        dXSARGS;
   880	          11        if (items)
   881	          11        	PerlIO_debug("warning:%s\n",SvPV_nolen_const(ST(0)));
   882	          11        XSRETURN(0);
   883			}
   884			
   885			XS(XS_PerlIO__Layer__find)
   886	          76    {
   887	          76        dXSARGS;
   888	          76        if (items < 2)
   889	      ######    	Perl_croak(aTHX_ "Usage class->find(name[,load])");
   890			    else {
   891	          76    	STRLEN len;
   892	          76    	const char *name = SvPV_const(ST(1), len);
   893	          76    	const bool load = (items > 2) ? SvTRUE(ST(2)) : 0;
   894	          76    	PerlIO_funcs *layer = PerlIO_find_layer(aTHX_ name, len, load);
   895	          76    	ST(0) =
   896				    (layer) ? sv_2mortal(PerlIO_tab_sv(aTHX_ layer)) :
   897				    &PL_sv_undef;
   898	          76    	XSRETURN(1);
   899			    }
   900			}
   901			
   902			void
   903			PerlIO_define_layer(pTHX_ PerlIO_funcs *tab)
   904	       40562    {
   905	       40562        if (!PL_known_layers)
   906	        4503    	PL_known_layers = PerlIO_list_alloc(aTHX);
   907	       40562        PerlIO_list_push(aTHX_ PL_known_layers, tab, Nullsv);
   908	       40562        PerlIO_debug("define %s %p\n", tab->name, (void*)tab);
   909			}
   910			
   911			int
   912			PerlIO_parse_layers(pTHX_ PerlIO_list_t *av, const char *names)
   913	        1135    {
   914	        1135        if (names) {
   915	        1135    	const char *s = names;
   916	        2302    	while (*s) {
   917	        1587    	    while (isSPACE(*s) || *s == ':')
   918	         406    		s++;
   919	        1181    	    if (*s) {
   920	        1181    		STRLEN llen = 0;
   921	        1181    		const char *e = s;
   922	        1181    		const char *as = Nullch;
   923	        1181    		STRLEN alen = 0;
   924	        1181    		if (!isIDFIRST(*s)) {
   925					    /*
   926					     * Message is consistent with how attribute lists are
   927					     * passed. Even though this means "foo : : bar" is
   928					     * seen as an invalid separator character.
   929					     */
   930	           5    		    const char q = ((*s == '\'') ? '"' : '\'');
   931	           5    		    if (ckWARN(WARN_LAYER))
   932	           4    			Perl_warner(aTHX_ packWARN(WARN_LAYER),
   933						      "Invalid separator character %c%c%c in PerlIO layer specification %s",
   934						      q, *s, q, s);
   935	           5    		    SETERRNO(EINVAL, LIB_INVARG);
   936	           5    		    return -1;
   937					}
   938	        5109    		do {
   939	        5109    		    e++;
   940	        5109    		} while (isALNUM(*e));
   941	        1176    		llen = e - s;
   942	        1176    		if (*e == '(') {
   943	         116    		    int nesting = 1;
   944	         116    		    as = ++e;
   945	        1113    		    while (nesting) {
   946	         999    			switch (*e++) {
   947						case ')':
   948	         114    			    if (--nesting == 0)
   949	         114    				alen = (e - 1) - as;
   950	         114    			    break;
   951						case '(':
   952	      ######    			    ++nesting;
   953	      ######    			    break;
   954						case '\\':
   955						    /*
   956						     * It's a nul terminated string, not allowed
   957						     * to \ the terminating null. Anything other
   958						     * character is passed over.
   959						     */
   960	      ######    			    if (*e++) {
   961	      ######    				break;
   962						    }
   963						    /*
   964						     * Drop through
   965						     */
   966						case '\0':
   967	           2    			    e--;
   968	           2    			    if (ckWARN(WARN_LAYER))
   969	           1    				Perl_warner(aTHX_ packWARN(WARN_LAYER),
   970							      "Argument list not closed for PerlIO layer \"%.*s\"",
   971							      (int) (e - s), s);
   972	           2    			    return -1;
   973						default:
   974						    /*
   975						     * boring.
   976						     */
   977	        1174    			    break;
   978						}
   979					    }
   980					}
   981	        1174    		if (e > s) {
   982	        1174    		    const bool warn_layer = ckWARN(WARN_LAYER);
   983	        1174    		    PerlIO_funcs *layer =
   984	        1174    			PerlIO_find_layer(aTHX_ s, llen, 1);
   985	        1174    		    if (layer) {
   986	        1167    			PerlIO_list_push(aTHX_ av, layer,
   987								 (as) ? newSVpvn(as,
   988										 alen) :
   989								 &PL_sv_undef);
   990					    }
   991					    else {
   992	           7    			if (warn_layer)
   993	           5    			    Perl_warner(aTHX_ packWARN(WARN_LAYER), "Unknown PerlIO layer \"%.*s\"",
   994							  (int) llen, s);
   995	           7    			return -1;
   996					    }
   997					}
   998	        1167    		s = e;
   999				    }
  1000				}
  1001			    }
  1002	        1121        return 0;
  1003			}
  1004			
  1005			void
  1006			PerlIO_default_buffer(pTHX_ PerlIO_list_t *av)
  1007	        4503    {
  1008	        4503        PERLIO_FUNCS_DECL(*tab) = &PerlIO_perlio;
  1009			#ifdef PERLIO_USING_CRLF
  1010			    tab = &PerlIO_crlf;
  1011			#else
  1012	        4503        if (PerlIO_stdio.Set_ptrcnt)
  1013	      ######    	tab = &PerlIO_stdio;
  1014			#endif
  1015	        4503        PerlIO_debug("Pushing %s\n", tab->name);
  1016	        4503        PerlIO_list_push(aTHX_ av, PerlIO_find_layer(aTHX_ tab->name, 0, 0),
  1017					     &PL_sv_undef);
  1018			}
  1019			
  1020			SV *
  1021			PerlIO_arg_fetch(PerlIO_list_t *av, IV n)
  1022	      153733    {
  1023	      153733        return av->array[n].arg;
  1024			}
  1025			
  1026			PerlIO_funcs *
  1027			PerlIO_layer_fetch(pTHX_ PerlIO_list_t *av, IV n, PerlIO_funcs *def)
  1028	      251883    {
  1029	      251883        if (n >= 0 && n < av->cur) {
  1030	      251883    	PerlIO_debug("Layer %" IVdf " is %s\n", n,
  1031					     av->array[n].funcs->name);
  1032	      251883    	return av->array[n].funcs;
  1033			    }
  1034	      ######        if (!def)
  1035	      ######    	Perl_croak(aTHX_ "panic: PerlIO layer array corrupt");
  1036	      ######        return def;
  1037			}
  1038			
  1039			IV
  1040			PerlIOPop_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  1041	           1    {
  1042	           1        PERL_UNUSED_ARG(mode);
  1043	           1        PERL_UNUSED_ARG(arg);
  1044	           1        PERL_UNUSED_ARG(tab);
  1045	           1        if (PerlIOValid(f)) {
  1046	           1    	PerlIO_flush(f);
  1047	           1    	PerlIO_pop(aTHX_ f);
  1048	           1    	return 0;
  1049			    }
  1050	      ######        return -1;
  1051			}
  1052			
  1053			PERLIO_FUNCS_DECL(PerlIO_remove) = {
  1054			    sizeof(PerlIO_funcs),
  1055			    "pop",
  1056			    0,
  1057			    PERLIO_K_DUMMY | PERLIO_K_UTF8,
  1058			    PerlIOPop_pushed,
  1059			    NULL,
  1060			    NULL,
  1061			    NULL,
  1062			    NULL,
  1063			    NULL,
  1064			    NULL,
  1065			    NULL,
  1066			    NULL,
  1067			    NULL,
  1068			    NULL,
  1069			    NULL,
  1070			    NULL,
  1071			    NULL,                       /* flush */
  1072			    NULL,                       /* fill */
  1073			    NULL,
  1074			    NULL,
  1075			    NULL,
  1076			    NULL,
  1077			    NULL,                       /* get_base */
  1078			    NULL,                       /* get_bufsiz */
  1079			    NULL,                       /* get_ptr */
  1080			    NULL,                       /* get_cnt */
  1081			    NULL,                       /* set_ptrcnt */
  1082			};
  1083			
  1084			PerlIO_list_t *
  1085			PerlIO_default_layers(pTHX)
  1086	      167492    {
  1087	      167492        if (!PL_def_layerlist) {
  1088	        4503    	const char *s = (PL_tainting) ? Nullch : PerlEnv_getenv("PERLIO");
  1089	        4503    	PERLIO_FUNCS_DECL(*osLayer) = &PerlIO_unix;
  1090	        4503    	PL_def_layerlist = PerlIO_list_alloc(aTHX);
  1091	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_unix));
  1092			#if defined(WIN32)
  1093				PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_win32));
  1094			#if 0
  1095				osLayer = &PerlIO_win32;
  1096			#endif
  1097			#endif
  1098	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_raw));
  1099	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_perlio));
  1100	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_stdio));
  1101	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_crlf));
  1102			#ifdef HAS_MMAP
  1103	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_mmap));
  1104			#endif
  1105	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_utf8));
  1106	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_remove));
  1107	        4503    	PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_byte));
  1108	        4503    	PerlIO_list_push(aTHX_ PL_def_layerlist,
  1109						 PerlIO_find_layer(aTHX_ osLayer->name, 0, 0),
  1110						 &PL_sv_undef);
  1111	        4503    	if (s) {
  1112	      ######    	    PerlIO_parse_layers(aTHX_ PL_def_layerlist, s);
  1113				}
  1114				else {
  1115	        4503    	    PerlIO_default_buffer(aTHX_ PL_def_layerlist);
  1116				}
  1117			    }
  1118	      167492        if (PL_def_layerlist->cur < 2) {
  1119	      ######    	PerlIO_default_buffer(aTHX_ PL_def_layerlist);
  1120			    }
  1121	      167492        return PL_def_layerlist;
  1122			}
  1123			
  1124			void
  1125			Perl_boot_core_PerlIO(pTHX)
  1126	        4500    {
  1127			#ifdef USE_ATTRIBUTES_FOR_PERLIO
  1128			    newXS("io::MODIFY_SCALAR_ATTRIBUTES", XS_io_MODIFY_SCALAR_ATTRIBUTES,
  1129				  __FILE__);
  1130			#endif
  1131	        4500        newXS("PerlIO::Layer::find", XS_PerlIO__Layer__find, __FILE__);
  1132	        4500        newXS("PerlIO::Layer::NoWarnings", XS_PerlIO__Layer__NoWarnings, __FILE__);
  1133			}
  1134			
  1135			PerlIO_funcs *
  1136			PerlIO_default_layer(pTHX_ I32 n)
  1137	       83305    {
  1138	       83305        PerlIO_list_t *av = PerlIO_default_layers(aTHX);
  1139	       83305        if (n < 0)
  1140	      ######    	n += av->cur;
  1141	       83305        return PerlIO_layer_fetch(aTHX_ av, n, PERLIO_FUNCS_CAST(&PerlIO_stdio));
  1142			}
  1143			
  1144			#define PerlIO_default_top() PerlIO_default_layer(aTHX_ -1)
  1145			#define PerlIO_default_btm() PerlIO_default_layer(aTHX_ 0)
  1146			
  1147			void
  1148			PerlIO_stdstreams(pTHX)
  1149	        4503    {
  1150	        4503        if (!PL_perlio) {
  1151	        4503    	PerlIO_allocate(aTHX);
  1152	        4503    	PerlIO_fdopen(0, "Ir" PERLIO_STDTEXT);
  1153	        4503    	PerlIO_fdopen(1, "Iw" PERLIO_STDTEXT);
  1154	        4503    	PerlIO_fdopen(2, "Iw" PERLIO_STDTEXT);
  1155			    }
  1156			}
  1157			
  1158			PerlIO *
  1159			PerlIO_push(pTHX_ PerlIO *f, PERLIO_FUNCS_DECL(*tab), const char *mode, SV *arg)
  1160	      167931    {
  1161	      167931        if (tab->fsize != sizeof(PerlIO_funcs)) {
  1162			      mismatch:
  1163	      ######    	Perl_croak(aTHX_ "Layer does not match this perl");
  1164			    }
  1165	      167931        if (tab->size) {
  1166	      156622    	PerlIOl *l;
  1167	      156622    	if (tab->size < sizeof(PerlIOl)) {
  1168	      ######    	    goto mismatch;
  1169				}
  1170				/* Real layer with a data area */
  1171	      156622    	Newc('L',l,tab->size,char,PerlIOl);
  1172	      156622    	if (l && f) {
  1173	      156622    	    Zero(l, tab->size, char);
  1174	      156622    	    l->next = *f;
  1175	      156622    	    l->tab = (PerlIO_funcs*) tab;
  1176	      156622    	    *f = l;
  1177	      156622    	    PerlIO_debug("PerlIO_push f=%p %s %s %p\n", (void*)f, tab->name,
  1178						(mode) ? mode : "(Null)", (void*)arg);
  1179	      156622    	    if (*l->tab->Pushed &&
  1180					(*l->tab->Pushed) (aTHX_ f, mode, arg, (PerlIO_funcs*) tab) != 0) {
  1181	           7    		PerlIO_pop(aTHX_ f);
  1182	           7    		return NULL;
  1183				    }
  1184				}
  1185			    }
  1186	       11309        else if (f) {
  1187				/* Pseudo-layer where push does its own stack adjust */
  1188	       11309    	PerlIO_debug("PerlIO_push f=%p %s %s %p\n", (void*)f, tab->name,
  1189					     (mode) ? mode : "(Null)", (void*)arg);
  1190	       11309    	if (tab->Pushed &&
  1191				    (*tab->Pushed) (aTHX_ f, mode, arg, (PerlIO_funcs*) tab) != 0) {
  1192	      ######    	     return NULL;
  1193				}
  1194			    }
  1195	      167924        return f;
  1196			}
  1197			
  1198			IV
  1199			PerlIOBase_binmode(pTHX_ PerlIO *f)
  1200	       20668    {
  1201	       20668       if (PerlIOValid(f)) {
  1202				/* Is layer suitable for raw stream ? */
  1203	       20668    	if (PerlIOBase(f)->tab->kind & PERLIO_K_RAW) {
  1204				    /* Yes - turn off UTF-8-ness, to undo UTF-8 locale effects */
  1205	       20668    	    PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
  1206				}
  1207				else {
  1208				    /* Not suitable - pop it */
  1209	      ######    	    PerlIO_pop(aTHX_ f);
  1210				}
  1211	       20668    	return 0;
  1212			   }
  1213	      ######       return -1;
  1214			}
  1215			
  1216			IV
  1217			PerlIORaw_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  1218	       10333    {
  1219	       10333        PERL_UNUSED_ARG(mode);
  1220	       10333        PERL_UNUSED_ARG(arg);
  1221	       10333        PERL_UNUSED_ARG(tab);
  1222			
  1223	       10333        if (PerlIOValid(f)) {
  1224	       10333    	PerlIO *t;
  1225	       10333    	const PerlIOl *l;
  1226	       10333    	PerlIO_flush(f);
  1227				/*
  1228				 * Strip all layers that are not suitable for a raw stream
  1229				 */
  1230	       10333    	t = f;
  1231	       31014    	while (t && (l = *t)) {
  1232	       20681    	    if (l->tab->Binmode) {
  1233					/* Has a handler - normal case */
  1234	       20671    		if ((*l->tab->Binmode)(aTHX_ f) == 0) {
  1235	       20671    		    if (*t == l) {
  1236						/* Layer still there - move down a layer */
  1237	       20668    			t = PerlIONext(t);
  1238					    }
  1239					}
  1240					else {
  1241	      ######    		    return -1;
  1242					}
  1243				    }
  1244				    else {
  1245					/* No handler - pop it */
  1246	          10    		PerlIO_pop(aTHX_ t);
  1247				    }
  1248				}
  1249	       10333    	if (PerlIOValid(f)) {
  1250	       10333    	    PerlIO_debug(":raw f=%p :%s\n", (void*)f, PerlIOBase(f)->tab->name);
  1251	       10333    	    return 0;
  1252				}
  1253			    }
  1254	      ######        return -1;
  1255			}
  1256			
  1257			int
  1258			PerlIO_apply_layera(pTHX_ PerlIO *f, const char *mode,
  1259					    PerlIO_list_t *layers, IV n, IV max)
  1260	        1036    {
  1261	        1036        int code = 0;
  1262	        2102        while (n < max) {
  1263	        1066    	PerlIO_funcs * const tab = PerlIO_layer_fetch(aTHX_ layers, n, NULL);
  1264	        1066    	if (tab) {
  1265	        1066    	    if (!PerlIO_push(aTHX_ f, tab, mode, PerlIOArg)) {
  1266	      ######    		code = -1;
  1267	      ######    		break;
  1268				    }
  1269				}
  1270	        1066    	n++;
  1271			    }
  1272	        1036        return code;
  1273			}
  1274			
  1275			int
  1276			PerlIO_apply_layers(pTHX_ PerlIO *f, const char *mode, const char *names)
  1277	         992    {
  1278	         992        int code = 0;
  1279	         992        if (f && names) {
  1280	         992    	PerlIO_list_t * const layers = PerlIO_list_alloc(aTHX);
  1281	         992    	code = PerlIO_parse_layers(aTHX_ layers, names);
  1282	         992    	if (code == 0) {
  1283	         990    	    code = PerlIO_apply_layera(aTHX_ f, mode, layers, 0, layers->cur);
  1284				}
  1285	         992    	PerlIO_list_free(aTHX_ layers);
  1286			    }
  1287	         992        return code;
  1288			}
  1289			
  1290			
  1291			/*--------------------------------------------------------------------------------------*/
  1292			/*
  1293			 * Given the abstraction above the public API functions
  1294			 */
  1295			
  1296			int
  1297			PerlIO_binmode(pTHX_ PerlIO *f, int iotype, int mode, const char *names)
  1298	       11276    {
  1299	       11276        PerlIO_debug("PerlIO_binmode f=%p %s %c %x %s\n",
  1300					 (void*)f, PerlIOBase(f)->tab->name, iotype, mode,
  1301					 (names) ? names : "(Null)");
  1302	       11276        if (names) {
  1303				/* Do not flush etc. if (e.g.) switching encodings.
  1304				   if a pushed layer knows it needs to flush lower layers
  1305				   (for example :unix which is never going to call them)
  1306				   it can do the flush when it is pushed.
  1307				 */
  1308	         983    	return PerlIO_apply_layers(aTHX_ f, NULL, names) == 0 ? TRUE : FALSE;
  1309			    }
  1310			    else {
  1311				/* Fake 5.6 legacy of using this call to turn ON O_TEXT */
  1312			#ifdef PERLIO_USING_CRLF
  1313				/* Legacy binmode only has meaning if O_TEXT has a value distinct from
  1314				   O_BINARY so we can look for it in mode.
  1315				 */
  1316				if (!(mode & O_BINARY)) {
  1317				    /* Text mode */
  1318				    /* FIXME?: Looking down the layer stack seems wrong,
  1319				       but is a way of reaching past (say) an encoding layer
  1320				       to flip CRLF-ness of the layer(s) below
  1321				     */
  1322				    while (*f) {
  1323					/* Perhaps we should turn on bottom-most aware layer
  1324					   e.g. Ilya's idea that UNIX TTY could serve
  1325					 */
  1326					if (PerlIOBase(f)->tab->kind & PERLIO_K_CANCRLF) {
  1327					    if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF)) {
  1328						/* Not in text mode - flush any pending stuff and flip it */
  1329						PerlIO_flush(f);
  1330						PerlIOBase(f)->flags |= PERLIO_F_CRLF;
  1331					    }
  1332					    /* Only need to turn it on in one layer so we are done */
  1333					    return TRUE;
  1334					}
  1335					f = PerlIONext(f);
  1336				    }
  1337				    /* Not finding a CRLF aware layer presumably means we are binary
  1338				       which is not what was requested - so we failed
  1339				       We _could_ push :crlf layer but so could caller
  1340				     */
  1341				    return FALSE;
  1342				}
  1343			#endif
  1344				/* Legacy binmode is now _defined_ as being equivalent to pushing :raw
  1345				   So code that used to be here is now in PerlIORaw_pushed().
  1346				 */
  1347	       10293    	return PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_raw), Nullch, Nullsv) ? TRUE : FALSE;
  1348			    }
  1349			}
  1350			
  1351			int
  1352			PerlIO__close(pTHX_ PerlIO *f)
  1353	       78959    {
  1354	       78959        if (PerlIOValid(f)) {
  1355	       78958    	PerlIO_funcs *tab = PerlIOBase(f)->tab;
  1356	       78958    	if (tab && tab->Close)
  1357	       78958    	    return (*tab->Close)(aTHX_ f);
  1358				else
  1359	      ######    	    return PerlIOBase_close(aTHX_ f);
  1360			    }
  1361			    else {
  1362	           1    	SETERRNO(EBADF, SS_IVCHAN);
  1363	           1    	return -1;
  1364			    }
  1365			}
  1366			
  1367			int
  1368			Perl_PerlIO_close(pTHX_ PerlIO *f)
  1369	       78959    {
  1370	       78959        const int code = PerlIO__close(aTHX_ f);
  1371	      236001        while (PerlIOValid(f)) {
  1372	      157042    	PerlIO_pop(aTHX_ f);
  1373			    }
  1374	       78959        return code;
  1375			}
  1376			
  1377			int
  1378			Perl_PerlIO_fileno(pTHX_ PerlIO *f)
  1379	      400431    {
  1380	      400431         Perl_PerlIO_or_Base(f, Fileno, fileno, -1, (aTHX_ f));
  1381			}
  1382			
  1383			static const char *
  1384			PerlIO_context_layers(pTHX_ const char *mode)
  1385	       82959    {
  1386	       82959        const char *type = NULL;
  1387			    /*
  1388			     * Need to supply default layer info from open.pm
  1389			     */
  1390	       82959        if (PL_curcop) {
  1391	       82959    	SV *layers = PL_curcop->cop_io;
  1392	       82959    	if (layers) {
  1393	           7    	    STRLEN len;
  1394	           7    	    type = SvPV_const(layers, len);
  1395	           7    	    if (type && mode[0] != 'r') {
  1396					/*
  1397					 * Skip to write part
  1398					 */
  1399	           3    		const char *s = strchr(type, 0);
  1400	           3    		if (s && (STRLEN)(s - type) < len) {
  1401	           3    		    type = s + 1;
  1402					}
  1403				    }
  1404				}
  1405			    }
  1406	       82959        return type;
  1407			}
  1408			
  1409			static PerlIO_funcs *
  1410			PerlIO_layer_from_ref(pTHX_ SV *sv)
  1411	         937    {
  1412			    /*
  1413			     * For any scalar type load the handler which is bundled with perl
  1414			     */
  1415	         937        if (SvTYPE(sv) < SVt_PVAV)
  1416	         937    	return PerlIO_find_layer(aTHX_ "scalar", 6, 1);
  1417			
  1418			    /*
  1419			     * For other types allow if layer is known but don't try and load it
  1420			     */
  1421	      ######        switch (SvTYPE(sv)) {
  1422			    case SVt_PVAV:
  1423	      ######    	return PerlIO_find_layer(aTHX_ "Array", 5, 0);
  1424			    case SVt_PVHV:
  1425	      ######    	return PerlIO_find_layer(aTHX_ "Hash", 4, 0);
  1426			    case SVt_PVCV:
  1427	      ######    	return PerlIO_find_layer(aTHX_ "Code", 4, 0);
  1428			    case SVt_PVGV:
  1429	      ######    	return PerlIO_find_layer(aTHX_ "Glob", 4, 0);
  1430			    }
  1431	      ######        return NULL;
  1432			}
  1433			
  1434			PerlIO_list_t *
  1435			PerlIO_resolve_layers(pTHX_ const char *layers,
  1436					      const char *mode, int narg, SV **args)
  1437	       84187    {
  1438	       84187        PerlIO_list_t *def = PerlIO_default_layers(aTHX);
  1439	       84187        int incdef = 1;
  1440	       84187        if (!PL_perlio)
  1441	        4481    	PerlIO_stdstreams(aTHX);
  1442	       84187        if (narg) {
  1443	       65559    	SV *arg = *args;
  1444				/*
  1445				 * If it is a reference but not an object see if we have a handler
  1446				 * for it
  1447				 */
  1448	       65559    	if (SvROK(arg) && !sv_isobject(arg)) {
  1449	         937    	    PerlIO_funcs *handler = PerlIO_layer_from_ref(aTHX_ SvRV(arg));
  1450	         937    	    if (handler) {
  1451	         937    		def = PerlIO_list_alloc(aTHX);
  1452	         937    		PerlIO_list_push(aTHX_ def, handler, &PL_sv_undef);
  1453	         937    		incdef = 0;
  1454				    }
  1455				    /*
  1456				     * Don't fail if handler cannot be found :via(...) etc. may do
  1457				     * something sensible else we will just stringfy and open
  1458				     * resulting string.
  1459				     */
  1460				}
  1461			    }
  1462	       84187        if (!layers)
  1463	       82959    	layers = PerlIO_context_layers(aTHX_ mode);
  1464	       84187        if (layers && *layers) {
  1465	         143    	PerlIO_list_t *av;
  1466	         143    	if (incdef) {
  1467	         142    	    IV i;
  1468	         142    	    av = PerlIO_list_alloc(aTHX);
  1469	         426    	    for (i = 0; i < def->cur; i++) {
  1470	         284    		PerlIO_list_push(aTHX_ av, def->array[i].funcs,
  1471							 def->array[i].arg);
  1472				    }
  1473				}
  1474				else {
  1475	           1    	    av = def;
  1476				}
  1477	         143    	if (PerlIO_parse_layers(aTHX_ av, layers) == 0) {
  1478	         131    	     return av;
  1479				}
  1480				else {
  1481	          12    	    PerlIO_list_free(aTHX_ av);
  1482	          12    	    return (PerlIO_list_t *) NULL;
  1483				}
  1484			    }
  1485			    else {
  1486	       84044    	if (incdef)
  1487	       83108    	    def->refcnt++;
  1488	       84044    	return def;
  1489			    }
  1490			}
  1491			
  1492			PerlIO *
  1493			PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
  1494				     int imode, int perm, PerlIO *f, int narg, SV **args)
  1495	       84191    {
  1496	       84191        if (!f && narg == 1 && *args == &PL_sv_undef) {
  1497	           4    	if ((f = PerlIO_tmpfile())) {
  1498	           4    	    if (!layers)
  1499	      ######    		layers = PerlIO_context_layers(aTHX_ mode);
  1500	           4    	    if (layers && *layers)
  1501	      ######    		PerlIO_apply_layers(aTHX_ f, mode, layers);
  1502				}
  1503			    }
  1504			    else {
  1505	       84187    	PerlIO_list_t *layera;
  1506	       84187    	IV n;
  1507	       84187    	PerlIO_funcs *tab = NULL;
  1508	       84187    	if (PerlIOValid(f)) {
  1509				    /*
  1510				     * This is "reopen" - it is not tested as perl does not use it
  1511				     * yet
  1512				     */
  1513	      ######    	    PerlIOl *l = *f;
  1514	      ######    	    layera = PerlIO_list_alloc(aTHX);
  1515	      ######    	    while (l) {
  1516	      ######    		SV *arg = (l->tab->Getarg)
  1517						? (*l->tab->Getarg) (aTHX_ &l, NULL, 0)
  1518	      ######    			: &PL_sv_undef;
  1519	      ######    		PerlIO_list_push(aTHX_ layera, l->tab, arg);
  1520	      ######    		l = *PerlIONext(&l);
  1521				    }
  1522				}
  1523				else {
  1524	       84187    	    layera = PerlIO_resolve_layers(aTHX_ layers, mode, narg, args);
  1525	       84187    	    if (!layera) {
  1526	          12    		return NULL;
  1527				    }
  1528				}
  1529				/*
  1530				 * Start at "top" of layer stack
  1531				 */
  1532	       84175    	n = layera->cur - 1;
  1533	       84221    	while (n >= 0) {
  1534	       84221    	    PerlIO_funcs *t = PerlIO_layer_fetch(aTHX_ layera, n, NULL);
  1535	       84221    	    if (t && t->Open) {
  1536	       84175    		tab = t;
  1537	       84175    		break;
  1538				    }
  1539	          46    	    n--;
  1540				}
  1541	       84175    	if (tab) {
  1542				    /*
  1543				     * Found that layer 'n' can do opens - call it
  1544				     */
  1545	       84175    	    if (narg > 1 && !(tab->kind & PERLIO_K_MULTIARG)) {
  1546	      ######    		Perl_croak(aTHX_ "More than one argument to open(,':%s')",tab->name);
  1547				    }
  1548	       84175    	    PerlIO_debug("openn(%s,'%s','%s',%d,%x,%o,%p,%d,%p)\n",
  1549						 tab->name, layers, mode, fd, imode, perm,
  1550						 (void*)f, narg, (void*)args);
  1551	       84175    	    if (tab->Open)
  1552	       84175    		 f = (*tab->Open) (aTHX_ tab, layera, n, mode, fd, imode, perm,
  1553							   f, narg, args);
  1554				    else {
  1555	      ######    		 SETERRNO(EINVAL, LIB_INVARG);
  1556	      ######    		 f = NULL;
  1557				    }
  1558	       84175    	    if (f) {
  1559	       77237    		if (n + 1 < layera->cur) {
  1560					    /*
  1561					     * More layers above the one that we used to open -
  1562					     * apply them now
  1563					     */
  1564	          46    		    if (PerlIO_apply_layera(aTHX_ f, mode, layera, n + 1, layera->cur) != 0) {
  1565						/* If pushing layers fails close the file */
  1566	      ######    			PerlIO_close(f);
  1567	      ######    			f = NULL;
  1568					    }
  1569					}
  1570				    }
  1571				}
  1572	       84175    	PerlIO_list_free(aTHX_ layera);
  1573			    }
  1574	       84179        return f;
  1575			}
  1576			
  1577			
  1578			SSize_t
  1579			Perl_PerlIO_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
  1580	      508610    {
  1581	      508610         Perl_PerlIO_or_Base(f, Read, read, -1, (aTHX_ f, vbuf, count));
  1582			}
  1583			
  1584			SSize_t
  1585			Perl_PerlIO_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  1586	        7437    {
  1587	        7437         Perl_PerlIO_or_Base(f, Unread, unread, -1, (aTHX_ f, vbuf, count));
  1588			}
  1589			
  1590			SSize_t
  1591			Perl_PerlIO_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  1592	     1318615    {
  1593	     1318615         Perl_PerlIO_or_fail(f, Write, -1, (aTHX_ f, vbuf, count));
  1594			}
  1595			
  1596			int
  1597			Perl_PerlIO_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
  1598	       77937    {
  1599	       77937         Perl_PerlIO_or_fail(f, Seek, -1, (aTHX_ f, offset, whence));
  1600			}
  1601			
  1602			Off_t
  1603			Perl_PerlIO_tell(pTHX_ PerlIO *f)
  1604	     1886891    {
  1605	     1886891         Perl_PerlIO_or_fail(f, Tell, -1, (aTHX_ f));
  1606			}
  1607			
  1608			int
  1609			Perl_PerlIO_flush(pTHX_ PerlIO *f)
  1610	     1113344    {
  1611	     1113344        if (f) {
  1612	     1104217    	if (*f) {
  1613	     1104213    	    const PerlIO_funcs *tab = PerlIOBase(f)->tab;
  1614			
  1615	     1104213    	    if (tab && tab->Flush)
  1616	     1104213    		return (*tab->Flush) (aTHX_ f);
  1617				    else
  1618	      ######    		 return 0; /* If no Flush defined, silently succeed. */
  1619				}
  1620				else {
  1621	           4    	    PerlIO_debug("Cannot flush f=%p\n", (void*)f);
  1622	           4    	    SETERRNO(EBADF, SS_IVCHAN);
  1623	           4    	    return -1;
  1624				}
  1625			    }
  1626			    else {
  1627				/*
  1628				 * Is it good API design to do flush-all on NULL, a potentially
  1629				 * errorneous input? Maybe some magical value (PerlIO*
  1630				 * PERLIO_FLUSH_ALL = (PerlIO*)-1;)? Yes, stdio does similar
  1631				 * things on fflush(NULL), but should we be bound by their design
  1632				 * decisions? --jhi
  1633				 */
  1634	        9127    	PerlIO **table = &PL_perlio;
  1635	        9127    	int code = 0;
  1636	       18251    	while ((f = *table)) {
  1637	        9124    	    int i;
  1638	        9124    	    table = (PerlIO **) (f++);
  1639	      583936    	    for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
  1640	      574812    		if (*f && PerlIO_flush(f) != 0)
  1641	      ######    		    code = -1;
  1642	      574812    		f++;
  1643				    }
  1644				}
  1645	        9127    	return code;
  1646			    }
  1647			}
  1648			
  1649			void
  1650			PerlIOBase_flush_linebuf(pTHX)
  1651	           9    {
  1652	           9        PerlIO **table = &PL_perlio;
  1653	          18        PerlIO *f;
  1654	          18        while ((f = *table)) {
  1655	           9    	int i;
  1656	           9    	table = (PerlIO **) (f++);
  1657	         576    	for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
  1658	         567    	    if (*f
  1659					&& (PerlIOBase(f)->
  1660					    flags & (PERLIO_F_LINEBUF | PERLIO_F_CANWRITE))
  1661					== (PERLIO_F_LINEBUF | PERLIO_F_CANWRITE))
  1662	          13    		PerlIO_flush(f);
  1663	         567    	    f++;
  1664				}
  1665			    }
  1666			}
  1667			
  1668			int
  1669			Perl_PerlIO_fill(pTHX_ PerlIO *f)
  1670	      244516    {
  1671	      244516         Perl_PerlIO_or_fail(f, Fill, -1, (aTHX_ f));
  1672			}
  1673			
  1674			int
  1675			PerlIO_isutf8(PerlIO *f)
  1676	    13412227    {
  1677	    13412227         if (PerlIOValid(f))
  1678	    13412227    	  return (PerlIOBase(f)->flags & PERLIO_F_UTF8) != 0;
  1679			     else
  1680	      ######    	  SETERRNO(EBADF, SS_IVCHAN);
  1681			
  1682	      ######         return -1;
  1683			}
  1684			
  1685			int
  1686			Perl_PerlIO_eof(pTHX_ PerlIO *f)
  1687	        3749    {
  1688	        3749         Perl_PerlIO_or_Base(f, Eof, eof, -1, (aTHX_ f));
  1689			}
  1690			
  1691			int
  1692			Perl_PerlIO_error(pTHX_ PerlIO *f)
  1693	     1207558    {
  1694	     1207558         Perl_PerlIO_or_Base(f, Error, error, -1, (aTHX_ f));
  1695			}
  1696			
  1697			void
  1698			Perl_PerlIO_clearerr(pTHX_ PerlIO *f)
  1699	        7760    {
  1700	        7760         Perl_PerlIO_or_Base_void(f, Clearerr, clearerr, (aTHX_ f));
  1701			}
  1702			
  1703			void
  1704			Perl_PerlIO_setlinebuf(pTHX_ PerlIO *f)
  1705	      ######    {
  1706	      ######         Perl_PerlIO_or_Base_void(f, Setlinebuf, setlinebuf, (aTHX_ f));
  1707			}
  1708			
  1709			int
  1710			PerlIO_has_base(PerlIO *f)
  1711	          11    {
  1712	          11         if (PerlIOValid(f)) {
  1713	          11              const PerlIO_funcs *tab = PerlIOBase(f)->tab;
  1714			
  1715	          11    	  if (tab)
  1716	          11    	       return (tab->Get_base != NULL);
  1717	      ######    	  SETERRNO(EINVAL, LIB_INVARG);
  1718			     }
  1719			     else
  1720	      ######    	  SETERRNO(EBADF, SS_IVCHAN);
  1721			
  1722	      ######         return 0;
  1723			}
  1724			
  1725			int
  1726			PerlIO_fast_gets(PerlIO *f)
  1727	    11376159    {
  1728	    11376159        if (PerlIOValid(f) && (PerlIOBase(f)->flags & PERLIO_F_FASTGETS)) {
  1729	    11132035    	 const PerlIO_funcs *tab = PerlIOBase(f)->tab;
  1730			
  1731	    11132035    	 if (tab)
  1732	    11132035    	      return (tab->Set_ptrcnt != NULL);
  1733	      ######    	 SETERRNO(EINVAL, LIB_INVARG);
  1734			    }
  1735			    else
  1736	      244124    	 SETERRNO(EBADF, SS_IVCHAN);
  1737			
  1738	      244124        return 0;
  1739			}
  1740			
  1741			int
  1742			PerlIO_has_cntptr(PerlIO *f)
  1743	        1575    {
  1744	        1575        if (PerlIOValid(f)) {
  1745	        1575    	const PerlIO_funcs *tab = PerlIOBase(f)->tab;
  1746			
  1747	        1575    	if (tab)
  1748	        1575    	     return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
  1749	      ######    	  SETERRNO(EINVAL, LIB_INVARG);
  1750			    }
  1751			    else
  1752	      ######    	 SETERRNO(EBADF, SS_IVCHAN);
  1753			
  1754	      ######        return 0;
  1755			}
  1756			
  1757			int
  1758			PerlIO_canset_cnt(PerlIO *f)
  1759	          49    {
  1760	          49        if (PerlIOValid(f)) {
  1761	          49    	  const PerlIO_funcs *tab = PerlIOBase(f)->tab;
  1762			
  1763	          49    	  if (tab)
  1764	          49    	       return (tab->Set_ptrcnt != NULL);
  1765	      ######    	  SETERRNO(EINVAL, LIB_INVARG);
  1766			    }
  1767			    else
  1768	      ######    	 SETERRNO(EBADF, SS_IVCHAN);
  1769			
  1770	      ######        return 0;
  1771			}
  1772			
  1773			STDCHAR *
  1774			Perl_PerlIO_get_base(pTHX_ PerlIO *f)
  1775	      351986    {
  1776	      351986         Perl_PerlIO_or_fail(f, Get_base, NULL, (aTHX_ f));
  1777			}
  1778			
  1779			int
  1780			Perl_PerlIO_get_bufsiz(pTHX_ PerlIO *f)
  1781	           9    {
  1782	           9         Perl_PerlIO_or_fail(f, Get_bufsiz, -1, (aTHX_ f));
  1783			}
  1784			
  1785			STDCHAR *
  1786			Perl_PerlIO_get_ptr(pTHX_ PerlIO *f)
  1787	    11606560    {
  1788	    11606560         Perl_PerlIO_or_fail(f, Get_ptr, NULL, (aTHX_ f));
  1789			}
  1790			
  1791			int
  1792			Perl_PerlIO_get_cnt(pTHX_ PerlIO *f)
  1793	    23412647    {
  1794	    23412647         Perl_PerlIO_or_fail(f, Get_cnt, -1, (aTHX_ f));
  1795			}
  1796			
  1797			void
  1798			Perl_PerlIO_set_cnt(pTHX_ PerlIO *f, int cnt)
  1799	      ######    {
  1800	      ######         Perl_PerlIO_or_fail_void(f, Set_ptrcnt, (aTHX_ f, NULL, cnt));
  1801			}
  1802			
  1803			void
  1804			Perl_PerlIO_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, int cnt)
  1805	    11606552    {
  1806	    11606552         Perl_PerlIO_or_fail_void(f, Set_ptrcnt, (aTHX_ f, ptr, cnt));
  1807			}
  1808			
  1809			
  1810			/*--------------------------------------------------------------------------------------*/
  1811			/*
  1812			 * utf8 and raw dummy layers
  1813			 */
  1814			
  1815			IV
  1816			PerlIOUtf8_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  1817	         975    {
  1818	         975        PERL_UNUSED_ARG(mode);
  1819	         975        PERL_UNUSED_ARG(arg);
  1820	         975        if (PerlIOValid(f)) {
  1821	         975    	if (tab->kind & PERLIO_K_UTF8)
  1822	         911    	    PerlIOBase(f)->flags |= PERLIO_F_UTF8;
  1823				else
  1824	          64    	    PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
  1825	         975    	return 0;
  1826			    }
  1827	      ######        return -1;
  1828			}
  1829			
  1830			PERLIO_FUNCS_DECL(PerlIO_utf8) = {
  1831			    sizeof(PerlIO_funcs),
  1832			    "utf8",
  1833			    0,
  1834			    PERLIO_K_DUMMY | PERLIO_K_UTF8,
  1835			    PerlIOUtf8_pushed,
  1836			    NULL,
  1837			    NULL,
  1838			    NULL,
  1839			    NULL,
  1840			    NULL,
  1841			    NULL,
  1842			    NULL,
  1843			    NULL,
  1844			    NULL,
  1845			    NULL,
  1846			    NULL,
  1847			    NULL,
  1848			    NULL,                       /* flush */
  1849			    NULL,                       /* fill */
  1850			    NULL,
  1851			    NULL,
  1852			    NULL,
  1853			    NULL,
  1854			    NULL,                       /* get_base */
  1855			    NULL,                       /* get_bufsiz */
  1856			    NULL,                       /* get_ptr */
  1857			    NULL,                       /* get_cnt */
  1858			    NULL,                       /* set_ptrcnt */
  1859			};
  1860			
  1861			PERLIO_FUNCS_DECL(PerlIO_byte) = {
  1862			    sizeof(PerlIO_funcs),
  1863			    "bytes",
  1864			    0,
  1865			    PERLIO_K_DUMMY,
  1866			    PerlIOUtf8_pushed,
  1867			    NULL,
  1868			    NULL,
  1869			    NULL,
  1870			    NULL,
  1871			    NULL,
  1872			    NULL,
  1873			    NULL,
  1874			    NULL,
  1875			    NULL,
  1876			    NULL,
  1877			    NULL,
  1878			    NULL,
  1879			    NULL,                       /* flush */
  1880			    NULL,                       /* fill */
  1881			    NULL,
  1882			    NULL,
  1883			    NULL,
  1884			    NULL,
  1885			    NULL,                       /* get_base */
  1886			    NULL,                       /* get_bufsiz */
  1887			    NULL,                       /* get_ptr */
  1888			    NULL,                       /* get_cnt */
  1889			    NULL,                       /* set_ptrcnt */
  1890			};
  1891			
  1892			PerlIO *
  1893			PerlIORaw_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
  1894				       IV n, const char *mode, int fd, int imode, int perm,
  1895				       PerlIO *old, int narg, SV **args)
  1896	          19    {
  1897	          19        PerlIO_funcs * const tab = PerlIO_default_btm();
  1898	          19        PERL_UNUSED_ARG(self);
  1899	          19        if (tab && tab->Open)
  1900	          19    	 return (*tab->Open) (aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
  1901						      old, narg, args);
  1902	      ######        SETERRNO(EINVAL, LIB_INVARG);
  1903	      ######        return NULL;
  1904			}
  1905			
  1906			PERLIO_FUNCS_DECL(PerlIO_raw) = {
  1907			    sizeof(PerlIO_funcs),
  1908			    "raw",
  1909			    0,
  1910			    PERLIO_K_DUMMY,
  1911			    PerlIORaw_pushed,
  1912			    PerlIOBase_popped,
  1913			    PerlIORaw_open,
  1914			    NULL,
  1915			    NULL,
  1916			    NULL,
  1917			    NULL,
  1918			    NULL,
  1919			    NULL,
  1920			    NULL,
  1921			    NULL,
  1922			    NULL,
  1923			    NULL,
  1924			    NULL,                       /* flush */
  1925			    NULL,                       /* fill */
  1926			    NULL,
  1927			    NULL,
  1928			    NULL,
  1929			    NULL,
  1930			    NULL,                       /* get_base */
  1931			    NULL,                       /* get_bufsiz */
  1932			    NULL,                       /* get_ptr */
  1933			    NULL,                       /* get_cnt */
  1934			    NULL,                       /* set_ptrcnt */
  1935			};
  1936			/*--------------------------------------------------------------------------------------*/
  1937			/*--------------------------------------------------------------------------------------*/
  1938			/*
  1939			 * "Methods" of the "base class"
  1940			 */
  1941			
  1942			IV
  1943			PerlIOBase_fileno(pTHX_ PerlIO *f)
  1944	      199852    {
  1945	      199852        return PerlIOValid(f) ? PerlIO_fileno(PerlIONext(f)) : -1;
  1946			}
  1947			
  1948			char *
  1949			PerlIO_modestr(PerlIO * f, char *buf)
  1950	        2967    {
  1951	        2967        char *s = buf;
  1952	        2967        if (PerlIOValid(f)) {
  1953	        2967    	const IV flags = PerlIOBase(f)->flags;
  1954	        2967    	if (flags & PERLIO_F_APPEND) {
  1955	      ######    	    *s++ = 'a';
  1956	      ######    	    if (flags & PERLIO_F_CANREAD) {
  1957	      ######    		*s++ = '+';
  1958				    }
  1959				}
  1960	        2967    	else if (flags & PERLIO_F_CANREAD) {
  1961	          11    	    *s++ = 'r';
  1962	          11    	    if (flags & PERLIO_F_CANWRITE)
  1963	           1    		*s++ = '+';
  1964				}
  1965	        2956    	else if (flags & PERLIO_F_CANWRITE) {
  1966	        2956    	    *s++ = 'w';
  1967	        2956    	    if (flags & PERLIO_F_CANREAD) {
  1968	      ######    		*s++ = '+';
  1969				    }
  1970				}
  1971			#ifdef PERLIO_USING_CRLF
  1972				if (!(flags & PERLIO_F_CRLF))
  1973				    *s++ = 'b';
  1974			#endif
  1975			    }
  1976	        2967        *s = '\0';
  1977	        2967        return buf;
  1978			}
  1979			
  1980			
  1981			IV
  1982			PerlIOBase_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  1983	      156622    {
  1984	      156622        PerlIOl * const l = PerlIOBase(f);
  1985	      156622        PERL_UNUSED_ARG(arg);
  1986			
  1987	      156622        l->flags &= ~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE |
  1988					  PERLIO_F_TRUNCATE | PERLIO_F_APPEND);
  1989	      156622        if (tab->Set_ptrcnt != NULL)
  1990	       78835    	l->flags |= PERLIO_F_FASTGETS;
  1991	      156622        if (mode) {
  1992	      156572    	if (*mode == IoTYPE_NUMERIC || *mode == IoTYPE_IMPLICIT)
  1993	       16557    	    mode++;
  1994	      156572    	switch (*mode++) {
  1995				case 'r':
  1996	      120356    	    l->flags |= PERLIO_F_CANREAD;
  1997	      120356    	    break;
  1998				case 'a':
  1999	          75    	    l->flags |= PERLIO_F_APPEND | PERLIO_F_CANWRITE;
  2000	          75    	    break;
  2001				case 'w':
  2002	       36141    	    l->flags |= PERLIO_F_TRUNCATE | PERLIO_F_CANWRITE;
  2003	       36141    	    break;
  2004				default:
  2005	      ######    	    SETERRNO(EINVAL, LIB_INVARG);
  2006	      ######    	    return -1;
  2007				}
  2008	      162650    	while (*mode) {
  2009	        6078    	    switch (*mode++) {
  2010				    case '+':
  2011	        6078    		l->flags |= PERLIO_F_CANREAD | PERLIO_F_CANWRITE;
  2012	        6078    		break;
  2013				    case 'b':
  2014	      ######    		l->flags &= ~PERLIO_F_CRLF;
  2015	      ######    		break;
  2016				    case 't':
  2017	      ######    		l->flags |= PERLIO_F_CRLF;
  2018	      ######    		break;
  2019				    default:
  2020	      ######    		SETERRNO(EINVAL, LIB_INVARG);
  2021	      ######    		return -1;
  2022				    }
  2023				}
  2024			    }
  2025			    else {
  2026	          50    	if (l->next) {
  2027	          50    	    l->flags |= l->next->flags &
  2028					(PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_TRUNCATE |
  2029					 PERLIO_F_APPEND);
  2030				}
  2031			    }
  2032			#if 0
  2033			    PerlIO_debug("PerlIOBase_pushed f=%p %s %s fl=%08" UVxf " (%s)\n",
  2034					 f, PerlIOBase(f)->tab->name, (omode) ? omode : "(Null)",
  2035					 l->flags, PerlIO_modestr(f, temp));
  2036			#endif
  2037	      156622        return 0;
  2038			}
  2039			
  2040			IV
  2041			PerlIOBase_popped(pTHX_ PerlIO *f)
  2042	      156040    {
  2043	      156040        PERL_UNUSED_ARG(f);
  2044	      156040        return 0;
  2045			}
  2046			
  2047			SSize_t
  2048			PerlIOBase_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  2049	      ######    {
  2050			    /*
  2051			     * Save the position as current head considers it
  2052			     */
  2053	      ######        const Off_t old = PerlIO_tell(f);
  2054	      ######        PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_pending), "r", Nullsv);
  2055	      ######        PerlIOSelf(f, PerlIOBuf)->posn = old;
  2056	      ######        return PerlIOBuf_unread(aTHX_ f, vbuf, count);
  2057			}
  2058			
  2059			SSize_t
  2060			PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
  2061	      264479    {
  2062	      264479        STDCHAR *buf = (STDCHAR *) vbuf;
  2063	      264479        if (f) {
  2064	      264479            if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD)) {
  2065	          10    	    PerlIOBase(f)->flags |= PERLIO_F_ERROR;
  2066	          10    	    SETERRNO(EBADF, SS_IVCHAN);
  2067	          10    	    return 0;
  2068				}
  2069	      693017    	while (count > 0) {
  2070	      468517    	    SSize_t avail = PerlIO_get_cnt(f);
  2071	      468517    	    SSize_t take = 0;
  2072	      468517    	    if (avail > 0)
  2073	      232910    		take = ((SSize_t)count < avail) ? count : avail;
  2074	      468517    	    if (take > 0) {
  2075	      232910    		STDCHAR *ptr = PerlIO_get_ptr(f);
  2076	      232910    		Copy(ptr, buf, take, STDCHAR);
  2077	      232910    		PerlIO_set_ptrcnt(f, ptr + take, (avail -= take));
  2078	      232910    		count -= take;
  2079	      232910    		buf += take;
  2080				    }
  2081	      468517    	    if (count > 0 && avail <= 0) {
  2082	      244341    		if (PerlIO_fill(f) != 0)
  2083	      264468    		    break;
  2084				    }
  2085				}
  2086	      264468    	return (buf - (STDCHAR *) vbuf);
  2087			    }
  2088	      ######        return 0;
  2089			}
  2090			
  2091			IV
  2092			PerlIOBase_noop_ok(pTHX_ PerlIO *f)
  2093	      550317    {
  2094	      550317        PERL_UNUSED_ARG(f);
  2095	      550317        return 0;
  2096			}
  2097			
  2098			IV
  2099			PerlIOBase_noop_fail(pTHX_ PerlIO *f)
  2100	      ######    {
  2101	      ######        PERL_UNUSED_ARG(f);
  2102	      ######        return -1;
  2103			}
  2104			
  2105			IV
  2106			PerlIOBase_close(pTHX_ PerlIO *f)
  2107	       79018    {
  2108	       79018        IV code = -1;
  2109	       79018        if (PerlIOValid(f)) {
  2110	       79018    	PerlIO *n = PerlIONext(f);
  2111	       79018    	code = PerlIO_flush(f);
  2112	       79018    	PerlIOBase(f)->flags &=
  2113				   ~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_OPEN);
  2114	       79018    	while (PerlIOValid(n)) {
  2115	       78080    	    const PerlIO_funcs * const tab = PerlIOBase(n)->tab;
  2116	       78080    	    if (tab && tab->Close) {
  2117	       78080    		if ((*tab->Close)(aTHX_ n) != 0)
  2118	           2    		    code = -1;
  2119	           2    		break;
  2120				    }
  2121				    else {
  2122	      ######    		PerlIOBase(n)->flags &=
  2123					    ~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_OPEN);
  2124				    }
  2125	      ######    	    n = PerlIONext(n);
  2126				}
  2127			    }
  2128			    else {
  2129	      ######    	SETERRNO(EBADF, SS_IVCHAN);
  2130			    }
  2131	       79018        return code;
  2132			}
  2133			
  2134			IV
  2135			PerlIOBase_eof(pTHX_ PerlIO *f)
  2136	        3749    {
  2137	        3749        if (PerlIOValid(f)) {
  2138	        3749    	return (PerlIOBase(f)->flags & PERLIO_F_EOF) != 0;
  2139			    }
  2140	      ######        return 1;
  2141			}
  2142			
  2143			IV
  2144			PerlIOBase_error(pTHX_ PerlIO *f)
  2145	     1207557    {
  2146	     1207557        if (PerlIOValid(f)) {
  2147	     1207557    	return (PerlIOBase(f)->flags & PERLIO_F_ERROR) != 0;
  2148			    }
  2149	      ######        return 1;
  2150			}
  2151			
  2152			void
  2153			PerlIOBase_clearerr(pTHX_ PerlIO *f)
  2154	        7760    {
  2155	        7760        if (PerlIOValid(f)) {
  2156	        7760    	PerlIO *n = PerlIONext(f);
  2157	        7760    	PerlIOBase(f)->flags &= ~(PERLIO_F_ERROR | PERLIO_F_EOF);
  2158	        7760    	if (PerlIOValid(n))
  2159	        3891    	    PerlIO_clearerr(n);
  2160			    }
  2161			}
  2162			
  2163			void
  2164			PerlIOBase_setlinebuf(pTHX_ PerlIO *f)
  2165	      ######    {
  2166	      ######        if (PerlIOValid(f)) {
  2167	      ######    	PerlIOBase(f)->flags |= PERLIO_F_LINEBUF;
  2168			    }
  2169			}
  2170			
  2171			SV *
  2172			PerlIO_sv_dup(pTHX_ SV *arg, CLONE_PARAMS *param)
  2173	           2    {
  2174	           2        if (!arg)
  2175	      ######    	return Nullsv;
  2176			#ifdef sv_dup
  2177			    if (param) {
  2178				return sv_dup(arg, param);
  2179			    }
  2180			    else {
  2181				return newSVsv(arg);
  2182			    }
  2183			#else
  2184	           2        PERL_UNUSED_ARG(param);
  2185	           2        return newSVsv(arg);
  2186			#endif
  2187			}
  2188			
  2189			PerlIO *
  2190			PerlIOBase_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
  2191	        2967    {
  2192	        2967        PerlIO * const nexto = PerlIONext(o);
  2193	        2967        if (PerlIOValid(nexto)) {
  2194	        1484    	const PerlIO_funcs * const tab = PerlIOBase(nexto)->tab;
  2195	        1484    	if (tab && tab->Dup)
  2196	        1484    	    f = (*tab->Dup)(aTHX_ f, nexto, param, flags);
  2197				else
  2198	      ######    	    f = PerlIOBase_dup(aTHX_ f, nexto, param, flags);
  2199			    }
  2200	        2967        if (f) {
  2201	        2967    	PerlIO_funcs *self = PerlIOBase(o)->tab;
  2202	        2967    	SV *arg;
  2203	        2967    	char buf[8];
  2204	        2967    	PerlIO_debug("PerlIOBase_dup %s f=%p o=%p param=%p\n",
  2205					     self->name, (void*)f, (void*)o, (void*)param);
  2206	        2967    	if (self->Getarg)
  2207	           3    	    arg = (*self->Getarg)(aTHX_ o, param, flags);
  2208				else {
  2209	        2964    	    arg = Nullsv;
  2210				}
  2211	        2967    	f = PerlIO_push(aTHX_ f, self, PerlIO_modestr(o,buf), arg);
  2212	        2967    	if (arg) {
  2213	           3    	    SvREFCNT_dec(arg);
  2214				}
  2215			    }
  2216	        2967        return f;
  2217			}
  2218			
  2219			#ifdef USE_THREADS
  2220			perl_mutex PerlIO_mutex;
  2221			#endif
  2222			
  2223			/* PL_perlio_fd_refcnt[] is in intrpvar.h */
  2224			
  2225			void
  2226			PerlIO_init(pTHX)
  2227	        4503    {
  2228			 /* Place holder for stdstreams call ??? */
  2229			#ifdef USE_THREADS
  2230			    MUTEX_INIT(&PerlIO_mutex);
  2231			#endif
  2232			}
  2233			
  2234			void
  2235			PerlIOUnix_refcnt_inc(int fd)
  2236	       91433    {
  2237			    dTHX;
  2238	       91433        if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) {
  2239			#ifdef USE_THREADS
  2240				MUTEX_LOCK(&PerlIO_mutex);
  2241			#endif
  2242	       91433    	PL_perlio_fd_refcnt[fd]++;
  2243	       91433    	PerlIO_debug("fd %d refcnt=%d\n",fd,PL_perlio_fd_refcnt[fd]);
  2244			#ifdef USE_THREADS
  2245				MUTEX_UNLOCK(&PerlIO_mutex);
  2246			#endif
  2247			    }
  2248			}
  2249			
  2250			int
  2251			PerlIOUnix_refcnt_dec(int fd)
  2252	       91667    {
  2253			    dTHX;
  2254	       91667        int cnt = 0;
  2255	       91667        if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) {
  2256			#ifdef USE_THREADS
  2257				MUTEX_LOCK(&PerlIO_mutex);
  2258			#endif
  2259	       91667    	cnt = --PL_perlio_fd_refcnt[fd];
  2260	       91667    	PerlIO_debug("fd %d refcnt=%d\n",fd,cnt);
  2261			#ifdef USE_THREADS
  2262				MUTEX_UNLOCK(&PerlIO_mutex);
  2263			#endif
  2264			    }
  2265	       91667        return cnt;
  2266			}
  2267			
  2268			void
  2269			PerlIO_cleanup(pTHX)
  2270	        4549    {
  2271	        4549        int i;
  2272			#ifdef USE_ITHREADS
  2273			    PerlIO_debug("Cleanup layers for %p\n",aTHX);
  2274			#else
  2275	        4549        PerlIO_debug("Cleanup layers\n");
  2276			#endif
  2277			    /* Raise STDIN..STDERR refcount so we don't close them */
  2278	       18196        for (i=0; i < 3; i++)
  2279	       13647    	PerlIOUnix_refcnt_inc(i);
  2280	        4549        PerlIO_cleantable(aTHX_ &PL_perlio);
  2281			    /* Restore STDIN..STDERR refcount */
  2282	       18196        for (i=0; i < 3; i++)
  2283	       13647    	PerlIOUnix_refcnt_dec(i);
  2284			
  2285	        4549        if (PL_known_layers) {
  2286	        4549    	PerlIO_list_free(aTHX_ PL_known_layers);
  2287	        4549    	PL_known_layers = NULL;
  2288			    }
  2289	        4549        if (PL_def_layerlist) {
  2290	        4549    	PerlIO_list_free(aTHX_ PL_def_layerlist);
  2291	        4549    	PL_def_layerlist = NULL;
  2292			    }
  2293			}
  2294			
  2295			
  2296			
  2297			/*--------------------------------------------------------------------------------------*/
  2298			/*
  2299			 * Bottom-most level for UNIX-like case
  2300			 */
  2301			
  2302			typedef struct {
  2303			    struct _PerlIO base;        /* The generic part */
  2304			    int fd;                     /* UNIX like file descriptor */
  2305			    int oflags;                 /* open/fcntl flags */
  2306			} PerlIOUnix;
  2307			
  2308			int
  2309			PerlIOUnix_oflags(const char *mode)
  2310	       61552    {
  2311	       61552        int oflags = -1;
  2312	       61552        if (*mode == IoTYPE_IMPLICIT || *mode == IoTYPE_NUMERIC)
  2313	      ######    	mode++;
  2314	       61552        switch (*mode) {
  2315			    case 'r':
  2316	       55112    	oflags = O_RDONLY;
  2317	       55112    	if (*++mode == '+') {
  2318	           3    	    oflags = O_RDWR;
  2319	           3    	    mode++;
  2320				}
  2321	           3    	break;
  2322			
  2323			    case 'w':
  2324	        6402    	oflags = O_CREAT | O_TRUNC;
  2325	        6402    	if (*++mode == '+') {
  2326	           8    	    oflags |= O_RDWR;
  2327	           8    	    mode++;
  2328				}
  2329				else
  2330	        6394    	    oflags |= O_WRONLY;
  2331	        6394    	break;
  2332			
  2333			    case 'a':
  2334	          38    	oflags = O_CREAT | O_APPEND;
  2335	          38    	if (*++mode == '+') {
  2336	           1    	    oflags |= O_RDWR;
  2337	           1    	    mode++;
  2338				}
  2339				else
  2340	          37    	    oflags |= O_WRONLY;
  2341				break;
  2342			    }
  2343	       61552        if (*mode == 'b') {
  2344	      ######    	oflags |= O_BINARY;
  2345	      ######    	oflags &= ~O_TEXT;
  2346	      ######    	mode++;
  2347			    }
  2348	       61552        else if (*mode == 't') {
  2349	      ######    	oflags |= O_TEXT;
  2350	      ######    	oflags &= ~O_BINARY;
  2351	      ######    	mode++;
  2352			    }
  2353			    /*
  2354			     * Always open in binary mode
  2355			     */
  2356	       61552        oflags |= O_BINARY;
  2357	       61552        if (*mode || oflags == -1) {
  2358	      ######    	SETERRNO(EINVAL, LIB_INVARG);
  2359	      ######    	oflags = -1;
  2360			    }
  2361	       61552        return oflags;
  2362			}
  2363			
  2364			IV
  2365			PerlIOUnix_fileno(pTHX_ PerlIO *f)
  2366	      199630    {
  2367	      199630        return PerlIOSelf(f, PerlIOUnix)->fd;
  2368			}
  2369			
  2370			static void
  2371			PerlIOUnix_setfd(pTHX_ PerlIO *f, int fd, int imode)
  2372	       77786    {
  2373	       77786        PerlIOUnix * const s = PerlIOSelf(f, PerlIOUnix);
  2374			#if defined(WIN32)
  2375			    Stat_t st;
  2376			    if (PerlLIO_fstat(fd, &st) == 0) {
  2377				if (!S_ISREG(st.st_mode)) {
  2378				    PerlIO_debug("%d is not regular file\n",fd);
  2379			    	    PerlIOBase(f)->flags |= PERLIO_F_NOTREG;
  2380				}
  2381				else {
  2382				    PerlIO_debug("%d _is_ a regular file\n",fd);
  2383				}
  2384			    }
  2385			#endif
  2386	       77786        s->fd = fd;
  2387	       77786        s->oflags = imode;
  2388	       77786        PerlIOUnix_refcnt_inc(fd);
  2389			}
  2390			
  2391			IV
  2392			PerlIOUnix_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  2393	       77786    {
  2394	       77786        IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
  2395	       77786        if (*PerlIONext(f)) {
  2396				/* We never call down so do any pending stuff now */
  2397	           2    	PerlIO_flush(PerlIONext(f));
  2398				/*
  2399				 * XXX could (or should) we retrieve the oflags from the open file
  2400				 * handle rather than believing the "mode" we are passed in? XXX
  2401				 * Should the value on NULL mode be 0 or -1?
  2402				 */
  2403	           2            PerlIOUnix_setfd(aTHX_ f, PerlIO_fileno(PerlIONext(f)),
  2404			                         mode ? PerlIOUnix_oflags(mode) : -1);
  2405			    }
  2406	       77786        PerlIOBase(f)->flags |= PERLIO_F_OPEN;
  2407			
  2408	       77786        return code;
  2409			}
  2410			
  2411			IV
  2412			PerlIOUnix_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
  2413	       48925    {
  2414	       48925        const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
  2415	       48925        Off_t new_loc;
  2416	       48925        if (PerlIOBase(f)->flags & PERLIO_F_NOTREG) {
  2417			#ifdef  ESPIPE
  2418	      ######    	SETERRNO(ESPIPE, LIB_INVARG);
  2419			#else
  2420				SETERRNO(EINVAL, LIB_INVARG);
  2421			#endif
  2422	      ######    	return -1;
  2423			    }
  2424	       48925        new_loc = PerlLIO_lseek(fd, offset, whence);
  2425	       48925        if (new_loc == (Off_t) - 1)
  2426			     {
  2427	          12          return -1;
  2428			     }
  2429	       48913        PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
  2430	       48913        return  0;
  2431			}
  2432			
  2433			PerlIO *
  2434			PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
  2435					IV n, const char *mode, int fd, int imode,
  2436					int perm, PerlIO *f, int narg, SV **args)
  2437	       83233    {
  2438	       83233        if (PerlIOValid(f)) {
  2439	      ######    	if (PerlIOBase(f)->flags & PERLIO_F_OPEN)
  2440	      ######    	    (*PerlIOBase(f)->tab->Close)(aTHX_ f);
  2441			    }
  2442	       83233        if (narg > 0) {
  2443	       64605    	if (*mode == IoTYPE_NUMERIC)
  2444	        3053    	    mode++;
  2445				else {
  2446	       61552    	    imode = PerlIOUnix_oflags(mode);
  2447	       61552    	    perm = 0666;
  2448				}
  2449	       64605    	if (imode != -1) {
  2450	       64605    	    const char *path = SvPV_nolen_const(*args);
  2451	       64605    	    fd = PerlLIO_open3(path, imode, perm);
  2452				}
  2453			    }
  2454	       83233        if (fd >= 0) {
  2455	       76302    	if (*mode == IoTYPE_IMPLICIT)
  2456	       13509    	    mode++;
  2457	       76302    	if (!f) {
  2458	       76298    	    f = PerlIO_allocate(aTHX);
  2459				}
  2460	       76302    	if (!PerlIOValid(f)) {
  2461	       76302    	    if (!(f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg))) {
  2462	      ######    		return NULL;
  2463				    }
  2464				}
  2465	       76302            PerlIOUnix_setfd(aTHX_ f, fd, imode);
  2466	       76302    	PerlIOBase(f)->flags |= PERLIO_F_OPEN;
  2467	       76302    	if (*mode == IoTYPE_APPEND)
  2468	          37    	    PerlIOUnix_seek(aTHX_ f, 0, SEEK_END);
  2469	       76302    	return f;
  2470			    }
  2471			    else {
  2472	        6931    	if (f) {
  2473				    /*
  2474				     * FIXME: pop layers ???
  2475				     */
  2476				}
  2477	        6931    	return NULL;
  2478			    }
  2479			}
  2480			
  2481			PerlIO *
  2482			PerlIOUnix_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
  2483	        1482    {
  2484	        1482        PerlIOUnix *os = PerlIOSelf(o, PerlIOUnix);
  2485	        1482        int fd = os->fd;
  2486	        1482        if (flags & PERLIO_DUP_FD) {
  2487	        1477    	fd = PerlLIO_dup(fd);
  2488			    }
  2489	        1482        if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) {
  2490	        1482    	f = PerlIOBase_dup(aTHX_ f, o, param, flags);
  2491	        1482    	if (f) {
  2492				    /* If all went well overwrite fd in dup'ed lay with the dup()'ed fd */
  2493	        1482    	    PerlIOUnix_setfd(aTHX_ f, fd, os->oflags);
  2494	        1482    	    return f;
  2495				}
  2496			    }
  2497	      ######        return NULL;
  2498			}
  2499			
  2500			
  2501			SSize_t
  2502			PerlIOUnix_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
  2503	      244131    {
  2504	      244131        const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
  2505			#ifdef PERLIO_STD_SPECIAL
  2506			    if (fd == 0)
  2507			        return PERLIO_STD_IN(fd, vbuf, count);
  2508			#endif
  2509	      244131        if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD) ||
  2510			         PerlIOBase(f)->flags & (PERLIO_F_EOF|PERLIO_F_ERROR)) {
  2511	        2173    	return 0;
  2512			    }
  2513	      241958        while (1) {
  2514	      241958    	const SSize_t len = PerlLIO_read(fd, vbuf, count);
  2515	      241958    	if (len >= 0 || errno != EINTR) {
  2516	      241957    	    if (len < 0) {
  2517	           2    		if (errno != EAGAIN) {
  2518	           2    		    PerlIOBase(f)->flags |= PERLIO_F_ERROR;
  2519					}
  2520				    }
  2521	      241955    	    else if (len == 0 && count != 0) {
  2522	       37784    		PerlIOBase(f)->flags |= PERLIO_F_EOF;
  2523	       37784    		SETERRNO(0,0);
  2524				    }
  2525	      241957    	    return len;
  2526				}
  2527	           1    	PERL_ASYNC_CHECK();
  2528			    }
  2529			    /*NOTREACHED*/
  2530			}
  2531			
  2532			SSize_t
  2533			PerlIOUnix_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  2534	      146040    {
  2535	      146040        const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
  2536			#ifdef PERLIO_STD_SPECIAL
  2537			    if (fd == 1 || fd == 2)
  2538			        return PERLIO_STD_OUT(fd, vbuf, count);
  2539			#endif
  2540	      146040        while (1) {
  2541	      146040    	const SSize_t len = PerlLIO_write(fd, vbuf, count);
  2542	      146040    	if (len >= 0 || errno != EINTR) {
  2543	      146040    	    if (len < 0) {
  2544	           3    		if (errno != EAGAIN) {
  2545	           3    		    PerlIOBase(f)->flags |= PERLIO_F_ERROR;
  2546					}
  2547				    }
  2548	      146040    	    return len;
  2549				}
  2550	      ######    	PERL_ASYNC_CHECK();
  2551			    }
  2552			    /*NOTREACHED*/
  2553			}
  2554			
  2555			Off_t
  2556			PerlIOUnix_tell(pTHX_ PerlIO *f)
  2557	      126660    {
  2558	      126660        return PerlLIO_lseek(PerlIOSelf(f, PerlIOUnix)->fd, 0, SEEK_CUR);
  2559			}
  2560			
  2561			
  2562			IV
  2563			PerlIOUnix_close(pTHX_ PerlIO *f)
  2564	       78020    {
  2565	       78020        const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
  2566	       78020        int code = 0;
  2567	       78020        if (PerlIOBase(f)->flags & PERLIO_F_OPEN) {
  2568	       78020    	if (PerlIOUnix_refcnt_dec(fd) > 0) {
  2569	       14269    	    PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
  2570	       14269    	    return 0;
  2571				}
  2572			    }
  2573			    else {
  2574	      ######    	SETERRNO(EBADF,SS_IVCHAN);
  2575	      ######    	return -1;
  2576			    }
  2577	       63751        while (PerlLIO_close(fd) != 0) {
  2578	           2    	if (errno != EINTR) {
  2579	           2    	    code = -1;
  2580	           2    	    break;
  2581				}
  2582	      ######    	PERL_ASYNC_CHECK();
  2583			    }
  2584	       63751        if (code == 0) {
  2585	       63749    	PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
  2586			    }
  2587	       63751        return code;
  2588			}
  2589			
  2590			PERLIO_FUNCS_DECL(PerlIO_unix) = {
  2591			    sizeof(PerlIO_funcs),
  2592			    "unix",
  2593			    sizeof(PerlIOUnix),
  2594			    PERLIO_K_RAW,
  2595			    PerlIOUnix_pushed,
  2596			    PerlIOBase_popped,
  2597			    PerlIOUnix_open,
  2598			    PerlIOBase_binmode,         /* binmode */
  2599			    NULL,
  2600			    PerlIOUnix_fileno,
  2601			    PerlIOUnix_dup,
  2602			    PerlIOUnix_read,
  2603			    PerlIOBase_unread,
  2604			    PerlIOUnix_write,
  2605			    PerlIOUnix_seek,
  2606			    PerlIOUnix_tell,
  2607			    PerlIOUnix_close,
  2608			    PerlIOBase_noop_ok,         /* flush */
  2609			    PerlIOBase_noop_fail,       /* fill */
  2610			    PerlIOBase_eof,
  2611			    PerlIOBase_error,
  2612			    PerlIOBase_clearerr,
  2613			    PerlIOBase_setlinebuf,
  2614			    NULL,                       /* get_base */
  2615			    NULL,                       /* get_bufsiz */
  2616			    NULL,                       /* get_ptr */
  2617			    NULL,                       /* get_cnt */
  2618			    NULL,                       /* set_ptrcnt */
  2619			};
  2620			
  2621			/*--------------------------------------------------------------------------------------*/
  2622			/*
  2623			 * stdio as a layer
  2624			 */
  2625			
  2626			#if defined(VMS) && !defined(STDIO_BUFFER_WRITABLE)
  2627			/* perl5.8 - This ensures the last minute VMS ungetc fix is not
  2628			   broken by the last second glibc 2.3 fix
  2629			 */
  2630			#define STDIO_BUFFER_WRITABLE
  2631			#endif
  2632			
  2633			
  2634			typedef struct {
  2635			    struct _PerlIO base;
  2636			    FILE *stdio;                /* The stream */
  2637			} PerlIOStdio;
  2638			
  2639			IV
  2640			PerlIOStdio_fileno(pTHX_ PerlIO *f)
  2641	           1    {
  2642	           1        FILE *s;
  2643	           1        if (PerlIOValid(f) && (s = PerlIOSelf(f, PerlIOStdio)->stdio)) {
  2644	           1    	return PerlSIO_fileno(s);
  2645			    }
  2646	      ######        errno = EBADF;
  2647	      ######        return -1;
  2648			}
  2649			
  2650			char *
  2651			PerlIOStdio_mode(const char *mode, char *tmode)
  2652	      ######    {
  2653	      ######        char * const ret = tmode;
  2654	      ######        if (mode) {
  2655	      ######    	while (*mode) {
  2656	      ######    	    *tmode++ = *mode++;
  2657				}
  2658			    }
  2659			#if defined(PERLIO_USING_CRLF) || defined(__CYGWIN__)
  2660			    *tmode++ = 'b';
  2661			#endif
  2662	      ######        *tmode = '\0';
  2663	      ######        return ret;
  2664			}
  2665			
  2666			IV
  2667			PerlIOStdio_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  2668	           1    {
  2669	           1        PerlIO *n;
  2670	           1        if (PerlIOValid(f) && PerlIOValid(n = PerlIONext(f))) {
  2671	      ######            PerlIO_funcs *toptab = PerlIOBase(n)->tab;
  2672	      ######            if (toptab == tab) {
  2673				    /* Top is already stdio - pop self (duplicate) and use original */
  2674	      ######    	    PerlIO_pop(aTHX_ f);
  2675	      ######    	    return 0;
  2676				} else {
  2677	      ######    	    const int fd = PerlIO_fileno(n);
  2678	      ######    	    char tmode[8];
  2679	      ######    	    FILE *stdio;
  2680	      ######    	    if (fd >= 0 && (stdio  = PerlSIO_fdopen(fd,
  2681						    mode = PerlIOStdio_mode(mode, tmode)))) {
  2682	      ######    		PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
  2683				    	/* We never call down so do any pending stuff now */
  2684	      ######    	    	PerlIO_flush(PerlIONext(f));
  2685				    }
  2686				    else {
  2687	      ######    		return -1;
  2688				    }
  2689			        }
  2690			    }
  2691	           1        return PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
  2692			}
  2693			
  2694			
  2695			PerlIO *
  2696			PerlIO_importFILE(FILE *stdio, const char *mode)
  2697	           1    {
  2698			    dTHX;
  2699	           1        PerlIO *f = NULL;
  2700	           1        if (stdio) {
  2701	           1    	PerlIOStdio *s;
  2702	           1    	if (!mode || !*mode) {
  2703				    /* We need to probe to see how we can open the stream
  2704				       so start with read/write and then try write and read
  2705				       we dup() so that we can fclose without loosing the fd.
  2706			
  2707				       Note that the errno value set by a failing fdopen
  2708				       varies between stdio implementations.
  2709				     */
  2710	           1    	    const int fd = PerlLIO_dup(fileno(stdio));
  2711	           1    	    FILE *f2 = PerlSIO_fdopen(fd, (mode = "r+"));
  2712	           1    	    if (!f2) {
  2713	           1    		f2 = PerlSIO_fdopen(fd, (mode = "w"));
  2714				    }
  2715	           1    	    if (!f2) {
  2716	      ######    		f2 = PerlSIO_fdopen(fd, (mode = "r"));
  2717				    }
  2718	           1    	    if (!f2) {
  2719					/* Don't seem to be able to open */
  2720	      ######    		PerlLIO_close(fd);
  2721	      ######    		return f;
  2722				    }
  2723	           1    	    fclose(f2);
  2724				}
  2725	           1    	if ((f = PerlIO_push(aTHX_(f = PerlIO_allocate(aTHX)), PERLIO_FUNCS_CAST(&PerlIO_stdio), mode, Nullsv))) {
  2726	           1    	    s = PerlIOSelf(f, PerlIOStdio);
  2727	           1    	    s->stdio = stdio;
  2728				}
  2729			    }
  2730	           1        return f;
  2731			}
  2732			
  2733			PerlIO *
  2734			PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
  2735					 IV n, const char *mode, int fd, int imode,
  2736					 int perm, PerlIO *f, int narg, SV **args)
  2737	      ######    {
  2738	      ######        char tmode[8];
  2739	      ######        if (PerlIOValid(f)) {
  2740	      ######    	const char *path = SvPV_nolen_const(*args);
  2741	      ######    	PerlIOStdio *s = PerlIOSelf(f, PerlIOStdio);
  2742	      ######    	FILE *stdio;
  2743	      ######    	PerlIOUnix_refcnt_dec(fileno(s->stdio));
  2744	      ######    	stdio = PerlSIO_freopen(path, (mode = PerlIOStdio_mode(mode, tmode)),
  2745						    s->stdio);
  2746	      ######    	if (!s->stdio)
  2747	      ######    	    return NULL;
  2748	      ######    	s->stdio = stdio;
  2749	      ######    	PerlIOUnix_refcnt_inc(fileno(s->stdio));
  2750	      ######    	return f;
  2751			    }
  2752			    else {
  2753	      ######    	if (narg > 0) {
  2754	      ######    	    const char *path = SvPV_nolen_const(*args);
  2755	      ######    	    if (*mode == IoTYPE_NUMERIC) {
  2756	      ######    		mode++;
  2757	      ######    		fd = PerlLIO_open3(path, imode, perm);
  2758				    }
  2759				    else {
  2760	      ######    	        FILE *stdio;
  2761	      ######    	        bool appended = FALSE;
  2762			#ifdef __CYGWIN__
  2763					/* Cygwin wants its 'b' early. */
  2764					appended = TRUE;
  2765					mode = PerlIOStdio_mode(mode, tmode);
  2766			#endif
  2767	      ######    		stdio = PerlSIO_fopen(path, mode);
  2768	      ######    		if (stdio) {
  2769	      ######    		    PerlIOStdio *s;
  2770	      ######    		    if (!f) {
  2771	      ######    			f = PerlIO_allocate(aTHX);
  2772					    }
  2773	      ######    		    if (!appended)
  2774	      ######    		        mode = PerlIOStdio_mode(mode, tmode);
  2775	      ######    		    f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg);
  2776	      ######    		    if (f) {
  2777	      ######    			s = PerlIOSelf(f, PerlIOStdio);
  2778	      ######    			s->stdio = stdio;
  2779	      ######    			PerlIOUnix_refcnt_inc(fileno(s->stdio));
  2780					    }
  2781	      ######    		    return f;
  2782					}
  2783					else {
  2784	      ######    		    return NULL;
  2785					}
  2786				    }
  2787				}
  2788	      ######    	if (fd >= 0) {
  2789	      ######    	    FILE *stdio = NULL;
  2790	      ######    	    int init = 0;
  2791	      ######    	    if (*mode == IoTYPE_IMPLICIT) {
  2792	      ######    		init = 1;
  2793	      ######    		mode++;
  2794				    }
  2795	      ######    	    if (init) {
  2796	      ######    		switch (fd) {
  2797					case 0:
  2798	      ######    		    stdio = PerlSIO_stdin;
  2799	      ######    		    break;
  2800					case 1:
  2801	      ######    		    stdio = PerlSIO_stdout;
  2802	      ######    		    break;
  2803					case 2:
  2804	      ######    		    stdio = PerlSIO_stderr;
  2805	      ######    		    break;
  2806					}
  2807				    }
  2808				    else {
  2809	      ######    		stdio = PerlSIO_fdopen(fd, mode =
  2810							       PerlIOStdio_mode(mode, tmode));
  2811				    }
  2812	      ######    	    if (stdio) {
  2813	      ######    		if (!f) {
  2814	      ######    		    f = PerlIO_allocate(aTHX);
  2815					}
  2816	      ######    		if ((f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg))) {
  2817	      ######    		    PerlIOStdio *s = PerlIOSelf(f, PerlIOStdio);
  2818	      ######    		    s->stdio = stdio;
  2819	      ######    		    PerlIOUnix_refcnt_inc(fileno(s->stdio));
  2820					}
  2821	      ######    		return f;
  2822				    }
  2823				}
  2824			    }
  2825	      ######        return NULL;
  2826			}
  2827			
  2828			PerlIO *
  2829			PerlIOStdio_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
  2830	      ######    {
  2831			    /* This assumes no layers underneath - which is what
  2832			       happens, but is not how I remember it. NI-S 2001/10/16
  2833			     */
  2834	      ######        if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
  2835	      ######    	FILE *stdio = PerlIOSelf(o, PerlIOStdio)->stdio;
  2836	      ######    	const int fd = fileno(stdio);
  2837	      ######    	char mode[8];
  2838	      ######    	if (flags & PERLIO_DUP_FD) {
  2839	      ######    	    const int dfd = PerlLIO_dup(fileno(stdio));
  2840	      ######    	    if (dfd >= 0) {
  2841	      ######    		stdio = PerlSIO_fdopen(dfd, PerlIO_modestr(o,mode));
  2842	      ######    		goto set_this;
  2843				    }
  2844				    else {
  2845					/* FIXME: To avoid messy error recovery if dup fails
  2846					   re-use the existing stdio as though flag was not set
  2847					 */
  2848				    }
  2849				}
  2850	      ######        	stdio = PerlSIO_fdopen(fd, PerlIO_modestr(o,mode));
  2851			    set_this:
  2852	      ######    	PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
  2853	      ######    	PerlIOUnix_refcnt_inc(fileno(stdio));
  2854			    }
  2855	      ######        return f;
  2856			}
  2857			
  2858			static int
  2859			PerlIOStdio_invalidate_fileno(pTHX_ FILE *f)
  2860	      ######    {
  2861			    /* XXX this could use PerlIO_canset_fileno() and
  2862			     * PerlIO_set_fileno() support from Configure
  2863			     */
  2864			#  if defined(__UCLIBC__)
  2865			    /* uClibc must come before glibc because it defines __GLIBC__ as well. */
  2866			    f->__filedes = -1;
  2867			    return 1;
  2868			#  elif defined(__GLIBC__)
  2869			    /* There may be a better way for GLIBC:
  2870			    	- libio.h defines a flag to not close() on cleanup
  2871			     */	
  2872	      ######        f->_fileno = -1;
  2873	      ######        return 1;
  2874			#  elif defined(__sun__)
  2875			#    if defined(_LP64)
  2876			    /* On solaris, if _LP64 is defined, the FILE structure is this:
  2877			     *
  2878			     *  struct FILE {
  2879			     *      long __pad[16];
  2880			     *  };
  2881			     *
  2882			     * It turns out that the fd is stored in the top 32 bits of
  2883			     * file->__pad[4]. The lower 32 bits contain flags. file->pad[5] appears
  2884			     * to contain a pointer or offset into another structure. All the
  2885			     * remaining fields are zero.
  2886			     *
  2887			     * We set the top bits to -1 (0xFFFFFFFF).
  2888			     */
  2889			    f->__pad[4] |= 0xffffffff00000000L;
  2890			    assert(fileno(f) == 0xffffffff);
  2891			#    else /* !defined(_LP64) */
  2892			    /* _file is just a unsigned char :-(
  2893			       Not clear why we dup() rather than using -1
  2894			       even if that would be treated as 0xFF - so will
  2895			       a dup fail ...
  2896			     */
  2897			    f->_file = PerlLIO_dup(fileno(f));
  2898			#    endif /* defined(_LP64) */
  2899			    return 1;
  2900			#  elif defined(__hpux)
  2901			    f->__fileH = 0xff;
  2902			    f->__fileL = 0xff;
  2903			    return 1;
  2904			   /* Next one ->_file seems to be a reasonable fallback, i.e. if
  2905			      your platform does not have special entry try this one.
  2906			      [For OSF only have confirmation for Tru64 (alpha)
  2907			      but assume other OSFs will be similar.]
  2908			    */
  2909			#  elif defined(_AIX) || defined(__osf__) || defined(__irix__)
  2910			    f->_file = -1;
  2911			    return 1;
  2912			#  elif defined(__FreeBSD__)
  2913			    /* There may be a better way on FreeBSD:
  2914			        - we could insert a dummy func in the _close function entry
  2915				f->_close = (int (*)(void *)) dummy_close;
  2916			     */
  2917			    f->_file = -1;
  2918			    return 1;
  2919			#  elif defined(__OpenBSD__)
  2920			    /* There may be a better way on OpenBSD:
  2921			        - we could insert a dummy func in the _close function entry
  2922				f->_close = (int (*)(void *)) dummy_close;
  2923			     */
  2924			    f->_file = -1;
  2925			    return 1;
  2926			#  elif defined(__EMX__)
  2927			    /* f->_flags &= ~_IOOPEN; */	/* Will leak stream->_buffer */
  2928			    f->_handle = -1;
  2929			    return 1;
  2930			#  elif defined(__CYGWIN__)
  2931			    /* There may be a better way on CYGWIN:
  2932			        - we could insert a dummy func in the _close function entry
  2933				f->_close = (int (*)(void *)) dummy_close;
  2934			     */
  2935			    f->_file = -1;
  2936			    return 1;
  2937			#  elif defined(WIN32)
  2938			#    if defined(__BORLANDC__)
  2939			    f->fd = PerlLIO_dup(fileno(f));
  2940			#    elif defined(UNDER_CE)
  2941			    /* WIN_CE does not have access to FILE internals, it hardly has FILE
  2942			       structure at all
  2943			     */
  2944			#    else
  2945			    f->_file = -1;
  2946			#    endif
  2947			    return 1;
  2948			#  else
  2949			#if 0
  2950			    /* Sarathy's code did this - we fall back to a dup/dup2 hack
  2951			       (which isn't thread safe) instead
  2952			     */
  2953			#    error "Don't know how to set FILE.fileno on your platform"
  2954			#endif
  2955			    PERL_UNUSED_ARG(f);
  2956			    return 0;
  2957			#  endif
  2958			}
  2959			
  2960			IV
  2961			PerlIOStdio_close(pTHX_ PerlIO *f)
  2962	      ######    {
  2963	      ######        FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  2964	      ######        if (!stdio) {
  2965	      ######    	errno = EBADF;
  2966	      ######    	return -1;
  2967			    }
  2968			    else {
  2969	      ######            const int fd = fileno(stdio);
  2970	      ######    	int socksfd = 0;
  2971	      ######    	int invalidate = 0;
  2972	      ######    	IV result = 0;
  2973	      ######    	int saveerr = 0;
  2974	      ######    	int dupfd = 0;
  2975			#ifdef SOCKS5_VERSION_NAME
  2976			    	/* Socks lib overrides close() but stdio isn't linked to
  2977				   that library (though we are) - so we must call close()
  2978				   on sockets on stdio's behalf.
  2979				 */
  2980			    	int optval;
  2981			    	Sock_size_t optlen = sizeof(int);
  2982			    	if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *) &optval, &optlen) == 0) {
  2983			            socksfd = 1;
  2984				    invalidate = 1;
  2985			    	}
  2986			#endif
  2987	      ######        	if (PerlIOUnix_refcnt_dec(fd) > 0) {
  2988				    /* File descriptor still in use */
  2989	      ######    	    invalidate = 1;
  2990	      ######    	    socksfd = 0;
  2991				}
  2992	      ######    	if (invalidate) {
  2993			   	    /* For STD* handles don't close the stdio at all
  2994				       this is because we have shared the FILE * too
  2995			   	     */
  2996	      ######    	    if (stdio == stdin) {
  2997				    	/* Some stdios are buggy fflush-ing inputs */
  2998	      ######    	    	return 0;
  2999				    }
  3000	      ######    	    else if (stdio == stdout || stdio == stderr) {
  3001	      ######    	    	return PerlIO_flush(f);
  3002				    }
  3003			            /* Tricky - must fclose(stdio) to free memory but not close(fd)
  3004				       Use Sarathy's trick from maint-5.6 to invalidate the
  3005				       fileno slot of the FILE *
  3006				    */
  3007	      ######    	    result = PerlIO_flush(f);
  3008	      ######    	    saveerr = errno;
  3009	      ######        	    if (!(invalidate = PerlIOStdio_invalidate_fileno(aTHX_ stdio))) {
  3010	      ######    	    	dupfd = PerlLIO_dup(fd);
  3011				    }
  3012				}
  3013	      ######            result = PerlSIO_fclose(stdio);
  3014				/* We treat error from stdio as success if we invalidated
  3015				   errno may NOT be expected EBADF
  3016				 */
  3017	      ######    	if (invalidate && result != 0) {
  3018	      ######    	    errno = saveerr;
  3019	      ######    	    result = 0;
  3020				}
  3021	      ######    	if (socksfd) {
  3022				    /* in SOCKS case let close() determine return value */
  3023	      ######    	    result = close(fd);
  3024				}
  3025	      ######    	if (dupfd) {
  3026	      ######    	    PerlLIO_dup2(dupfd,fd);
  3027	      ######    	    PerlLIO_close(dupfd);
  3028				}
  3029	      ######    	return result;
  3030			    }
  3031			}
  3032			
  3033			SSize_t
  3034			PerlIOStdio_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
  3035	      ######    {
  3036	      ######        FILE *s = PerlIOSelf(f, PerlIOStdio)->stdio;
  3037	      ######        SSize_t got = 0;
  3038	      ######        for (;;) {
  3039	      ######    	if (count == 1) {
  3040	      ######    	    STDCHAR *buf = (STDCHAR *) vbuf;
  3041				    /*
  3042				     * Perl is expecting PerlIO_getc() to fill the buffer Linux's
  3043				     * stdio does not do that for fread()
  3044				     */
  3045	      ######    	    const int ch = PerlSIO_fgetc(s);
  3046	      ######    	    if (ch != EOF) {
  3047	      ######    		*buf = ch;
  3048	      ######    		got = 1;
  3049				    }
  3050				}
  3051				else
  3052	      ######    	    got = PerlSIO_fread(vbuf, 1, count, s);
  3053	      ######    	if (got == 0 && PerlSIO_ferror(s))
  3054	      ######    	    got = -1;
  3055	      ######    	if (got >= 0 || errno != EINTR)
  3056	      ######    	    break;
  3057	      ######    	PERL_ASYNC_CHECK();
  3058	      ######    	SETERRNO(0,0);	/* just in case */
  3059			    }
  3060	      ######        return got;
  3061			}
  3062			
  3063			SSize_t
  3064			PerlIOStdio_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  3065	      ######    {
  3066	      ######        SSize_t unread = 0;
  3067	      ######        FILE *s = PerlIOSelf(f, PerlIOStdio)->stdio;
  3068			
  3069			#ifdef STDIO_BUFFER_WRITABLE
  3070			    if (PerlIO_fast_gets(f) && PerlIO_has_base(f)) {
  3071				STDCHAR *buf = ((STDCHAR *) vbuf) + count;
  3072				STDCHAR *base = PerlIO_get_base(f);
  3073				SSize_t cnt   = PerlIO_get_cnt(f);
  3074				STDCHAR *ptr  = PerlIO_get_ptr(f);
  3075				SSize_t avail = ptr - base;
  3076				if (avail > 0) {
  3077				    if (avail > count) {
  3078					avail = count;
  3079				    }
  3080				    ptr -= avail;
  3081				    Move(buf-avail,ptr,avail,STDCHAR);
  3082				    count -= avail;
  3083				    unread += avail;
  3084				    PerlIO_set_ptrcnt(f,ptr,cnt+avail);
  3085				    if (PerlSIO_feof(s) && unread >= 0)
  3086					PerlSIO_clearerr(s);
  3087				}
  3088			    }
  3089			    else
  3090			#endif
  3091	      ######        if (PerlIO_has_cntptr(f)) {
  3092				/* We can get pointer to buffer but not its base
  3093				   Do ungetc() but check chars are ending up in the
  3094				   buffer
  3095				 */
  3096	      ######    	STDCHAR *eptr = (STDCHAR*)PerlSIO_get_ptr(s);
  3097	      ######    	STDCHAR *buf = ((STDCHAR *) vbuf) + count;
  3098	      ######    	while (count > 0) {
  3099	      ######    	    const int ch = *--buf & 0xFF;
  3100	      ######    	    if (ungetc(ch,s) != ch) {
  3101					/* ungetc did not work */
  3102	      ######    		break;
  3103				    }
  3104	      ######    	    if ((STDCHAR*)PerlSIO_get_ptr(s) != --eptr || ((*eptr & 0xFF) != ch)) {
  3105					/* Did not change pointer as expected */
  3106	      ######    		fgetc(s);  /* get char back again */
  3107	      ######    		break;
  3108				    }
  3109				    /* It worked ! */
  3110	      ######    	    count--;
  3111	      ######    	    unread++;
  3112				}
  3113			    }
  3114			
  3115	      ######        if (count > 0) {
  3116	      ######    	unread += PerlIOBase_unread(aTHX_ f, vbuf, count);
  3117			    }
  3118	      ######        return unread;
  3119			}
  3120			
  3121			SSize_t
  3122			PerlIOStdio_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  3123	           1    {
  3124	           1        SSize_t got;
  3125	           1        for (;;) {
  3126	           1    	got = PerlSIO_fwrite(vbuf, 1, count,
  3127						      PerlIOSelf(f, PerlIOStdio)->stdio);
  3128	           1    	if (got >= 0 || errno != EINTR)
  3129	      ######    	    break;
  3130	      ######    	PERL_ASYNC_CHECK();
  3131	      ######    	SETERRNO(0,0);	/* just in case */
  3132			    }
  3133	           1        return got;
  3134			}
  3135			
  3136			IV
  3137			PerlIOStdio_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
  3138	      ######    {
  3139	      ######        FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3140	      ######        return PerlSIO_fseek(stdio, offset, whence);
  3141			}
  3142			
  3143			Off_t
  3144			PerlIOStdio_tell(pTHX_ PerlIO *f)
  3145	      ######    {
  3146	      ######        FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3147	      ######        return PerlSIO_ftell(stdio);
  3148			}
  3149			
  3150			IV
  3151			PerlIOStdio_flush(pTHX_ PerlIO *f)
  3152	      ######    {
  3153	      ######        FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3154	      ######        if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) {
  3155	      ######    	return PerlSIO_fflush(stdio);
  3156			    }
  3157			    else {
  3158			#if 0
  3159				/*
  3160				 * FIXME: This discards ungetc() and pre-read stuff which is not
  3161				 * right if this is just a "sync" from a layer above Suspect right
  3162				 * design is to do _this_ but not have layer above flush this
  3163				 * layer read-to-read
  3164				 */
  3165				/*
  3166				 * Not writeable - sync by attempting a seek
  3167				 */
  3168				int err = errno;
  3169				if (PerlSIO_fseek(stdio, (Off_t) 0, SEEK_CUR) != 0)
  3170				    errno = err;
  3171			#endif
  3172			    }
  3173	      ######        return 0;
  3174			}
  3175			
  3176			IV
  3177			PerlIOStdio_eof(pTHX_ PerlIO *f)
  3178	      ######    {
  3179	      ######        return PerlSIO_feof(PerlIOSelf(f, PerlIOStdio)->stdio);
  3180			}
  3181			
  3182			IV
  3183			PerlIOStdio_error(pTHX_ PerlIO *f)
  3184	           1    {
  3185	           1        return PerlSIO_ferror(PerlIOSelf(f, PerlIOStdio)->stdio);
  3186			}
  3187			
  3188			void
  3189			PerlIOStdio_clearerr(pTHX_ PerlIO *f)
  3190	      ######    {
  3191	      ######        PerlSIO_clearerr(PerlIOSelf(f, PerlIOStdio)->stdio);
  3192			}
  3193			
  3194			void
  3195			PerlIOStdio_setlinebuf(pTHX_ PerlIO *f)
  3196	      ######    {
  3197			#ifdef HAS_SETLINEBUF
  3198	      ######        PerlSIO_setlinebuf(PerlIOSelf(f, PerlIOStdio)->stdio);
  3199			#else
  3200			    PerlSIO_setvbuf(PerlIOSelf(f, PerlIOStdio)->stdio, Nullch, _IOLBF, 0);
  3201			#endif
  3202			}
  3203			
  3204			#ifdef FILE_base
  3205			STDCHAR *
  3206			PerlIOStdio_get_base(pTHX_ PerlIO *f)
  3207			{
  3208			    FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3209			    return (STDCHAR*)PerlSIO_get_base(stdio);
  3210			}
  3211			
  3212			Size_t
  3213			PerlIOStdio_get_bufsiz(pTHX_ PerlIO *f)
  3214			{
  3215			    FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3216			    return PerlSIO_get_bufsiz(stdio);
  3217			}
  3218			#endif
  3219			
  3220			#ifdef USE_STDIO_PTR
  3221			STDCHAR *
  3222			PerlIOStdio_get_ptr(pTHX_ PerlIO *f)
  3223			{
  3224			    FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3225			    return (STDCHAR*)PerlSIO_get_ptr(stdio);
  3226			}
  3227			
  3228			SSize_t
  3229			PerlIOStdio_get_cnt(pTHX_ PerlIO *f)
  3230			{
  3231			    FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3232			    return PerlSIO_get_cnt(stdio);
  3233			}
  3234			
  3235			void
  3236			PerlIOStdio_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
  3237			{
  3238			    FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3239			    if (ptr != NULL) {
  3240			#ifdef STDIO_PTR_LVALUE
  3241				PerlSIO_set_ptr(stdio, (void*)ptr); /* LHS STDCHAR* cast non-portable */
  3242			#ifdef STDIO_PTR_LVAL_SETS_CNT
  3243				if (PerlSIO_get_cnt(stdio) != (cnt)) {
  3244				    assert(PerlSIO_get_cnt(stdio) == (cnt));
  3245				}
  3246			#endif
  3247			#if (!defined(STDIO_PTR_LVAL_NOCHANGE_CNT))
  3248				/*
  3249				 * Setting ptr _does_ change cnt - we are done
  3250				 */
  3251				return;
  3252			#endif
  3253			#else                           /* STDIO_PTR_LVALUE */
  3254				PerlProc_abort();
  3255			#endif                          /* STDIO_PTR_LVALUE */
  3256			    }
  3257			    /*
  3258			     * Now (or only) set cnt
  3259			     */
  3260			#ifdef STDIO_CNT_LVALUE
  3261			    PerlSIO_set_cnt(stdio, cnt);
  3262			#else                           /* STDIO_CNT_LVALUE */
  3263			#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
  3264			    PerlSIO_set_ptr(stdio,
  3265					    PerlSIO_get_ptr(stdio) + (PerlSIO_get_cnt(stdio) -
  3266								      cnt));
  3267			#else                           /* STDIO_PTR_LVAL_SETS_CNT */
  3268			    PerlProc_abort();
  3269			#endif                          /* STDIO_PTR_LVAL_SETS_CNT */
  3270			#endif                          /* STDIO_CNT_LVALUE */
  3271			}
  3272			
  3273			
  3274			#endif
  3275			
  3276			IV
  3277			PerlIOStdio_fill(pTHX_ PerlIO *f)
  3278	      ######    {
  3279	      ######        FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  3280	      ######        int c;
  3281			    /*
  3282			     * fflush()ing read-only streams can cause trouble on some stdio-s
  3283			     */
  3284	      ######        if ((PerlIOBase(f)->flags & PERLIO_F_CANWRITE)) {
  3285	      ######    	if (PerlSIO_fflush(stdio) != 0)
  3286	      ######    	    return EOF;
  3287			    }
  3288	      ######        c = PerlSIO_fgetc(stdio);
  3289	      ######        if (c == EOF)
  3290	      ######    	return EOF;
  3291			
  3292			#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
  3293			
  3294			#ifdef STDIO_BUFFER_WRITABLE
  3295			    if (PerlIO_fast_gets(f) && PerlIO_has_base(f)) {
  3296				/* Fake ungetc() to the real buffer in case system's ungetc
  3297				   goes elsewhere
  3298				 */
  3299				STDCHAR *base = (STDCHAR*)PerlSIO_get_base(stdio);
  3300				SSize_t cnt   = PerlSIO_get_cnt(stdio);
  3301				STDCHAR *ptr  = (STDCHAR*)PerlSIO_get_ptr(stdio);
  3302				if (ptr == base+1) {
  3303				    *--ptr = (STDCHAR) c;
  3304				    PerlIOStdio_set_ptrcnt(aTHX_ f,ptr,cnt+1);
  3305				    if (PerlSIO_feof(stdio))
  3306					PerlSIO_clearerr(stdio);
  3307				    return 0;
  3308				}
  3309			    }
  3310			    else
  3311			#endif
  3312			    if (PerlIO_has_cntptr(f)) {
  3313				STDCHAR ch = c;
  3314				if (PerlIOStdio_unread(aTHX_ f,&ch,1) == 1) {
  3315				    return 0;
  3316				}
  3317			    }
  3318			#endif
  3319			
  3320			#if defined(VMS)
  3321			    /* An ungetc()d char is handled separately from the regular
  3322			     * buffer, so we stuff it in the buffer ourselves.
  3323			     * Should never get called as should hit code above
  3324			     */
  3325			    *(--((*stdio)->_ptr)) = (unsigned char) c;
  3326			    (*stdio)->_cnt++;
  3327			#else
  3328			    /* If buffer snoop scheme above fails fall back to
  3329			       using ungetc().
  3330			     */
  3331	      ######        if (PerlSIO_ungetc(c, stdio) != c)
  3332	      ######    	return EOF;
  3333			#endif
  3334	      ######        return 0;
  3335			}
  3336			
  3337			
  3338			
  3339			PERLIO_FUNCS_DECL(PerlIO_stdio) = {
  3340			    sizeof(PerlIO_funcs),
  3341			    "stdio",
  3342			    sizeof(PerlIOStdio),
  3343			    PERLIO_K_BUFFERED|PERLIO_K_RAW,
  3344			    PerlIOStdio_pushed,
  3345			    PerlIOBase_popped,
  3346			    PerlIOStdio_open,
  3347			    PerlIOBase_binmode,         /* binmode */
  3348			    NULL,
  3349			    PerlIOStdio_fileno,
  3350			    PerlIOStdio_dup,
  3351			    PerlIOStdio_read,
  3352			    PerlIOStdio_unread,
  3353			    PerlIOStdio_write,
  3354			    PerlIOStdio_seek,
  3355			    PerlIOStdio_tell,
  3356			    PerlIOStdio_close,
  3357			    PerlIOStdio_flush,
  3358			    PerlIOStdio_fill,
  3359			    PerlIOStdio_eof,
  3360			    PerlIOStdio_error,
  3361			    PerlIOStdio_clearerr,
  3362			    PerlIOStdio_setlinebuf,
  3363			#ifdef FILE_base
  3364			    PerlIOStdio_get_base,
  3365			    PerlIOStdio_get_bufsiz,
  3366			#else
  3367			    NULL,
  3368			    NULL,
  3369			#endif
  3370			#ifdef USE_STDIO_PTR
  3371			    PerlIOStdio_get_ptr,
  3372			    PerlIOStdio_get_cnt,
  3373			#   if defined(HAS_FAST_STDIO) && defined(USE_FAST_STDIO)
  3374			    PerlIOStdio_set_ptrcnt,
  3375			#   else
  3376			    NULL,
  3377			#   endif /* HAS_FAST_STDIO && USE_FAST_STDIO */
  3378			#else
  3379			    NULL,
  3380			    NULL,
  3381			    NULL,
  3382			#endif /* USE_STDIO_PTR */
  3383			};
  3384			
  3385			/* Note that calls to PerlIO_exportFILE() are reversed using
  3386			 * PerlIO_releaseFILE(), not importFILE. */
  3387			FILE *
  3388			PerlIO_exportFILE(PerlIO * f, const char *mode)
  3389	      ######    {
  3390			    dTHX;
  3391	      ######        FILE *stdio = NULL;
  3392	      ######        if (PerlIOValid(f)) {
  3393	      ######    	char buf[8];
  3394	      ######    	PerlIO_flush(f);
  3395	      ######    	if (!mode || !*mode) {
  3396	      ######    	    mode = PerlIO_modestr(f, buf);
  3397				}
  3398	      ######    	stdio = PerlSIO_fdopen(PerlIO_fileno(f), mode);
  3399	      ######    	if (stdio) {
  3400	      ######    	    PerlIOl *l = *f;
  3401	      ######    	    PerlIO *f2;
  3402				    /* De-link any lower layers so new :stdio sticks */
  3403	      ######    	    *f = NULL;
  3404	      ######    	    if ((f2 = PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_stdio), buf, Nullsv))) {
  3405	      ######    		PerlIOStdio *s = PerlIOSelf((f = f2), PerlIOStdio);
  3406	      ######    		s->stdio = stdio;
  3407					/* Link previous lower layers under new one */
  3408	      ######    		*PerlIONext(f) = l;
  3409				    }
  3410				    else {
  3411					/* restore layers list */
  3412	      ######    		*f = l;
  3413				    }
  3414				}
  3415			    }
  3416	      ######        return stdio;
  3417			}
  3418			
  3419			
  3420			FILE *
  3421			PerlIO_findFILE(PerlIO *f)
  3422	           2    {
  3423	           2        PerlIOl *l = *f;
  3424	           2        while (l) {
  3425	           2    	if (l->tab == &PerlIO_stdio) {
  3426	           2    	    PerlIOStdio *s = PerlIOSelf(&l, PerlIOStdio);
  3427	           2    	    return s->stdio;
  3428				}
  3429	      ######    	l = *PerlIONext(&l);
  3430			    }
  3431			    /* Uses fallback "mode" via PerlIO_modestr() in PerlIO_exportFILE */
  3432	      ######        return PerlIO_exportFILE(f, Nullch);
  3433			}
  3434			
  3435			/* Use this to reverse PerlIO_exportFILE calls. */
  3436			void
  3437			PerlIO_releaseFILE(PerlIO *p, FILE *f)
  3438	           1    {
  3439			    dVAR;
  3440	           1        PerlIOl *l;
  3441	           1        while ((l = *p)) {
  3442	           1    	if (l->tab == &PerlIO_stdio) {
  3443	           1    	    PerlIOStdio *s = PerlIOSelf(&l, PerlIOStdio);
  3444	           1    	    if (s->stdio == f) {
  3445					dTHX;
  3446	           1    		PerlIO_pop(aTHX_ p);
  3447	           1    		return;
  3448				    }
  3449				}
  3450	      ######    	p = PerlIONext(p);
  3451			    }
  3452	           1        return;
  3453			}
  3454			
  3455			/*--------------------------------------------------------------------------------------*/
  3456			/*
  3457			 * perlio buffer layer
  3458			 */
  3459			
  3460			IV
  3461			PerlIOBuf_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  3462	       77887    {
  3463	       77887        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3464	       77887        const int fd = PerlIO_fileno(f);
  3465	       77887        if (fd >= 0 && PerlLIO_isatty(fd)) {
  3466	        9041    	PerlIOBase(f)->flags |= PERLIO_F_LINEBUF | PERLIO_F_TTY;
  3467			    }
  3468	       77887        if (*PerlIONext(f)) {
  3469	       77887    	const Off_t posn = PerlIO_tell(PerlIONext(f));
  3470	       77887    	if (posn != (Off_t) - 1) {
  3471	       57982    	    b->posn = posn;
  3472				}
  3473			    }
  3474	       77887        return PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
  3475			}
  3476			
  3477			PerlIO *
  3478			PerlIOBuf_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
  3479				       IV n, const char *mode, int fd, int imode, int perm,
  3480				       PerlIO *f, int narg, SV **args)
  3481	       83286    {
  3482	       83286        if (PerlIOValid(f)) {
  3483	      ######    	PerlIO *next = PerlIONext(f);
  3484	      ######    	PerlIO_funcs *tab =
  3485	      ######    	     PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIOBase(next)->tab);
  3486	      ######    	if (tab && tab->Open)
  3487	      ######    	     next =
  3488					  (*tab->Open)(aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
  3489						       next, narg, args);
  3490	      ######    	if (!next || (*PerlIOBase(f)->tab->Pushed) (aTHX_ f, mode, PerlIOArg, self) != 0) {
  3491	      ######    	    return NULL;
  3492				}
  3493			    }
  3494			    else {
  3495	       83286    	PerlIO_funcs *tab = PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIO_default_btm());
  3496	       83286    	int init = 0;
  3497	       83286    	if (*mode == IoTYPE_IMPLICIT) {
  3498	       13509    	    init = 1;
  3499				    /*
  3500				     * mode++;
  3501				     */
  3502				}
  3503	       83286    	if (tab && tab->Open)
  3504	       83286    	     f = (*tab->Open)(aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
  3505						      f, narg, args);
  3506				else
  3507	      ######    	     SETERRNO(EINVAL, LIB_INVARG);
  3508	       83286    	if (f) {
  3509	       76355    	    if (PerlIO_push(aTHX_ f, self, mode, PerlIOArg) == 0) {
  3510					/*
  3511					 * if push fails during open, open fails. close will pop us.
  3512					 */
  3513	           2    		PerlIO_close (f);
  3514	           2    		return NULL;
  3515				    } else {
  3516	       76353    		fd = PerlIO_fileno(f);
  3517	       76353    		if (init && fd == 2) {
  3518					    /*
  3519					     * Initial stderr is unbuffered
  3520					     */
  3521	        4503    		    PerlIOBase(f)->flags |= PERLIO_F_UNBUF;
  3522					}
  3523			#ifdef PERLIO_USING_CRLF
  3524			#  ifdef PERLIO_IS_BINMODE_FD
  3525					if (PERLIO_IS_BINMODE_FD(fd))
  3526					    PerlIO_binmode(aTHX_ f,  '<'/*not used*/, O_BINARY, Nullch);
  3527					else
  3528			#  endif
  3529					/*
  3530					 * do something about failing setmode()? --jhi
  3531					 */
  3532					PerlLIO_setmode(fd, O_BINARY);
  3533			#endif
  3534				    }
  3535				}
  3536			    }
  3537	       83284        return f;
  3538			}
  3539			
  3540			/*
  3541			 * This "flush" is akin to sfio's sync in that it handles files in either
  3542			 * read or write state
  3543			 */
  3544			IV
  3545			PerlIOBuf_flush(pTHX_ PerlIO *f)
  3546	      550364    {
  3547	      550364        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3548	      550364        int code = 0;
  3549	      550364        PerlIO *n = PerlIONext(f);
  3550	      550364        if (PerlIOBase(f)->flags & PERLIO_F_WRBUF) {
  3551				/*
  3552				 * write() the buffer
  3553				 */
  3554	      146033    	const STDCHAR *buf = b->buf;
  3555	      146033    	const STDCHAR *p = buf;
  3556	      292063    	while (p < b->ptr) {
  3557	      146033    	    SSize_t count = PerlIO_write(n, p, b->ptr - p);
  3558	      146033    	    if (count > 0) {
  3559	      146030    		p += count;
  3560				    }
  3561	           3    	    else if (count < 0 || PerlIO_error(n)) {
  3562	           3    		PerlIOBase(f)->flags |= PERLIO_F_ERROR;
  3563	           3    		code = -1;
  3564					break;
  3565				    }
  3566				}
  3567	      146033    	b->posn += (p - buf);
  3568			    }
  3569	      404331        else if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
  3570	      288657    	STDCHAR *buf = PerlIO_get_base(f);
  3571				/*
  3572				 * Note position change
  3573				 */
  3574	      288657    	b->posn += (b->ptr - buf);
  3575	      288657    	if (b->ptr < b->end) {
  3576				    /* We did not consume all of it - try and seek downstream to
  3577				       our logical position
  3578				     */
  3579	       19849    	    if (PerlIOValid(n) && PerlIO_seek(n, b->posn, SEEK_SET) == 0) {
  3580					/* Reload n as some layers may pop themselves on seek */
  3581	       19838    		b->posn = PerlIO_tell(n = PerlIONext(f));
  3582				    }
  3583				    else {
  3584					/* Seek failed (e.g. pipe or tty). Do NOT clear buffer or pre-read
  3585					   data is lost for good - so return saying "ok" having undone
  3586					   the position adjust
  3587					 */
  3588	          11    		b->posn -= (b->ptr - buf);
  3589	          11    		return code;
  3590				    }
  3591				}
  3592			    }
  3593	      550353        b->ptr = b->end = b->buf;
  3594	      550353        PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
  3595			    /* We check for Valid because of dubious decision to make PerlIO_flush(NULL) flush all */
  3596	      550353        if (PerlIOValid(n) && PerlIO_flush(n) != 0)
  3597	      ######    	code = -1;
  3598	      550353        return code;
  3599			}
  3600			
  3601			IV
  3602			PerlIOBuf_fill(pTHX_ PerlIO *f)
  3603	      244155    {
  3604	      244155        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3605	      244155        PerlIO *n = PerlIONext(f);
  3606	      244155        SSize_t avail;
  3607			    /*
  3608			     * Down-stream flush is defined not to loose read data so is harmless.
  3609			     * we would not normally be fill'ing if there was data left in anycase.
  3610			     */
  3611	      244155        if (PerlIO_flush(f) != 0)
  3612	      ######    	return -1;
  3613	      244155        if (PerlIOBase(f)->flags & PERLIO_F_TTY)
  3614	           9    	PerlIOBase_flush_linebuf(aTHX);
  3615			
  3616	      244155        if (!b->buf)
  3617	      ######    	PerlIO_get_base(f);     /* allocate via vtable */
  3618			
  3619	      244155        b->ptr = b->end = b->buf;
  3620			
  3621	      244155        if (!PerlIOValid(n)) {
  3622	      ######    	PerlIOBase(f)->flags |= PERLIO_F_EOF;
  3623	      ######    	return -1;
  3624			    }
  3625			
  3626	      244155        if (PerlIO_fast_gets(n)) {
  3627				/*
  3628				 * Layer below is also buffered. We do _NOT_ want to call its
  3629				 * ->Read() because that will loop till it gets what we asked for
  3630				 * which may hang on a pipe etc. Instead take anything it has to
  3631				 * hand, or ask it to fill _once_.
  3632				 */
  3633	          33    	avail = PerlIO_get_cnt(n);
  3634	          33    	if (avail <= 0) {
  3635	          11    	    avail = PerlIO_fill(n);
  3636	          11    	    if (avail == 0)
  3637	           9    		avail = PerlIO_get_cnt(n);
  3638				    else {
  3639	           2    		if (!PerlIO_error(n) && PerlIO_eof(n))
  3640	           2    		    avail = 0;
  3641				    }
  3642				}
  3643	          33    	if (avail > 0) {
  3644	          31    	    STDCHAR *ptr = PerlIO_get_ptr(n);
  3645	          31    	    SSize_t cnt = avail;
  3646	          31    	    if (avail > (SSize_t)b->bufsiz)
  3647	          23    		avail = b->bufsiz;
  3648	          31    	    Copy(ptr, b->buf, avail, STDCHAR);
  3649	          31    	    PerlIO_set_ptrcnt(n, ptr + avail, cnt - avail);
  3650				}
  3651			    }
  3652			    else {
  3653	      244122    	avail = PerlIO_read(n, b->ptr, b->bufsiz);
  3654			    }
  3655	      244154        if (avail <= 0) {
  3656	       39960    	if (avail == 0)
  3657	       39958    	    PerlIOBase(f)->flags |= PERLIO_F_EOF;
  3658				else
  3659	           2    	    PerlIOBase(f)->flags |= PERLIO_F_ERROR;
  3660	       39960    	return -1;
  3661			    }
  3662	      204194        b->end = b->buf + avail;
  3663	      204194        PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
  3664	      204194        return 0;
  3665			}
  3666			
  3667			SSize_t
  3668			PerlIOBuf_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
  3669	      264464    {
  3670	      264464        if (PerlIOValid(f)) {
  3671	      264464            const PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3672	      264464    	if (!b->ptr)
  3673	        2739    	    PerlIO_get_base(f);
  3674	      264464    	return PerlIOBase_read(aTHX_ f, vbuf, count);
  3675			    }
  3676	      ######        return 0;
  3677			}
  3678			
  3679			SSize_t
  3680			PerlIOBuf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  3681	        7436    {
  3682	        7436        const STDCHAR *buf = (const STDCHAR *) vbuf + count;
  3683	        7436        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3684	        7436        SSize_t unread = 0;
  3685	        7436        SSize_t avail;
  3686	        7436        if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
  3687	      ######    	PerlIO_flush(f);
  3688	        7436        if (!b->buf)
  3689	      ######    	PerlIO_get_base(f);
  3690	        7436        if (b->buf) {
  3691	        7436    	if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
  3692				    /*
  3693				     * Buffer is already a read buffer, we can overwrite any chars
  3694				     * which have been read back to buffer start
  3695				     */
  3696	        7436    	    avail = (b->ptr - b->buf);
  3697				}
  3698				else {
  3699				    /*
  3700				     * Buffer is idle, set it up so whole buffer is available for
  3701				     * unread
  3702				     */
  3703	      ######    	    avail = b->bufsiz;
  3704	      ######    	    b->end = b->buf + avail;
  3705	      ######    	    b->ptr = b->end;
  3706	      ######    	    PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
  3707				    /*
  3708				     * Buffer extends _back_ from where we are now
  3709				     */
  3710	      ######    	    b->posn -= b->bufsiz;
  3711				}
  3712	        7436    	if (avail > (SSize_t) count) {
  3713				    /*
  3714				     * If we have space for more than count, just move count
  3715				     */
  3716	        7407    	    avail = count;
  3717				}
  3718	        7436    	if (avail > 0) {
  3719	        7436    	    b->ptr -= avail;
  3720	        7436    	    buf -= avail;
  3721				    /*
  3722				     * In simple stdio-like ungetc() case chars will be already
  3723				     * there
  3724				     */
  3725	        7436    	    if (buf != b->ptr) {
  3726	        7436    		Copy(buf, b->ptr, avail, STDCHAR);
  3727				    }
  3728	        7436    	    count -= avail;
  3729	        7436    	    unread += avail;
  3730	        7436    	    PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
  3731				}
  3732			    }
  3733	        7436        if (count > 0) {
  3734	      ######    	unread += PerlIOBase_unread(aTHX_ f, vbuf, count);
  3735			    }
  3736	        7436        return unread;
  3737			}
  3738			
  3739			SSize_t
  3740			PerlIOBuf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  3741	     1141559    {
  3742	     1141559        PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
  3743	     1141559        const STDCHAR *buf = (const STDCHAR *) vbuf;
  3744	     1141559        const STDCHAR *flushptr = buf;
  3745	     1141559        Size_t written = 0;
  3746	     1141559        if (!b->buf)
  3747	       12042    	PerlIO_get_base(f);
  3748	     1141559        if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
  3749	      ######    	return 0;
  3750	     1141559        if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
  3751	           6        	if (PerlIO_flush(f) != 0) {
  3752	      ######    	    return 0;
  3753				}
  3754			    }	
  3755	     1141559        if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
  3756	        4361    	flushptr = buf + count;
  3757	      229906    	while (flushptr > buf && *(flushptr - 1) != '\n')
  3758	      225545    	    --flushptr;
  3759			    }
  3760	     2326435        while (count > 0) {
  3761	     1184876    	SSize_t avail = b->bufsiz - (b->ptr - b->buf);
  3762	     1184876    	if ((SSize_t) count < avail)
  3763	     1135682    	    avail = count;
  3764	     1184876    	if (flushptr > buf && flushptr <= buf + avail)
  3765	        1659    	    avail = flushptr - buf;
  3766	     1184876    	PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
  3767	     1184876    	if (avail) {
  3768	     1184876    	    Copy(buf, b->ptr, avail, STDCHAR);
  3769	     1184876    	    count -= avail;
  3770	     1184876    	    buf += avail;
  3771	     1184876    	    written += avail;
  3772	     1184876    	    b->ptr += avail;
  3773	     1184876    	    if (buf == flushptr)
  3774	        1659    		PerlIO_flush(f);
  3775				}
  3776	     1184876    	if (b->ptr >= (b->buf + b->bufsiz))
  3777	       49194    	    PerlIO_flush(f);
  3778			    }
  3779	     1141559        if (PerlIOBase(f)->flags & PERLIO_F_UNBUF)
  3780	        2360    	PerlIO_flush(f);
  3781	     1141559        return written;
  3782			}
  3783			
  3784			IV
  3785			PerlIOBuf_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
  3786	       29042    {
  3787	       29042        IV code;
  3788	       29042        if ((code = PerlIO_flush(f)) == 0) {
  3789	       29042    	PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
  3790	       29042    	code = PerlIO_seek(PerlIONext(f), offset, whence);
  3791	       29042    	if (code == 0) {
  3792	       29041    	    PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3793	       29041    	    b->posn = PerlIO_tell(PerlIONext(f));
  3794				}
  3795			    }
  3796	       29042        return code;
  3797			}
  3798			
  3799			Off_t
  3800			PerlIOBuf_tell(pTHX_ PerlIO *f)
  3801	     1760220    {
  3802	     1760220        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3803			    /*
  3804			     * b->posn is file position where b->buf was read, or will be written
  3805			     */
  3806	     1760220        Off_t posn = b->posn;
  3807	     1760220        if ((PerlIOBase(f)->flags & PERLIO_F_APPEND) &&
  3808			        (PerlIOBase(f)->flags & PERLIO_F_WRBUF)) {
  3809			#if 1
  3810			    	/* As O_APPEND files are normally shared in some sense it is better
  3811				   to flush :
  3812				 */  	
  3813	           1    	PerlIO_flush(f);
  3814			#else	
  3815			        /* when file is NOT shared then this is sufficient */
  3816				PerlIO_seek(PerlIONext(f),0, SEEK_END);
  3817			#endif
  3818	           1    	posn = b->posn = PerlIO_tell(PerlIONext(f));
  3819			    }
  3820	     1760220        if (b->buf) {
  3821				/*
  3822				 * If buffer is valid adjust position by amount in buffer
  3823				 */
  3824	     1756890    	posn += (b->ptr - b->buf);
  3825			    }
  3826	     1760220        return posn;
  3827			}
  3828			
  3829			IV
  3830			PerlIOBuf_popped(pTHX_ PerlIO *f)
  3831	       78017    {
  3832	       78017        const IV code = PerlIOBase_popped(aTHX_ f);
  3833	       78017        PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
  3834	       78017        if (b->buf && b->buf != (STDCHAR *) & b->oneword) {
  3835	           2    	Safefree(b->buf);
  3836			    }
  3837	       78017        b->buf = NULL;
  3838	       78017        b->ptr = b->end = b->buf;
  3839	       78017        PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
  3840	       78017        return code;
  3841			}
  3842			
  3843			IV
  3844			PerlIOBuf_close(pTHX_ PerlIO *f)
  3845	       78010    {
  3846	       78010        const IV code = PerlIOBase_close(aTHX_ f);
  3847	       78010        PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
  3848	       78010        if (b->buf && b->buf != (STDCHAR *) & b->oneword) {
  3849	       63283    	Safefree(b->buf);
  3850			    }
  3851	       78010        b->buf = NULL;
  3852	       78010        b->ptr = b->end = b->buf;
  3853	       78010        PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
  3854	       78010        return code;
  3855			}
  3856			
  3857			STDCHAR *
  3858			PerlIOBuf_get_ptr(pTHX_ PerlIO *f)
  3859	    11606502    {
  3860	    11606502        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3861	    11606502        if (!b->buf)
  3862	      ######    	PerlIO_get_base(f);
  3863	    11606502        return b->ptr;
  3864			}
  3865			
  3866			SSize_t
  3867			PerlIOBuf_get_cnt(pTHX_ PerlIO *f)
  3868	    23374802    {
  3869	    23374802        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3870	    23374802        if (!b->buf)
  3871	       48529    	PerlIO_get_base(f);
  3872	    23374802        if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
  3873	    23193184    	return (b->end - b->ptr);
  3874	      181618        return 0;
  3875			}
  3876			
  3877			STDCHAR *
  3878			PerlIOBuf_get_base(pTHX_ PerlIO *f)
  3879	      351914    {
  3880	      351914        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3881	      351914        if (!b->buf) {
  3882	       63248    	if (!b->bufsiz)
  3883	       63248    	    b->bufsiz = 4096;
  3884	       63248    	b->buf = Newz('B',b->buf,b->bufsiz, STDCHAR);
  3885	       63248    	if (!b->buf) {
  3886	      ######    	    b->buf = (STDCHAR *) & b->oneword;
  3887	      ######    	    b->bufsiz = sizeof(b->oneword);
  3888				}
  3889	       63248    	b->ptr = b->buf;
  3890	       63248    	b->end = b->ptr;
  3891			    }
  3892	      351914        return b->buf;
  3893			}
  3894			
  3895			Size_t
  3896			PerlIOBuf_bufsiz(pTHX_ PerlIO *f)
  3897	           9    {
  3898	           9        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3899	           9        if (!b->buf)
  3900	      ######    	PerlIO_get_base(f);
  3901	           9        return (b->end - b->buf);
  3902			}
  3903			
  3904			void
  3905			PerlIOBuf_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
  3906	    11568739    {
  3907	    11568739        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3908	    11568739        if (!b->buf)
  3909	      ######    	PerlIO_get_base(f);
  3910	    11568739        b->ptr = ptr;
  3911	    11568739        if (PerlIO_get_cnt(f) != cnt || b->ptr < b->buf) {
  3912	      ######    	assert(PerlIO_get_cnt(f) == cnt);
  3913	      ######    	assert(b->ptr >= b->buf);
  3914			    }
  3915	    11568739        PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
  3916			}
  3917			
  3918			PerlIO *
  3919			PerlIOBuf_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
  3920	        1482    {
  3921	        1482     return PerlIOBase_dup(aTHX_ f, o, param, flags);
  3922			}
  3923			
  3924			
  3925			
  3926			PERLIO_FUNCS_DECL(PerlIO_perlio) = {
  3927			    sizeof(PerlIO_funcs),
  3928			    "perlio",
  3929			    sizeof(PerlIOBuf),
  3930			    PERLIO_K_BUFFERED|PERLIO_K_RAW,
  3931			    PerlIOBuf_pushed,
  3932			    PerlIOBuf_popped,
  3933			    PerlIOBuf_open,
  3934			    PerlIOBase_binmode,         /* binmode */
  3935			    NULL,
  3936			    PerlIOBase_fileno,
  3937			    PerlIOBuf_dup,
  3938			    PerlIOBuf_read,
  3939			    PerlIOBuf_unread,
  3940			    PerlIOBuf_write,
  3941			    PerlIOBuf_seek,
  3942			    PerlIOBuf_tell,
  3943			    PerlIOBuf_close,
  3944			    PerlIOBuf_flush,
  3945			    PerlIOBuf_fill,
  3946			    PerlIOBase_eof,
  3947			    PerlIOBase_error,
  3948			    PerlIOBase_clearerr,
  3949			    PerlIOBase_setlinebuf,
  3950			    PerlIOBuf_get_base,
  3951			    PerlIOBuf_bufsiz,
  3952			    PerlIOBuf_get_ptr,
  3953			    PerlIOBuf_get_cnt,
  3954			    PerlIOBuf_set_ptrcnt,
  3955			};
  3956			
  3957			/*--------------------------------------------------------------------------------------*/
  3958			/*
  3959			 * Temp layer to hold unread chars when cannot do it any other way
  3960			 */
  3961			
  3962			IV
  3963			PerlIOPending_fill(pTHX_ PerlIO *f)
  3964	      ######    {
  3965			    /*
  3966			     * Should never happen
  3967			     */
  3968	      ######        PerlIO_flush(f);
  3969	      ######        return 0;
  3970			}
  3971			
  3972			IV
  3973			PerlIOPending_close(pTHX_ PerlIO *f)
  3974	      ######    {
  3975			    /*
  3976			     * A tad tricky - flush pops us, then we close new top
  3977			     */
  3978	      ######        PerlIO_flush(f);
  3979	      ######        return PerlIO_close(f);
  3980			}
  3981			
  3982			IV
  3983			PerlIOPending_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
  3984	      ######    {
  3985			    /*
  3986			     * A tad tricky - flush pops us, then we seek new top
  3987			     */
  3988	      ######        PerlIO_flush(f);
  3989	      ######        return PerlIO_seek(f, offset, whence);
  3990			}
  3991			
  3992			
  3993			IV
  3994			PerlIOPending_flush(pTHX_ PerlIO *f)
  3995	      ######    {
  3996	      ######        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  3997	      ######        if (b->buf && b->buf != (STDCHAR *) & b->oneword) {
  3998	      ######    	Safefree(b->buf);
  3999	      ######    	b->buf = NULL;
  4000			    }
  4001	      ######        PerlIO_pop(aTHX_ f);
  4002	      ######        return 0;
  4003			}
  4004			
  4005			void
  4006			PerlIOPending_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
  4007	      ######    {
  4008	      ######        if (cnt <= 0) {
  4009	      ######    	PerlIO_flush(f);
  4010			    }
  4011			    else {
  4012	      ######    	PerlIOBuf_set_ptrcnt(aTHX_ f, ptr, cnt);
  4013			    }
  4014			}
  4015			
  4016			IV
  4017			PerlIOPending_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  4018	      ######    {
  4019	      ######        const IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
  4020	      ######        PerlIOl *l = PerlIOBase(f);
  4021			    /*
  4022			     * Our PerlIO_fast_gets must match what we are pushed on, or sv_gets()
  4023			     * etc. get muddled when it changes mid-string when we auto-pop.
  4024			     */
  4025	      ######        l->flags = (l->flags & ~(PERLIO_F_FASTGETS | PERLIO_F_UTF8)) |
  4026				(PerlIOBase(PerlIONext(f))->
  4027				 flags & (PERLIO_F_FASTGETS | PERLIO_F_UTF8));
  4028	      ######        return code;
  4029			}
  4030			
  4031			SSize_t
  4032			PerlIOPending_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
  4033	      ######    {
  4034	      ######        SSize_t avail = PerlIO_get_cnt(f);
  4035	      ######        SSize_t got = 0;
  4036	      ######        if ((SSize_t)count < avail)
  4037	      ######    	avail = count;
  4038	      ######        if (avail > 0)
  4039	      ######    	got = PerlIOBuf_read(aTHX_ f, vbuf, avail);
  4040	      ######        if (got >= 0 && got < (SSize_t)count) {
  4041	      ######    	const SSize_t more =
  4042	      ######    	    PerlIO_read(f, ((STDCHAR *) vbuf) + got, count - got);
  4043	      ######    	if (more >= 0 || got == 0)
  4044	      ######    	    got += more;
  4045			    }
  4046	      ######        return got;
  4047			}
  4048			
  4049			PERLIO_FUNCS_DECL(PerlIO_pending) = {
  4050			    sizeof(PerlIO_funcs),
  4051			    "pending",
  4052			    sizeof(PerlIOBuf),
  4053			    PERLIO_K_BUFFERED|PERLIO_K_RAW,  /* not sure about RAW here */
  4054			    PerlIOPending_pushed,
  4055			    PerlIOBuf_popped,
  4056			    NULL,
  4057			    PerlIOBase_binmode,         /* binmode */
  4058			    NULL,
  4059			    PerlIOBase_fileno,
  4060			    PerlIOBuf_dup,
  4061			    PerlIOPending_read,
  4062			    PerlIOBuf_unread,
  4063			    PerlIOBuf_write,
  4064			    PerlIOPending_seek,
  4065			    PerlIOBuf_tell,
  4066			    PerlIOPending_close,
  4067			    PerlIOPending_flush,
  4068			    PerlIOPending_fill,
  4069			    PerlIOBase_eof,
  4070			    PerlIOBase_error,
  4071			    PerlIOBase_clearerr,
  4072			    PerlIOBase_setlinebuf,
  4073			    PerlIOBuf_get_base,
  4074			    PerlIOBuf_bufsiz,
  4075			    PerlIOBuf_get_ptr,
  4076			    PerlIOBuf_get_cnt,
  4077			    PerlIOPending_set_ptrcnt,
  4078			};
  4079			
  4080			
  4081			
  4082			/*--------------------------------------------------------------------------------------*/
  4083			/*
  4084			 * crlf - translation On read translate CR,LF to "\n" we do this by
  4085			 * overriding ptr/cnt entries to hand back a line at a time and keeping a
  4086			 * record of which nl we "lied" about. On write translate "\n" to CR,LF
  4087			 */
  4088			
  4089			typedef struct {
  4090			    PerlIOBuf base;             /* PerlIOBuf stuff */
  4091			    STDCHAR *nl;                /* Position of crlf we "lied" about in the
  4092							 * buffer */
  4093			} PerlIOCrlf;
  4094			
  4095			IV
  4096			PerlIOCrlf_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
  4097	          16    {
  4098	          16        IV code;
  4099	          16        PerlIOBase(f)->flags |= PERLIO_F_CRLF;
  4100	          16        code = PerlIOBuf_pushed(aTHX_ f, mode, arg, tab);
  4101			#if 0
  4102			    PerlIO_debug("PerlIOCrlf_pushed f=%p %s %s fl=%08" UVxf "\n",
  4103					 f, PerlIOBase(f)->tab->name, (mode) ? mode : "(Null)",
  4104					 PerlIOBase(f)->flags);
  4105			#endif
  4106			    {
  4107			      /* Enable the first CRLF capable layer you can find, but if none
  4108			       * found, the one we just pushed is fine.  This results in at
  4109			       * any given moment at most one CRLF-capable layer being enabled
  4110			       * in the whole layer stack. */
  4111	          16    	 PerlIO *g = PerlIONext(f);
  4112	          45    	 while (g && *g) {
  4113	          31    	      PerlIOl *b = PerlIOBase(g);
  4114	          31    	      if (b && b->tab == &PerlIO_crlf) {
  4115	           2    		   if (!(b->flags & PERLIO_F_CRLF))
  4116	      ######    			b->flags |= PERLIO_F_CRLF;
  4117	           2    		   PerlIO_pop(aTHX_ f);
  4118	           2    		   return code;
  4119				      }		  
  4120	          29    	      g = PerlIONext(g);
  4121				 }
  4122			    }
  4123	          14        return code;
  4124			}
  4125			
  4126			
  4127			SSize_t
  4128			PerlIOCrlf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  4129	      ######    {
  4130	      ######        PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
  4131	      ######        if (c->nl) {
  4132	      ######    	*(c->nl) = 0xd;
  4133	      ######    	c->nl = NULL;
  4134			    }
  4135	      ######        if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF))
  4136	      ######    	return PerlIOBuf_unread(aTHX_ f, vbuf, count);
  4137			    else {
  4138	      ######    	const STDCHAR *buf = (const STDCHAR *) vbuf + count;
  4139	      ######    	PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  4140	      ######    	SSize_t unread = 0;
  4141	      ######    	if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
  4142	      ######    	    PerlIO_flush(f);
  4143	      ######    	if (!b->buf)
  4144	      ######    	    PerlIO_get_base(f);
  4145	      ######    	if (b->buf) {
  4146	      ######    	    if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF)) {
  4147	      ######    		b->end = b->ptr = b->buf + b->bufsiz;
  4148	      ######    		PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
  4149	      ######    		b->posn -= b->bufsiz;
  4150				    }
  4151	      ######    	    while (count > 0 && b->ptr > b->buf) {
  4152	      ######    		int ch = *--buf;
  4153	      ######    		if (ch == '\n') {
  4154	      ######    		    if (b->ptr - 2 >= b->buf) {
  4155	      ######    			*--(b->ptr) = 0xa;
  4156	      ######    			*--(b->ptr) = 0xd;
  4157	      ######    			unread++;
  4158	      ######    			count--;
  4159					    }
  4160					    else {
  4161	      ######    			buf++;
  4162	      ######    			break;
  4163					    }
  4164					}
  4165					else {
  4166	      ######    		    *--(b->ptr) = ch;
  4167	      ######    		    unread++;
  4168	      ######    		    count--;
  4169					}
  4170				    }
  4171				}
  4172	      ######    	return unread;
  4173			    }
  4174			}
  4175			
  4176			SSize_t
  4177			PerlIOCrlf_get_cnt(pTHX_ PerlIO *f)
  4178	       37769    {
  4179	       37769        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  4180	       37769        if (!b->buf)
  4181	           3    	PerlIO_get_base(f);
  4182	       37769        if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
  4183	       37763    	PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
  4184	       37763    	if ((PerlIOBase(f)->flags & PERLIO_F_CRLF) && (!c->nl || *c->nl == 0xd)) {
  4185	       18943    	    STDCHAR *nl = (c->nl) ? c->nl : b->ptr;
  4186				  scan:
  4187	       96919    	    while (nl < b->end && *nl != 0xd)
  4188	       77976    		nl++;
  4189	       18943    	    if (nl < b->end && *nl == 0xd) {
  4190				      test:
  4191	       18939    		if (nl + 1 < b->end) {
  4192	       18876    		    if (nl[1] == 0xa) {
  4193	       18876    			*nl = '\n';
  4194	       18876    			c->nl = nl;
  4195					    }
  4196					    else {
  4197						/*
  4198						 * Not CR,LF but just CR
  4199						 */
  4200	      ######    			nl++;
  4201	      ######    			goto scan;
  4202					    }
  4203					}
  4204					else {
  4205					    /*
  4206					     * Blast - found CR as last char in buffer
  4207					     */
  4208			
  4209	          63    		    if (b->ptr < nl) {
  4210						/*
  4211						 * They may not care, defer work as long as
  4212						 * possible
  4213						 */
  4214	          42    			c->nl = nl;
  4215	          42    			return (nl - b->ptr);
  4216					    }
  4217					    else {
  4218	          21    			int code;
  4219	          21    			b->ptr++;       /* say we have read it as far as
  4220								 * flush() is concerned */
  4221	          21    			b->buf++;       /* Leave space in front of buffer */
  4222						/* Note as we have moved buf up flush's
  4223						   posn += ptr-buf
  4224						   will naturally make posn point at CR
  4225						 */
  4226	          21    			b->bufsiz--;    /* Buffer is thus smaller */
  4227	          21    			code = PerlIO_fill(f);  /* Fetch some more */
  4228	          21    			b->bufsiz++;    /* Restore size for next time */
  4229	          21    			b->buf--;       /* Point at space */
  4230	          21    			b->ptr = nl = b->buf;   /* Which is what we hand
  4231									 * off */
  4232	          21    			*nl = 0xd;      /* Fill in the CR */
  4233	          21    			if (code == 0)
  4234	          21    			    goto test;  /* fill() call worked */
  4235						/*
  4236						 * CR at EOF - just fall through
  4237						 */
  4238						/* Should we clear EOF though ??? */
  4239					    }
  4240					}
  4241				    }
  4242				}
  4243	       37721    	return (((c->nl) ? (c->nl + 1) : b->end) - b->ptr);
  4244			    }
  4245	           6        return 0;
  4246			}
  4247			
  4248			void
  4249			PerlIOCrlf_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
  4250	       37755    {
  4251	       37755        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  4252	       37755        PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
  4253	       37755        if (!b->buf)
  4254	      ######    	PerlIO_get_base(f);
  4255	       37755        if (!ptr) {
  4256	      ######    	if (c->nl) {
  4257	      ######    	    ptr = c->nl + 1;
  4258	      ######    	    if (ptr == b->end && *c->nl == 0xd) {
  4259					/* Defered CR at end of buffer case - we lied about count */
  4260	      ######    		ptr--;
  4261				    }
  4262				}
  4263				else {
  4264	      ######    	    ptr = b->end;
  4265				}
  4266	      ######    	ptr -= cnt;
  4267			    }
  4268			    else {
  4269			#if 0
  4270				/*
  4271				 * Test code - delete when it works ...
  4272				 */
  4273				IV flags = PerlIOBase(f)->flags;
  4274				STDCHAR *chk = (c->nl) ? (c->nl+1) : b->end;
  4275				if (ptr+cnt == c->nl && c->nl+1 == b->end && *c->nl == 0xd) {
  4276				  /* Defered CR at end of buffer case - we lied about count */
  4277				  chk--;
  4278				}
  4279				chk -= cnt;
  4280			
  4281				if (ptr != chk ) {
  4282				    Perl_croak(aTHX_ "ptr wrong %p != %p fl=%08" UVxf
  4283					       " nl=%p e=%p for %d", ptr, chk, flags, c->nl,
  4284					       b->end, cnt);
  4285				}
  4286			#endif
  4287			    }
  4288	       37755        if (c->nl) {
  4289	       37738    	if (ptr > c->nl) {
  4290				    /*
  4291				     * They have taken what we lied about
  4292				     */
  4293	       18875    	    *(c->nl) = 0xd;
  4294	       18875    	    c->nl = NULL;
  4295	       18875    	    ptr++;
  4296				}
  4297			    }
  4298	       37755        b->ptr = ptr;
  4299	       37755        PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
  4300			}
  4301			
  4302			SSize_t
  4303			PerlIOCrlf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  4304	           9    {
  4305	           9        if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF))
  4306	      ######    	return PerlIOBuf_write(aTHX_ f, vbuf, count);
  4307			    else {
  4308	           9    	PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  4309	           9    	const STDCHAR *buf = (const STDCHAR *) vbuf;
  4310	           9    	const STDCHAR *ebuf = buf + count;
  4311	           9    	if (!b->buf)
  4312	           7    	    PerlIO_get_base(f);
  4313	           9    	if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
  4314	      ######    	    return 0;
  4315	          25    	while (buf < ebuf) {
  4316	          16    	    STDCHAR *eptr = b->buf + b->bufsiz;
  4317	          16    	    PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
  4318	       30066    	    while (buf < ebuf && b->ptr < eptr) {
  4319	       30057    		if (*buf == '\n') {
  4320	        2009    		    if ((b->ptr + 2) > eptr) {
  4321						/*
  4322						 * Not room for both
  4323						 */
  4324	           1    			PerlIO_flush(f);
  4325	           1    			break;
  4326					    }
  4327					    else {
  4328	        2008    			*(b->ptr)++ = 0xd;      /* CR */
  4329	        2008    			*(b->ptr)++ = 0xa;      /* LF */
  4330	        2008    			buf++;
  4331	        2008    			if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
  4332	      ######    			    PerlIO_flush(f);
  4333	      ######    			    break;
  4334						}
  4335					    }
  4336					}
  4337					else {
  4338	       28048    		    int ch = *buf++;
  4339	       28048    		    *(b->ptr)++ = ch;
  4340					}
  4341	       30056    		if (b->ptr >= eptr) {
  4342	           6    		    PerlIO_flush(f);
  4343	           6    		    break;
  4344					}
  4345				    }
  4346				}
  4347	           9    	if (PerlIOBase(f)->flags & PERLIO_F_UNBUF)
  4348	      ######    	    PerlIO_flush(f);
  4349	           9    	return (buf - (STDCHAR *) vbuf);
  4350			    }
  4351			}
  4352			
  4353			IV
  4354			PerlIOCrlf_flush(pTHX_ PerlIO *f)
  4355	          57    {
  4356	          57        PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
  4357	          57        if (c->nl) {
  4358	          22    	*(c->nl) = 0xd;
  4359	          22    	c->nl = NULL;
  4360			    }
  4361	          57        return PerlIOBuf_flush(aTHX_ f);
  4362			}
  4363			
  4364			IV
  4365			PerlIOCrlf_binmode(pTHX_ PerlIO *f)
  4366	           3    {
  4367	           3        if ((PerlIOBase(f)->flags & PERLIO_F_CRLF)) {
  4368				/* In text mode - flush any pending stuff and flip it */
  4369	           3    	PerlIOBase(f)->flags &= ~PERLIO_F_CRLF;
  4370			#ifndef PERLIO_USING_CRLF
  4371				/* CRLF is unusual case - if this is just the :crlf layer pop it */
  4372	           3    	if (PerlIOBase(f)->tab == &PerlIO_crlf) {
  4373	           3    		PerlIO_pop(aTHX_ f);
  4374				}
  4375			#endif
  4376			    }
  4377	           3        return 0;
  4378			}
  4379			
  4380			PERLIO_FUNCS_DECL(PerlIO_crlf) = {
  4381			    sizeof(PerlIO_funcs),
  4382			    "crlf",
  4383			    sizeof(PerlIOCrlf),
  4384			    PERLIO_K_BUFFERED | PERLIO_K_CANCRLF | PERLIO_K_RAW,
  4385			    PerlIOCrlf_pushed,
  4386			    PerlIOBuf_popped,         /* popped */
  4387			    PerlIOBuf_open,
  4388			    PerlIOCrlf_binmode,       /* binmode */
  4389			    NULL,
  4390			    PerlIOBase_fileno,
  4391			    PerlIOBuf_dup,
  4392			    PerlIOBuf_read,             /* generic read works with ptr/cnt lies */
  4393			    PerlIOCrlf_unread,          /* Put CR,LF in buffer for each '\n' */
  4394			    PerlIOCrlf_write,           /* Put CR,LF in buffer for each '\n' */
  4395			    PerlIOBuf_seek,
  4396			    PerlIOBuf_tell,
  4397			    PerlIOBuf_close,
  4398			    PerlIOCrlf_flush,
  4399			    PerlIOBuf_fill,
  4400			    PerlIOBase_eof,
  4401			    PerlIOBase_error,
  4402			    PerlIOBase_clearerr,
  4403			    PerlIOBase_setlinebuf,
  4404			    PerlIOBuf_get_base,
  4405			    PerlIOBuf_bufsiz,
  4406			    PerlIOBuf_get_ptr,
  4407			    PerlIOCrlf_get_cnt,
  4408			    PerlIOCrlf_set_ptrcnt,
  4409			};
  4410			
  4411			#ifdef HAS_MMAP
  4412			/*--------------------------------------------------------------------------------------*/
  4413			/*
  4414			 * mmap as "buffer" layer
  4415			 */
  4416			
  4417			typedef struct {
  4418			    PerlIOBuf base;             /* PerlIOBuf stuff */
  4419			    Mmap_t mptr;                /* Mapped address */
  4420			    Size_t len;                 /* mapped length */
  4421			    STDCHAR *bbuf;              /* malloced buffer if map fails */
  4422			} PerlIOMmap;
  4423			
  4424			IV
  4425			PerlIOMmap_map(pTHX_ PerlIO *f)
  4426	      ######    {
  4427			    dVAR;
  4428	      ######        PerlIOMmap * const m = PerlIOSelf(f, PerlIOMmap);
  4429	      ######        const IV flags = PerlIOBase(f)->flags;
  4430	      ######        IV code = 0;
  4431	      ######        if (m->len)
  4432	      ######    	abort();
  4433	      ######        if (flags & PERLIO_F_CANREAD) {
  4434	      ######    	PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  4435	      ######    	const int fd = PerlIO_fileno(f);
  4436	      ######    	Stat_t st;
  4437	      ######    	code = Fstat(fd, &st);
  4438	      ######    	if (code == 0 && S_ISREG(st.st_mode)) {
  4439	      ######    	    SSize_t len = st.st_size - b->posn;
  4440	      ######    	    if (len > 0) {
  4441	      ######    		Off_t posn;
  4442	      ######    		if (PL_mmap_page_size <= 0)
  4443	      ######    		  Perl_croak(aTHX_ "panic: bad pagesize %" IVdf,
  4444						     PL_mmap_page_size);
  4445	      ######    		if (b->posn < 0) {
  4446					    /*
  4447					     * This is a hack - should never happen - open should
  4448					     * have set it !
  4449					     */
  4450	      ######    		    b->posn = PerlIO_tell(PerlIONext(f));
  4451					}
  4452	      ######    		posn = (b->posn / PL_mmap_page_size) * PL_mmap_page_size;
  4453	      ######    		len = st.st_size - posn;
  4454	      ######    		m->mptr = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, posn);
  4455	      ######    		if (m->mptr && m->mptr != (Mmap_t) - 1) {
  4456			#if 0 && defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
  4457					    madvise(m->mptr, len, MADV_SEQUENTIAL);
  4458			#endif
  4459			#if 0 && defined(HAS_MADVISE) && defined(MADV_WILLNEED)
  4460					    madvise(m->mptr, len, MADV_WILLNEED);
  4461			#endif
  4462	      ######    		    PerlIOBase(f)->flags =
  4463						(flags & ~PERLIO_F_EOF) | PERLIO_F_RDBUF;
  4464	      ######    		    b->end = ((STDCHAR *) m->mptr) + len;
  4465	      ######    		    b->buf = ((STDCHAR *) m->mptr) + (b->posn - posn);
  4466	      ######    		    b->ptr = b->buf;
  4467	      ######    		    m->len = len;
  4468					}
  4469					else {
  4470	      ######    		    b->buf = NULL;
  4471					}
  4472				    }
  4473				    else {
  4474	      ######    		PerlIOBase(f)->flags =
  4475					    flags | PERLIO_F_EOF | PERLIO_F_RDBUF;
  4476	      ######    		b->buf = NULL;
  4477	      ######    		b->ptr = b->end = b->ptr;
  4478	      ######    		code = -1;
  4479				    }
  4480				}
  4481			    }
  4482	      ######        return code;
  4483			}
  4484			
  4485			IV
  4486			PerlIOMmap_unmap(pTHX_ PerlIO *f)
  4487	      ######    {
  4488	      ######        PerlIOMmap *m = PerlIOSelf(f, PerlIOMmap);
  4489	      ######        PerlIOBuf *b = &m->base;
  4490	      ######        IV code = 0;
  4491	      ######        if (m->len) {
  4492	      ######    	if (b->buf) {
  4493	      ######    	    code = munmap(m->mptr, m->len);
  4494	      ######    	    b->buf = NULL;
  4495	      ######    	    m->len = 0;
  4496	      ######    	    m->mptr = NULL;
  4497	      ######    	    if (PerlIO_seek(PerlIONext(f), b->posn, SEEK_SET) != 0)
  4498	      ######    		code = -1;
  4499				}
  4500	      ######    	b->ptr = b->end = b->buf;
  4501	      ######    	PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
  4502			    }
  4503	      ######        return code;
  4504			}
  4505			
  4506			STDCHAR *
  4507			PerlIOMmap_get_base(pTHX_ PerlIO *f)
  4508	      ######    {
  4509	      ######        PerlIOMmap *m = PerlIOSelf(f, PerlIOMmap);
  4510	      ######        PerlIOBuf *b = &m->base;
  4511	      ######        if (b->buf && (PerlIOBase(f)->flags & PERLIO_F_RDBUF)) {
  4512				/*
  4513				 * Already have a readbuffer in progress
  4514				 */
  4515	      ######    	return b->buf;
  4516			    }
  4517	      ######        if (b->buf) {
  4518				/*
  4519				 * We have a write buffer or flushed PerlIOBuf read buffer
  4520				 */
  4521	      ######    	m->bbuf = b->buf;       /* save it in case we need it again */
  4522	      ######    	b->buf = NULL;          /* Clear to trigger below */
  4523			    }
  4524	      ######        if (!b->buf) {
  4525	      ######    	PerlIOMmap_map(aTHX_ f);        /* Try and map it */
  4526	      ######    	if (!b->buf) {
  4527				    /*
  4528				     * Map did not work - recover PerlIOBuf buffer if we have one
  4529				     */
  4530	      ######    	    b->buf = m->bbuf;
  4531				}
  4532			    }
  4533	      ######        b->ptr = b->end = b->buf;
  4534	      ######        if (b->buf)
  4535	      ######    	return b->buf;
  4536	      ######        return PerlIOBuf_get_base(aTHX_ f);
  4537			}
  4538			
  4539			SSize_t
  4540			PerlIOMmap_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  4541	      ######    {
  4542	      ######        PerlIOMmap *m = PerlIOSelf(f, PerlIOMmap);
  4543	      ######        PerlIOBuf *b = &m->base;
  4544	      ######        if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
  4545	      ######    	PerlIO_flush(f);
  4546	      ######        if (b->ptr && (b->ptr - count) >= b->buf
  4547				&& memEQ(b->ptr - count, vbuf, count)) {
  4548	      ######    	b->ptr -= count;
  4549	      ######    	PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
  4550	      ######    	return count;
  4551			    }
  4552	      ######        if (m->len) {
  4553				/*
  4554				 * Loose the unwritable mapped buffer
  4555				 */
  4556	      ######    	PerlIO_flush(f);
  4557				/*
  4558				 * If flush took the "buffer" see if we have one from before
  4559				 */
  4560	      ######    	if (!b->buf && m->bbuf)
  4561	      ######    	    b->buf = m->bbuf;
  4562	      ######    	if (!b->buf) {
  4563	      ######    	    PerlIOBuf_get_base(aTHX_ f);
  4564	      ######    	    m->bbuf = b->buf;
  4565				}
  4566			    }
  4567	      ######        return PerlIOBuf_unread(aTHX_ f, vbuf, count);
  4568			}
  4569			
  4570			SSize_t
  4571			PerlIOMmap_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
  4572	      ######    {
  4573	      ######        PerlIOMmap * const m = PerlIOSelf(f, PerlIOMmap);
  4574	      ######        PerlIOBuf * const b = &m->base;
  4575			
  4576	      ######        if (!b->buf || !(PerlIOBase(f)->flags & PERLIO_F_WRBUF)) {
  4577				/*
  4578				 * No, or wrong sort of, buffer
  4579				 */
  4580	      ######    	if (m->len) {
  4581	      ######    	    if (PerlIOMmap_unmap(aTHX_ f) != 0)
  4582	      ######    		return 0;
  4583				}
  4584				/*
  4585				 * If unmap took the "buffer" see if we have one from before
  4586				 */
  4587	      ######    	if (!b->buf && m->bbuf)
  4588	      ######    	    b->buf = m->bbuf;
  4589	      ######    	if (!b->buf) {
  4590	      ######    	    PerlIOBuf_get_base(aTHX_ f);
  4591	      ######    	    m->bbuf = b->buf;
  4592				}
  4593			    }
  4594	      ######        return PerlIOBuf_write(aTHX_ f, vbuf, count);
  4595			}
  4596			
  4597			IV
  4598			PerlIOMmap_flush(pTHX_ PerlIO *f)
  4599	      ######    {
  4600	      ######        PerlIOMmap *m = PerlIOSelf(f, PerlIOMmap);
  4601	      ######        PerlIOBuf *b = &m->base;
  4602	      ######        IV code = PerlIOBuf_flush(aTHX_ f);
  4603			    /*
  4604			     * Now we are "synced" at PerlIOBuf level
  4605			     */
  4606	      ######        if (b->buf) {
  4607	      ######    	if (m->len) {
  4608				    /*
  4609				     * Unmap the buffer
  4610				     */
  4611	      ######    	    if (PerlIOMmap_unmap(aTHX_ f) != 0)
  4612	      ######    		code = -1;
  4613				}
  4614				else {
  4615				    /*
  4616				     * We seem to have a PerlIOBuf buffer which was not mapped
  4617				     * remember it in case we need one later
  4618				     */
  4619	      ######    	    m->bbuf = b->buf;
  4620				}
  4621			    }
  4622	      ######        return code;
  4623			}
  4624			
  4625			IV
  4626			PerlIOMmap_fill(pTHX_ PerlIO *f)
  4627	      ######    {
  4628	      ######        PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
  4629	      ######        IV code = PerlIO_flush(f);
  4630	      ######        if (code == 0 && !b->buf) {
  4631	      ######    	code = PerlIOMmap_map(aTHX_ f);
  4632			    }
  4633	      ######        if (code == 0 && !(PerlIOBase(f)->flags & PERLIO_F_RDBUF)) {
  4634	      ######    	code = PerlIOBuf_fill(aTHX_ f);
  4635			    }
  4636	      ######        return code;
  4637			}
  4638			
  4639			IV
  4640			PerlIOMmap_close(pTHX_ PerlIO *f)
  4641	      ######    {
  4642	      ######        PerlIOMmap *m = PerlIOSelf(f, PerlIOMmap);
  4643	      ######        PerlIOBuf *b = &m->base;
  4644	      ######        IV code = PerlIO_flush(f);
  4645	      ######        if (m->bbuf) {
  4646	      ######    	b->buf = m->bbuf;
  4647	      ######    	m->bbuf = NULL;
  4648	      ######    	b->ptr = b->end = b->buf;
  4649			    }
  4650	      ######        if (PerlIOBuf_close(aTHX_ f) != 0)
  4651	      ######    	code = -1;
  4652	      ######        return code;
  4653			}
  4654			
  4655			PerlIO *
  4656			PerlIOMmap_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
  4657	      ######    {
  4658	      ######     return PerlIOBase_dup(aTHX_ f, o, param, flags);
  4659			}
  4660			
  4661			
  4662			PERLIO_FUNCS_DECL(PerlIO_mmap) = {
  4663			    sizeof(PerlIO_funcs),
  4664			    "mmap",
  4665			    sizeof(PerlIOMmap),
  4666			    PERLIO_K_BUFFERED|PERLIO_K_RAW,
  4667			    PerlIOBuf_pushed,
  4668			    PerlIOBuf_popped,
  4669			    PerlIOBuf_open,
  4670			    PerlIOBase_binmode,         /* binmode */
  4671			    NULL,
  4672			    PerlIOBase_fileno,
  4673			    PerlIOMmap_dup,
  4674			    PerlIOBuf_read,
  4675			    PerlIOMmap_unread,
  4676			    PerlIOMmap_write,
  4677			    PerlIOBuf_seek,
  4678			    PerlIOBuf_tell,
  4679			    PerlIOBuf_close,
  4680			    PerlIOMmap_flush,
  4681			    PerlIOMmap_fill,
  4682			    PerlIOBase_eof,
  4683			    PerlIOBase_error,
  4684			    PerlIOBase_clearerr,
  4685			    PerlIOBase_setlinebuf,
  4686			    PerlIOMmap_get_base,
  4687			    PerlIOBuf_bufsiz,
  4688			    PerlIOBuf_get_ptr,
  4689			    PerlIOBuf_get_cnt,
  4690			    PerlIOBuf_set_ptrcnt,
  4691			};
  4692			
  4693			#endif                          /* HAS_MMAP */
  4694			
  4695			PerlIO *
  4696			Perl_PerlIO_stdin(pTHX)
  4697	      169192    {
  4698	      169192        if (!PL_perlio) {
  4699	          19    	PerlIO_stdstreams(aTHX);
  4700			    }
  4701	      169192        return &PL_perlio[1];
  4702			}
  4703			
  4704			PerlIO *
  4705			Perl_PerlIO_stdout(pTHX)
  4706	       18859    {
  4707	       18859        if (!PL_perlio) {
  4708	           2    	PerlIO_stdstreams(aTHX);
  4709			    }
  4710	       18859        return &PL_perlio[2];
  4711			}
  4712			
  4713			PerlIO *
  4714			Perl_PerlIO_stderr(pTHX)
  4715	       13451    {
  4716	       13451        if (!PL_perlio) {
  4717	           1    	PerlIO_stdstreams(aTHX);
  4718			    }
  4719	       13451        return &PL_perlio[3];
  4720			}
  4721			
  4722			/*--------------------------------------------------------------------------------------*/
  4723			
  4724			char *
  4725			PerlIO_getname(PerlIO *f, char *buf)
  4726	      ######    {
  4727			    dTHX;
  4728			#ifdef VMS
  4729			    char *name = NULL;
  4730			    bool exported = FALSE;
  4731			    FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
  4732			    if (!stdio) {
  4733				stdio = PerlIO_exportFILE(f,0);
  4734				exported = TRUE;
  4735			    }
  4736			    if (stdio) {
  4737				name = fgetname(stdio, buf);
  4738				if (exported) PerlIO_releaseFILE(f,stdio);
  4739			    }
  4740			    return name;
  4741			#else
  4742	      ######        PERL_UNUSED_ARG(f);
  4743	      ######        PERL_UNUSED_ARG(buf);
  4744	      ######        Perl_croak(aTHX_ "Don't know how to get file name");
  4745			    return Nullch;
  4746			#endif
  4747			}
  4748			
  4749			
  4750			/*--------------------------------------------------------------------------------------*/
  4751			/*
  4752			 * Functions which can be called on any kind of PerlIO implemented in
  4753			 * terms of above
  4754			 */
  4755			
  4756			#undef PerlIO_fdopen
  4757			PerlIO *
  4758			PerlIO_fdopen(int fd, const char *mode)
  4759	       18114    {
  4760			    dTHX;
  4761	       18114        return PerlIO_openn(aTHX_ Nullch, mode, fd, 0, 0, NULL, 0, NULL);
  4762			}
  4763			
  4764			#undef PerlIO_open
  4765			PerlIO *
  4766			PerlIO_open(const char *path, const char *mode)
  4767	       46347    {
  4768			    dTHX;
  4769	       46347        SV *name = sv_2mortal(newSVpvn(path, strlen(path)));
  4770	       46347        return PerlIO_openn(aTHX_ Nullch, mode, -1, 0, 0, NULL, 1, &name);
  4771			}
  4772			
  4773			#undef Perlio_reopen
  4774			PerlIO *
  4775			PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
  4776	      ######    {
  4777			    dTHX;
  4778	      ######        SV *name = sv_2mortal(newSVpvn(path, strlen(path)));
  4779	      ######        return PerlIO_openn(aTHX_ Nullch, mode, -1, 0, 0, f, 1, &name);
  4780			}
  4781			
  4782			#undef PerlIO_getc
  4783			int
  4784			PerlIO_getc(PerlIO *f)
  4785	      250057    {
  4786			    dTHX;
  4787	      250057        STDCHAR buf[1];
  4788	      250057        if ( 1 == PerlIO_read(f, buf, 1) ) {
  4789	      215937    	return (unsigned char) buf[0];
  4790			    }
  4791	       34119        return EOF;
  4792			}
  4793			
  4794			#undef PerlIO_ungetc
  4795			int
  4796			PerlIO_ungetc(PerlIO *f, int ch)
  4797	        7438    {
  4798			    dTHX;
  4799	        7438        if (ch != EOF) {
  4800	        7436    	STDCHAR buf = ch;
  4801	        7436    	if (PerlIO_unread(f, &buf, 1) == 1)
  4802	        7436    	    return ch;
  4803			    }
  4804	           2        return EOF;
  4805			}
  4806			
  4807			#undef PerlIO_putc
  4808			int
  4809			PerlIO_putc(PerlIO *f, int ch)
  4810	         534    {
  4811			    dTHX;
  4812	         534        STDCHAR buf = ch;
  4813	         534        return PerlIO_write(f, &buf, 1);
  4814			}
  4815			
  4816			#undef PerlIO_puts
  4817			int
  4818			PerlIO_puts(PerlIO *f, const char *s)
  4819	      ######    {
  4820			    dTHX;
  4821	      ######        STRLEN len = strlen(s);
  4822	      ######        return PerlIO_write(f, s, len);
  4823			}
  4824			
  4825			#undef PerlIO_rewind
  4826			void
  4827			PerlIO_rewind(PerlIO *f)
  4828	      ######    {
  4829			    dTHX;
  4830	      ######        PerlIO_seek(f, (Off_t) 0, SEEK_SET);
  4831	      ######        PerlIO_clearerr(f);
  4832			}
  4833			
  4834			#undef PerlIO_vprintf
  4835			int
  4836			PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
  4837	       21665    {
  4838			    dTHX;
  4839	       21665        SV *sv = newSVpvn("", 0);
  4840	       21665        const char *s;
  4841	       21665        STRLEN len;
  4842	       21665        SSize_t wrote;
  4843			#ifdef NEED_VA_COPY
  4844			    va_list apc;
  4845			    Perl_va_copy(ap, apc);
  4846			    sv_vcatpvf(sv, fmt, &apc);
  4847			#else
  4848	       21665        sv_vcatpvf(sv, fmt, &ap);
  4849			#endif
  4850	       21665        s = SvPV_const(sv, len);
  4851	       21665        wrote = PerlIO_write(f, s, len);
  4852	       21665        SvREFCNT_dec(sv);
  4853	       21665        return wrote;
  4854			}
  4855			
  4856			#undef PerlIO_printf
  4857			int
  4858			PerlIO_printf(PerlIO *f, const char *fmt, ...)
  4859	       21454    {
  4860	       21454        va_list ap;
  4861	       21454        int result;
  4862	       21454        va_start(ap, fmt);
  4863	       21454        result = PerlIO_vprintf(f, fmt, ap);
  4864	       21454        va_end(ap);
  4865	       21454        return result;
  4866			}
  4867			
  4868			#undef PerlIO_stdoutf
  4869			int
  4870			PerlIO_stdoutf(const char *fmt, ...)
  4871	      ######    {
  4872			    dTHX;
  4873	      ######        va_list ap;
  4874	      ######        int result;
  4875	      ######        va_start(ap, fmt);
  4876	      ######        result = PerlIO_vprintf(PerlIO_stdout(), fmt, ap);
  4877	      ######        va_end(ap);
  4878	      ######        return result;
  4879			}
  4880			
  4881			#undef PerlIO_tmpfile
  4882			PerlIO *
  4883			PerlIO_tmpfile(void)
  4884	          20    {
  4885			     dTHX;
  4886	          20         PerlIO *f = NULL;
  4887			#ifdef WIN32
  4888			     const int fd = win32_tmpfd();
  4889			     if (fd >= 0)
  4890				  f = PerlIO_fdopen(fd, "w+b");
  4891			#else /* WIN32 */
  4892			#    if defined(HAS_MKSTEMP) && ! defined(VMS) && ! defined(OS2)
  4893	          20         SV *sv = newSVpv("/tmp/PerlIO_XXXXXX", 0);
  4894			     /*
  4895			      * I have no idea how portable mkstemp() is ... NI-S
  4896			      */
  4897	          20         const int fd = mkstemp(SvPVX(sv));
  4898	          20         if (fd >= 0) {
  4899	          20    	  f = PerlIO_fdopen(fd, "w+");
  4900	          20    	  if (f)
  4901	          20    	       PerlIOBase(f)->flags |= PERLIO_F_TEMP;
  4902	          20    	  PerlLIO_unlink(SvPVX_const(sv));
  4903	          20    	  SvREFCNT_dec(sv);
  4904			     }
  4905			#    else	/* !HAS_MKSTEMP, fallback to stdio tmpfile(). */
  4906			     FILE *stdio = PerlSIO_tmpfile();
  4907			
  4908			     if (stdio) {
  4909				  if ((f = PerlIO_push(aTHX_(PerlIO_allocate(aTHX)),
  4910			                               PERLIO_FUNCS_CAST(&PerlIO_stdio),
  4911						       "w+", Nullsv))) {
  4912			               PerlIOStdio *s = PerlIOSelf(f, PerlIOStdio);
  4913			
  4914			               if (s)
  4915			                    s->stdio = stdio;
  4916			          }
  4917			     }
  4918			#    endif /* else HAS_MKSTEMP */
  4919			#endif /* else WIN32 */
  4920	          20         return f;
  4921			}
  4922			
  4923			#undef HAS_FSETPOS
  4924			#undef HAS_FGETPOS
  4925			
  4926			#endif                          /* USE_SFIO */
  4927			#endif                          /* PERLIO_IS_STDIO */
  4928			
  4929			/*======================================================================================*/
  4930			/*
  4931			 * Now some functions in terms of above which may be needed even if we are
  4932			 * not in true PerlIO mode
  4933			 */
  4934			
  4935			#ifndef HAS_FSETPOS
  4936			#undef PerlIO_setpos
  4937			int
  4938			PerlIO_setpos(PerlIO *f, SV *pos)
  4939	           2    {
  4940			    dTHX;
  4941	           2        if (SvOK(pos)) {
  4942	           1    	STRLEN len;
  4943	           1    	Off_t *posn = (Off_t *) SvPV(pos, len);
  4944	           1    	if (f && len == sizeof(Off_t))
  4945	           1    	    return PerlIO_seek(f, *posn, SEEK_SET);
  4946			    }
  4947	           1        SETERRNO(EINVAL, SS_IVCHAN);
  4948	           1        return -1;
  4949			}
  4950			#else
  4951			#undef PerlIO_setpos
  4952			int
  4953			PerlIO_setpos(PerlIO *f, SV *pos)
  4954			{
  4955			    dTHX;
  4956			    if (SvOK(pos)) {
  4957				STRLEN len;
  4958				Fpos_t *fpos = (Fpos_t *) SvPV(pos, len);
  4959				if (f && len == sizeof(Fpos_t)) {
  4960			#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
  4961				    return fsetpos64(f, fpos);
  4962			#else
  4963				    return fsetpos(f, fpos);
  4964			#endif
  4965				}
  4966			    }
  4967			    SETERRNO(EINVAL, SS_IVCHAN);
  4968			    return -1;
  4969			}
  4970			#endif
  4971			
  4972			#ifndef HAS_FGETPOS
  4973			#undef PerlIO_getpos
  4974			int
  4975			PerlIO_getpos(PerlIO *f, SV *pos)
  4976	           1    {
  4977			    dTHX;
  4978	           1        Off_t posn = PerlIO_tell(f);
  4979	           1        sv_setpvn(pos, (char *) &posn, sizeof(posn));
  4980	           1        return (posn == (Off_t) - 1) ? -1 : 0;
  4981			}
  4982			#else
  4983			#undef PerlIO_getpos
  4984			int
  4985			PerlIO_getpos(PerlIO *f, SV *pos)
  4986			{
  4987			    dTHX;
  4988			    Fpos_t fpos;
  4989			    int code;
  4990			#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
  4991			    code = fgetpos64(f, &fpos);
  4992			#else
  4993			    code = fgetpos(f, &fpos);
  4994			#endif
  4995			    sv_setpvn(pos, (char *) &fpos, sizeof(fpos));
  4996			    return code;
  4997			}
  4998			#endif
  4999			
  5000			#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
  5001			
  5002			int
  5003			vprintf(char *pat, char *args)
  5004			{
  5005			    _doprnt(pat, args, stdout);
  5006			    return 0;                   /* wrong, but perl doesn't use the return
  5007							 * value */
  5008			}
  5009			
  5010			int
  5011			vfprintf(FILE *fd, char *pat, char *args)
  5012			{
  5013			    _doprnt(pat, args, fd);
  5014			    return 0;                   /* wrong, but perl doesn't use the return
  5015							 * value */
  5016			}
  5017			
  5018			#endif
  5019			
  5020			#ifndef PerlIO_vsprintf
  5021			int
  5022			PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
  5023	      ######    {
  5024			    dVAR;
  5025	      ######        const int val = vsprintf(s, fmt, ap);
  5026	      ######        if (n >= 0) {
  5027	      ######    	if (strlen(s) >= (STRLEN) n) {
  5028				    dTHX;
  5029	      ######    	    (void) PerlIO_puts(Perl_error_log,
  5030						       "panic: sprintf overflow - memory corrupted!\n");
  5031	      ######    	    my_exit(1);
  5032				}
  5033			    }
  5034	      ######        return val;
  5035			}
  5036			#endif
  5037			
  5038			#ifndef PerlIO_sprintf
  5039			int
  5040			PerlIO_sprintf(char *s, int n, const char *fmt, ...)
  5041	      ######    {
  5042	      ######        va_list ap;
  5043	      ######        int result;
  5044	      ######        va_start(ap, fmt);
  5045	      ######        result = PerlIO_vsprintf(s, n, fmt, ap);
  5046	      ######        va_end(ap);
  5047	      ######        return result;
  5048			}
  5049			#endif
  5050			
  5051			/*
  5052			 * Local variables:
  5053			 * c-indentation-style: bsd
  5054			 * c-basic-offset: 4
  5055			 * indent-tabs-mode: t
  5056			 * End:
  5057			 *
  5058			 * ex: set ts=8 sts=4 sw=4 noet:
  5059			 */

