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