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