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