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