ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/staticperl/perl/perlio.c
Revision: 1.1
Committed: Thu Jun 30 14:26:42 2005 UTC (21 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

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