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