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