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