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