This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Normalise 3 fatal pack/unpack error messages to "panic: %s"
[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
PP
392#undef PerlIO_tmpfile
393PerlIO *
8ac85365 394PerlIO_tmpfile(void)
33dcbb9a 395{
14a5cf38 396 return tmpfile();
33dcbb9a
PP
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
JH
616 IV i;
617 for (i = 0; i < list->cur; i++) {
618 if (list->array[i].arg)
619 SvREFCNT_dec(list->array[i].arg);
620 }
621 Safefree(list->array);
622 }
623 Safefree(list);
624 }
625 }
fcf2db38
NIS
626}
627
628void
3a1ee7e8 629PerlIO_list_push(pTHX_ PerlIO_list_t *list, PerlIO_funcs *funcs, SV *arg)
14a5cf38 630{
97aff369 631 dVAR;
334e202e 632 PerlIO_pair_t *p;
b37c2d43
AL
633 PERL_UNUSED_CONTEXT;
634
14a5cf38
JH
635 if (list->cur >= list->len) {
636 list->len += 8;
637 if (list->array)
638 Renew(list->array, list->len, PerlIO_pair_t);
639 else
a02a5408 640 Newx(list->array, list->len, PerlIO_pair_t);
14a5cf38
JH
641 }
642 p = &(list->array[list->cur++]);
643 p->funcs = funcs;
644 if ((p->arg = arg)) {
f84c484e 645 SvREFCNT_inc_simple_void_NN(arg);
14a5cf38 646 }
fcf2db38
NIS
647}
648
3a1ee7e8
NIS
649PerlIO_list_t *
650PerlIO_clone_list(pTHX_ PerlIO_list_t *proto, CLONE_PARAMS *param)
651{
b37c2d43 652 PerlIO_list_t *list = NULL;
694c95cf
JH
653 if (proto) {
654 int i;
655 list = PerlIO_list_alloc(aTHX);
656 for (i=0; i < proto->cur; i++) {
a951d81d
BL
657 SV *arg = proto->array[i].arg;
658#ifdef sv_dup
659 if (arg && param)
660 arg = sv_dup(arg, param);
661#else
662 PERL_UNUSED_ARG(param);
663#endif
694c95cf
JH
664 PerlIO_list_push(aTHX_ list, proto->array[i].funcs, arg);
665 }
3a1ee7e8
NIS
666 }
667 return list;
668}
4a4a6116 669
05d1247b 670void
3a1ee7e8 671PerlIO_clone(pTHX_ PerlInterpreter *proto, CLONE_PARAMS *param)
9a6404c5 672{
3aaf42a7 673#ifdef USE_ITHREADS
3a1ee7e8
NIS
674 PerlIO **table = &proto->Iperlio;
675 PerlIO *f;
676 PL_perlio = NULL;
677 PL_known_layers = PerlIO_clone_list(aTHX_ proto->Iknown_layers, param);
678 PL_def_layerlist = PerlIO_clone_list(aTHX_ proto->Idef_layerlist, param);
679 PerlIO_allocate(aTHX); /* root slot is never used */
a25429c6 680 PerlIO_debug("Clone %p from %p\n",(void*)aTHX,(void*)proto);
3a1ee7e8
NIS
681 while ((f = *table)) {
682 int i;
683 table = (PerlIO **) (f++);
684 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
685 if (*f) {
93a8090d 686 (void) fp_dup(f, 0, param);
3a1ee7e8
NIS
687 }
688 f++;
689 }
690 }
1b6737cc 691#else
a25429c6 692 PERL_UNUSED_CONTEXT;
1b6737cc
AL
693 PERL_UNUSED_ARG(proto);
694 PERL_UNUSED_ARG(param);
3aaf42a7 695#endif
9a6404c5
DM
696}
697
698void
13621cfb
NIS
699PerlIO_destruct(pTHX)
700{
97aff369 701 dVAR;
a1ea730d 702 PerlIO **table = &PL_perlio;
14a5cf38 703 PerlIO *f;
694c95cf 704#ifdef USE_ITHREADS
a25429c6 705 PerlIO_debug("Destruct %p\n",(void*)aTHX);
694c95cf 706#endif
14a5cf38
JH
707 while ((f = *table)) {
708 int i;
709 table = (PerlIO **) (f++);
710 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
711 PerlIO *x = f;
dcda55fc 712 const PerlIOl *l;
14a5cf38
JH
713 while ((l = *x)) {
714 if (l->tab->kind & PERLIO_K_DESTRUCT) {
715 PerlIO_debug("Destruct popping %s\n", l->tab->name);
716 PerlIO_flush(x);
717 PerlIO_pop(aTHX_ x);
718 }
719 else {
720 x = PerlIONext(x);
721 }
722 }
723 f++;
724 }
725 }
13621cfb
NIS
726}
727
728void
a999f61b 729PerlIO_pop(pTHX_ PerlIO *f)
760ac839 730{
dcda55fc 731 const PerlIOl *l = *f;
14a5cf38 732 if (l) {
fe5a182c 733 PerlIO_debug("PerlIO_pop f=%p %s\n", (void*)f, l->tab->name);
14a5cf38
JH
734 if (l->tab->Popped) {
735 /*
736 * If popped returns non-zero do not free its layer structure
737 * it has either done so itself, or it is shared and still in
71200d45 738 * use
14a5cf38 739 */
f62ce20a 740 if ((*l->tab->Popped) (aTHX_ f) != 0)
14a5cf38
JH
741 return;
742 }
b47cad08 743 *f = l->next;
3a1ee7e8 744 Safefree(l);
a8c08ecd 745 }
6f9d8c32
NIS
746}
747
39f7a870
JH
748/* Return as an array the stack of layers on a filehandle. Note that
749 * the stack is returned top-first in the array, and there are three
750 * times as many array elements as there are layers in the stack: the
751 * first element of a layer triplet is the name, the second one is the
752 * arguments, and the third one is the flags. */
753
754AV *
755PerlIO_get_layers(pTHX_ PerlIO *f)
756{
97aff369 757 dVAR;
dcda55fc 758 AV * const av = newAV();
39f7a870 759
dcda55fc
AL
760 if (PerlIOValid(f)) {
761 PerlIOl *l = PerlIOBase(f);
762
763 while (l) {
92e45a3e
NC
764 /* There is some collusion in the implementation of
765 XS_PerlIO_get_layers - it knows that name and flags are
766 generated as fresh SVs here, and takes advantage of that to
767 "copy" them by taking a reference. If it changes here, it needs
768 to change there too. */
dcda55fc
AL
769 SV * const name = l->tab && l->tab->name ?
770 newSVpv(l->tab->name, 0) : &PL_sv_undef;
771 SV * const arg = l->tab && l->tab->Getarg ?
772 (*l->tab->Getarg)(aTHX_ &l, 0, 0) : &PL_sv_undef;
773 av_push(av, name);
774 av_push(av, arg);
775 av_push(av, newSViv((IV)l->flags));
776 l = l->next;
777 }
778 }
39f7a870 779
dcda55fc 780 return av;
39f7a870
JH
781}
782
9e353e3b 783/*--------------------------------------------------------------------------------------*/
14a5cf38 784/*
71200d45 785 * XS Interface for perl code
14a5cf38 786 */
9e353e3b 787
fcf2db38 788PerlIO_funcs *
2edd7e44 789PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
f3862f8b 790{
27da23d5 791 dVAR;
14a5cf38
JH
792 IV i;
793 if ((SSize_t) len <= 0)
794 len = strlen(name);
3a1ee7e8 795 for (i = 0; i < PL_known_layers->cur; i++) {
46c461b5 796 PerlIO_funcs * const f = PL_known_layers->array[i].funcs;
a9f76400 797 if (memEQ(f->name, name, len) && f->name[len] == 0) {
fe5a182c 798 PerlIO_debug("%.*s => %p\n", (int) len, name, (void*)f);
14a5cf38
JH
799 return f;
800 }
801 }
3a1ee7e8
NIS
802 if (load && PL_subname && PL_def_layerlist
803 && PL_def_layerlist->cur >= 2) {
d7a09b41
SR
804 if (PL_in_load_module) {
805 Perl_croak(aTHX_ "Recursive call to Perl_load_module in PerlIO_find_layer");
806 return NULL;
807 } else {
396482e1 808 SV * const pkgsv = newSVpvs("PerlIO");
46c461b5 809 SV * const layer = newSVpvn(name, len);
b96d8cd9 810 CV * const cv = get_cvs("PerlIO::Layer::NoWarnings", 0);
46c461b5 811 ENTER;
d7a09b41 812 SAVEINT(PL_in_load_module);
c9bca74a 813 if (cv) {
9cfa90c0 814 SAVEGENERICSV(PL_warnhook);
ad64d0ec 815 PL_warnhook = MUTABLE_SV((SvREFCNT_inc_simple_NN(cv)));
c9bca74a 816 }
d7a09b41
SR
817 PL_in_load_module++;
818 /*
819 * The two SVs are magically freed by load_module
820 */
a0714e2c 821 Perl_load_module(aTHX_ 0, pkgsv, NULL, layer, NULL);
d7a09b41
SR
822 PL_in_load_module--;
823 LEAVE;
824 return PerlIO_find_layer(aTHX_ name, len, 0);
825 }
14a5cf38
JH
826 }
827 PerlIO_debug("Cannot find %.*s\n", (int) len, name);
828 return NULL;
f3862f8b
NIS
829}
830
2a1bc955 831#ifdef USE_ATTRIBUTES_FOR_PERLIO
b13b2135
NIS
832
833static int
834perlio_mg_set(pTHX_ SV *sv, MAGIC *mg)
835{
14a5cf38 836 if (SvROK(sv)) {
159b6efe 837 IO * const io = GvIOn(MUTABLE_GV(SvRV(sv)));
dcda55fc
AL
838 PerlIO * const ifp = IoIFP(io);
839 PerlIO * const ofp = IoOFP(io);
be2597df
MHM
840 Perl_warn(aTHX_ "set %" SVf " %p %p %p",
841 SVfARG(sv), (void*)io, (void*)ifp, (void*)ofp);
14a5cf38
JH
842 }
843 return 0;
b13b2135
NIS
844}
845
846static int
847perlio_mg_get(pTHX_ SV *sv, MAGIC *mg)
848{
14a5cf38 849 if (SvROK(sv)) {
159b6efe 850 IO * const io = GvIOn(MUTABLE_GV(SvRV(sv)));
dcda55fc
AL
851 PerlIO * const ifp = IoIFP(io);
852 PerlIO * const ofp = IoOFP(io);
be2597df
MHM
853 Perl_warn(aTHX_ "get %" SVf " %p %p %p",
854 SVfARG(sv), (void*)io, (void*)ifp, (void*)ofp);
14a5cf38
JH
855 }
856 return 0;
b13b2135
NIS
857}
858
859static int
860perlio_mg_clear(pTHX_ SV *sv, MAGIC *mg)
861{
be2597df 862 Perl_warn(aTHX_ "clear %" SVf, SVfARG(sv));
14a5cf38 863 return 0;
b13b2135
NIS
864}
865
866static int
867perlio_mg_free(pTHX_ SV *sv, MAGIC *mg)
868{
be2597df 869 Perl_warn(aTHX_ "free %" SVf, SVfARG(sv));
14a5cf38 870 return 0;
b13b2135
NIS
871}
872
873MGVTBL perlio_vtab = {
14a5cf38
JH
874 perlio_mg_get,
875 perlio_mg_set,
22569500 876 NULL, /* len */
14a5cf38
JH
877 perlio_mg_clear,
878 perlio_mg_free
b13b2135
NIS
879};
880
881XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
882{
14a5cf38 883 dXSARGS;
dcda55fc
AL
884 SV * const sv = SvRV(ST(1));
885 AV * const av = newAV();
14a5cf38
JH
886 MAGIC *mg;
887 int count = 0;
888 int i;
ad64d0ec 889 sv_magic(sv, MUTABLE_SV(av), PERL_MAGIC_ext, NULL, 0);
14a5cf38
JH
890 SvRMAGICAL_off(sv);
891 mg = mg_find(sv, PERL_MAGIC_ext);
892 mg->mg_virtual = &perlio_vtab;
893 mg_magical(sv);
be2597df 894 Perl_warn(aTHX_ "attrib %" SVf, SVfARG(sv));
14a5cf38
JH
895 for (i = 2; i < items; i++) {
896 STRLEN len;
dcda55fc
AL
897 const char * const name = SvPV_const(ST(i), len);
898 SV * const layer = PerlIO_find_layer(aTHX_ name, len, 1);
14a5cf38 899 if (layer) {
b37c2d43 900 av_push(av, SvREFCNT_inc_simple_NN(layer));
14a5cf38
JH
901 }
902 else {
903 ST(count) = ST(i);
904 count++;
905 }
906 }
907 SvREFCNT_dec(av);
908 XSRETURN(count);
909}
910
22569500 911#endif /* USE_ATTIBUTES_FOR_PERLIO */
2a1bc955 912
e3f3bf95
NIS
913SV *
914PerlIO_tab_sv(pTHX_ PerlIO_funcs *tab)
f3862f8b 915{
da51bb9b 916 HV * const stash = gv_stashpvs("PerlIO::Layer", GV_ADD);
46c461b5 917 SV * const sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))), stash);
14a5cf38 918 return sv;
e3f3bf95
NIS
919}
920
5ca1d77f 921XS(XS_PerlIO__Layer__NoWarnings)
c9bca74a 922{
37725cdc 923 /* This is used as a %SIG{__WARN__} handler to supress warnings
c9bca74a
NIS
924 during loading of layers.
925 */
97aff369 926 dVAR;
c9bca74a 927 dXSARGS;
58c0efa5 928 PERL_UNUSED_ARG(cv);
c9bca74a 929 if (items)
e62f0680 930 PerlIO_debug("warning:%s\n",SvPV_nolen_const(ST(0)));
c9bca74a
NIS
931 XSRETURN(0);
932}
933
5ca1d77f 934XS(XS_PerlIO__Layer__find)
0c4f7ff0 935{
97aff369 936 dVAR;
14a5cf38 937 dXSARGS;
58c0efa5 938 PERL_UNUSED_ARG(cv);
14a5cf38
JH
939 if (items < 2)
940 Perl_croak(aTHX_ "Usage class->find(name[,load])");
941 else {
de009b76 942 STRLEN len;
46c461b5 943 const char * const name = SvPV_const(ST(1), len);
de009b76 944 const bool load = (items > 2) ? SvTRUE(ST(2)) : 0;
46c461b5 945 PerlIO_funcs * const layer = PerlIO_find_layer(aTHX_ name, len, load);
14a5cf38
JH
946 ST(0) =
947 (layer) ? sv_2mortal(PerlIO_tab_sv(aTHX_ layer)) :
948 &PL_sv_undef;
949 XSRETURN(1);
950 }
0c4f7ff0
NIS
951}
952
e3f3bf95
NIS
953void
954PerlIO_define_layer(pTHX_ PerlIO_funcs *tab)
955{
97aff369 956 dVAR;
3a1ee7e8
NIS
957 if (!PL_known_layers)
958 PL_known_layers = PerlIO_list_alloc(aTHX);
a0714e2c 959 PerlIO_list_push(aTHX_ PL_known_layers, tab, NULL);
fe5a182c 960 PerlIO_debug("define %s %p\n", tab->name, (void*)tab);
f3862f8b
NIS
961}
962
1141d9f8 963int
fcf2db38 964PerlIO_parse_layers(pTHX_ PerlIO_list_t *av, const char *names)
1141d9f8 965{
97aff369 966 dVAR;
14a5cf38
JH
967 if (names) {
968 const char *s = names;
969 while (*s) {
970 while (isSPACE(*s) || *s == ':')
971 s++;
972 if (*s) {
973 STRLEN llen = 0;
974 const char *e = s;
bd61b366 975 const char *as = NULL;
14a5cf38
JH
976 STRLEN alen = 0;
977 if (!isIDFIRST(*s)) {
978 /*
979 * Message is consistent with how attribute lists are
980 * passed. Even though this means "foo : : bar" is
71200d45 981 * seen as an invalid separator character.
14a5cf38 982 */
de009b76 983 const char q = ((*s == '\'') ? '"' : '\'');
99ef548b 984 if (ckWARN(WARN_LAYER))
22569500 985 Perl_warner(aTHX_ packWARN(WARN_LAYER),
b4581f09 986 "Invalid separator character %c%c%c in PerlIO layer specification %s",
1e616cf5 987 q, *s, q, s);
93189314 988 SETERRNO(EINVAL, LIB_INVARG);
14a5cf38
JH
989 return -1;
990 }
991 do {
992 e++;
993 } while (isALNUM(*e));
994 llen = e - s;
995 if (*e == '(') {
996 int nesting = 1;
997 as = ++e;
998 while (nesting) {
999 switch (*e++) {
1000 case ')':
1001 if (--nesting == 0)
1002 alen = (e - 1) - as;
1003 break;
1004 case '(':
1005 ++nesting;
1006 break;
1007 case '\\':
1008 /*
1009 * It's a nul terminated string, not allowed
1010 * to \ the terminating null. Anything other
71200d45 1011 * character is passed over.
14a5cf38
JH
1012 */
1013 if (*e++) {
1014 break;
1015 }
1016 /*
71200d45 1017 * Drop through
14a5cf38
JH
1018 */
1019 case '\0':
1020 e--;
22569500
NIS
1021 if (ckWARN(WARN_LAYER))
1022 Perl_warner(aTHX_ packWARN(WARN_LAYER),
b4581f09 1023 "Argument list not closed for PerlIO layer \"%.*s\"",
14a5cf38
JH
1024 (int) (e - s), s);
1025 return -1;
1026 default:
1027 /*
71200d45 1028 * boring.
14a5cf38
JH
1029 */
1030 break;
1031 }
1032 }
1033 }
1034 if (e > s) {
46c461b5 1035 PerlIO_funcs * const layer =
14a5cf38
JH
1036 PerlIO_find_layer(aTHX_ s, llen, 1);
1037 if (layer) {
a951d81d
BL
1038 SV *arg = NULL;
1039 if (as)
1040 arg = newSVpvn(as, alen);
3a1ee7e8 1041 PerlIO_list_push(aTHX_ av, layer,
a951d81d
BL
1042 (arg) ? arg : &PL_sv_undef);
1043 if (arg)
1044 SvREFCNT_dec(arg);
14a5cf38
JH
1045 }
1046 else {
041457d9 1047 if (ckWARN(WARN_LAYER))
b4581f09 1048 Perl_warner(aTHX_ packWARN(WARN_LAYER), "Unknown PerlIO layer \"%.*s\"",
14a5cf38
JH
1049 (int) llen, s);
1050 return -1;
1051 }
1052 }
1053 s = e;
1054 }
1055 }
1056 }
1057 return 0;
1141d9f8
NIS
1058}
1059
dfebf958 1060void
fcf2db38 1061PerlIO_default_buffer(pTHX_ PerlIO_list_t *av)
dfebf958 1062{
97aff369 1063 dVAR;
27da23d5 1064 PERLIO_FUNCS_DECL(*tab) = &PerlIO_perlio;
35990314 1065#ifdef PERLIO_USING_CRLF
6ce75a77 1066 tab = &PerlIO_crlf;
846be114 1067#else
6ce75a77 1068 if (PerlIO_stdio.Set_ptrcnt)
22569500 1069 tab = &PerlIO_stdio;
846be114 1070#endif
14a5cf38 1071 PerlIO_debug("Pushing %s\n", tab->name);
3a1ee7e8 1072 PerlIO_list_push(aTHX_ av, PerlIO_find_layer(aTHX_ tab->name, 0, 0),
14a5cf38 1073 &PL_sv_undef);
dfebf958
NIS
1074}
1075
e3f3bf95 1076SV *
14a5cf38 1077PerlIO_arg_fetch(PerlIO_list_t *av, IV n)
e3f3bf95 1078{
14a5cf38 1079 return av->array[n].arg;
e3f3bf95
NIS
1080}
1081
f3862f8b 1082PerlIO_funcs *
14a5cf38 1083PerlIO_layer_fetch(pTHX_ PerlIO_list_t *av, IV n, PerlIO_funcs *def)
f3862f8b 1084{
14a5cf38
JH
1085 if (n >= 0 && n < av->cur) {
1086 PerlIO_debug("Layer %" IVdf " is %s\n", n,
1087 av->array[n].funcs->name);
1088 return av->array[n].funcs;
1089 }
1090 if (!def)
1091 Perl_croak(aTHX_ "panic: PerlIO layer array corrupt");
1092 return def;
e3f3bf95
NIS
1093}
1094
4ec2216f
NIS
1095IV
1096PerlIOPop_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
1097{
8772537c
AL
1098 PERL_UNUSED_ARG(mode);
1099 PERL_UNUSED_ARG(arg);
1100 PERL_UNUSED_ARG(tab);
4ec2216f
NIS
1101 if (PerlIOValid(f)) {
1102 PerlIO_flush(f);
1103 PerlIO_pop(aTHX_ f);
1104 return 0;
1105 }
1106 return -1;
1107}
1108
27da23d5 1109PERLIO_FUNCS_DECL(PerlIO_remove) = {
4ec2216f
NIS
1110 sizeof(PerlIO_funcs),
1111 "pop",
1112 0,
1113 PERLIO_K_DUMMY | PERLIO_K_UTF8,
1114 PerlIOPop_pushed,
1115 NULL,
1116 NULL,
1117 NULL,
1118 NULL,
1119 NULL,
1120 NULL,
1121 NULL,
1122 NULL,
1123 NULL,
1124 NULL,
de009b76
AL
1125 NULL,
1126 NULL,
4ec2216f
NIS
1127 NULL, /* flush */
1128 NULL, /* fill */
1129 NULL,
1130 NULL,
1131 NULL,
1132 NULL,
1133 NULL, /* get_base */
1134 NULL, /* get_bufsiz */
1135 NULL, /* get_ptr */
1136 NULL, /* get_cnt */
1137 NULL, /* set_ptrcnt */
1138};
1139
fcf2db38 1140PerlIO_list_t *
e3f3bf95
NIS
1141PerlIO_default_layers(pTHX)
1142{
97aff369 1143 dVAR;
3a1ee7e8 1144 if (!PL_def_layerlist) {
bd61b366 1145 const char * const s = (PL_tainting) ? NULL : PerlEnv_getenv("PERLIO");
27da23d5 1146 PERLIO_FUNCS_DECL(*osLayer) = &PerlIO_unix;
3a1ee7e8 1147 PL_def_layerlist = PerlIO_list_alloc(aTHX);
27da23d5 1148 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_unix));
979e2c82 1149#if defined(WIN32)
27da23d5 1150 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_win32));
2f8118af 1151#if 0
14a5cf38 1152 osLayer = &PerlIO_win32;
0c4128ad 1153#endif
2f8118af 1154#endif
27da23d5
JH
1155 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_raw));
1156 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_perlio));
1157 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_stdio));
1158 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_crlf));
06da4f11 1159#ifdef HAS_MMAP
27da23d5 1160 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_mmap));
06da4f11 1161#endif
27da23d5
JH
1162 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_utf8));
1163 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_remove));
1164 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_byte));
3a1ee7e8 1165 PerlIO_list_push(aTHX_ PL_def_layerlist,
14a5cf38
JH
1166 PerlIO_find_layer(aTHX_ osLayer->name, 0, 0),
1167 &PL_sv_undef);
1168 if (s) {
3a1ee7e8 1169 PerlIO_parse_layers(aTHX_ PL_def_layerlist, s);
14a5cf38
JH
1170 }
1171 else {
3a1ee7e8 1172 PerlIO_default_buffer(aTHX_ PL_def_layerlist);
14a5cf38 1173 }
1141d9f8 1174 }
3a1ee7e8
NIS
1175 if (PL_def_layerlist->cur < 2) {
1176 PerlIO_default_buffer(aTHX_ PL_def_layerlist);
f3862f8b 1177 }
3a1ee7e8 1178 return PL_def_layerlist;
e3f3bf95
NIS
1179}
1180
0c4f7ff0
NIS
1181void
1182Perl_boot_core_PerlIO(pTHX)
1183{
1184#ifdef USE_ATTRIBUTES_FOR_PERLIO
14a5cf38
JH
1185 newXS("io::MODIFY_SCALAR_ATTRIBUTES", XS_io_MODIFY_SCALAR_ATTRIBUTES,
1186 __FILE__);
0c4f7ff0 1187#endif
14a5cf38 1188 newXS("PerlIO::Layer::find", XS_PerlIO__Layer__find, __FILE__);
c9bca74a 1189 newXS("PerlIO::Layer::NoWarnings", XS_PerlIO__Layer__NoWarnings, __FILE__);
0c4f7ff0 1190}
e3f3bf95
NIS
1191
1192PerlIO_funcs *
1193PerlIO_default_layer(pTHX_ I32 n)
1194{
97aff369 1195 dVAR;
46c461b5 1196 PerlIO_list_t * const av = PerlIO_default_layers(aTHX);
14a5cf38
JH
1197 if (n < 0)
1198 n += av->cur;
27da23d5 1199 return PerlIO_layer_fetch(aTHX_ av, n, PERLIO_FUNCS_CAST(&PerlIO_stdio));
f3862f8b
NIS
1200}
1201
a999f61b
NIS
1202#define PerlIO_default_top() PerlIO_default_layer(aTHX_ -1)
1203#define PerlIO_default_btm() PerlIO_default_layer(aTHX_ 0)
60382766
NIS
1204
1205void
1141d9f8 1206PerlIO_stdstreams(pTHX)
60382766 1207{
97aff369 1208 dVAR;
a1ea730d 1209 if (!PL_perlio) {
14a5cf38
JH
1210 PerlIO_allocate(aTHX);
1211 PerlIO_fdopen(0, "Ir" PERLIO_STDTEXT);
1212 PerlIO_fdopen(1, "Iw" PERLIO_STDTEXT);
1213 PerlIO_fdopen(2, "Iw" PERLIO_STDTEXT);
1214 }
60382766
NIS
1215}
1216
1217PerlIO *
27da23d5 1218PerlIO_push(pTHX_ PerlIO *f, PERLIO_FUNCS_DECL(*tab), const char *mode, SV *arg)
14a5cf38 1219{
2dc2558e
NIS
1220 if (tab->fsize != sizeof(PerlIO_funcs)) {
1221 mismatch:
1222 Perl_croak(aTHX_ "Layer does not match this perl");
1223 }
1224 if (tab->size) {
b464bac0 1225 PerlIOl *l;
2dc2558e
NIS
1226 if (tab->size < sizeof(PerlIOl)) {
1227 goto mismatch;
1228 }
1229 /* Real layer with a data area */
002e75cf
JH
1230 if (f) {
1231 char *temp;
1232 Newxz(temp, tab->size, char);
1233 l = (PerlIOl*)temp;
1234 if (l) {
1235 l->next = *f;
1236 l->tab = (PerlIO_funcs*) tab;
1237 *f = l;
1238 PerlIO_debug("PerlIO_push f=%p %s %s %p\n",
1239 (void*)f, tab->name,
1240 (mode) ? mode : "(Null)", (void*)arg);
1241 if (*l->tab->Pushed &&
1242 (*l->tab->Pushed)
1243 (aTHX_ f, mode, arg, (PerlIO_funcs*) tab) != 0) {
1244 PerlIO_pop(aTHX_ f);
1245 return NULL;
1246 }
2dc2558e 1247 }
002e75cf
JH
1248 else
1249 return NULL;
2dc2558e
NIS
1250 }
1251 }
1252 else if (f) {
1253 /* Pseudo-layer where push does its own stack adjust */
00f51856
NIS
1254 PerlIO_debug("PerlIO_push f=%p %s %s %p\n", (void*)f, tab->name,
1255 (mode) ? mode : "(Null)", (void*)arg);
210e727c 1256 if (tab->Pushed &&
27da23d5 1257 (*tab->Pushed) (aTHX_ f, mode, arg, (PerlIO_funcs*) tab) != 0) {
210e727c 1258 return NULL;
14a5cf38
JH
1259 }
1260 }
1261 return f;
60382766
NIS
1262}
1263
dfebf958 1264IV
86e05cf2
NIS
1265PerlIOBase_binmode(pTHX_ PerlIO *f)
1266{
1267 if (PerlIOValid(f)) {
1268 /* Is layer suitable for raw stream ? */
1269 if (PerlIOBase(f)->tab->kind & PERLIO_K_RAW) {
1270 /* Yes - turn off UTF-8-ness, to undo UTF-8 locale effects */
1271 PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
1272 }
1273 else {
1274 /* Not suitable - pop it */
1275 PerlIO_pop(aTHX_ f);
1276 }
1277 return 0;
1278 }
1279 return -1;
1280}
1281
1282IV
2dc2558e 1283PerlIORaw_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
dfebf958 1284{
8772537c
AL
1285 PERL_UNUSED_ARG(mode);
1286 PERL_UNUSED_ARG(arg);
1287 PERL_UNUSED_ARG(tab);
86e05cf2 1288
04892f78 1289 if (PerlIOValid(f)) {
86e05cf2 1290 PerlIO *t;
de009b76 1291 const PerlIOl *l;
14a5cf38 1292 PerlIO_flush(f);
86e05cf2
NIS
1293 /*
1294 * Strip all layers that are not suitable for a raw stream
1295 */
1296 t = f;
1297 while (t && (l = *t)) {
1298 if (l->tab->Binmode) {
1299 /* Has a handler - normal case */
9d97e8b8 1300 if ((*l->tab->Binmode)(aTHX_ t) == 0) {
86e05cf2
NIS
1301 if (*t == l) {
1302 /* Layer still there - move down a layer */
1303 t = PerlIONext(t);
1304 }
1305 }
1306 else {
1307 return -1;
1308 }
14a5cf38
JH
1309 }
1310 else {
86e05cf2
NIS
1311 /* No handler - pop it */
1312 PerlIO_pop(aTHX_ t);
14a5cf38
JH
1313 }
1314 }
86e05cf2
NIS
1315 if (PerlIOValid(f)) {
1316 PerlIO_debug(":raw f=%p :%s\n", (void*)f, PerlIOBase(f)->tab->name);
1317 return 0;
1318 }
14a5cf38
JH
1319 }
1320 return -1;
dfebf958
NIS
1321}
1322
ac27b0f5 1323int
14a5cf38 1324PerlIO_apply_layera(pTHX_ PerlIO *f, const char *mode,
d9dac8cd 1325 PerlIO_list_t *layers, IV n, IV max)
14a5cf38 1326{
14a5cf38
JH
1327 int code = 0;
1328 while (n < max) {
8772537c 1329 PerlIO_funcs * const tab = PerlIO_layer_fetch(aTHX_ layers, n, NULL);
14a5cf38
JH
1330 if (tab) {
1331 if (!PerlIO_push(aTHX_ f, tab, mode, PerlIOArg)) {
1332 code = -1;
1333 break;
1334 }
1335 }
1336 n++;
1337 }
1338 return code;
e3f3bf95
NIS
1339}
1340
1341int
ac27b0f5
NIS
1342PerlIO_apply_layers(pTHX_ PerlIO *f, const char *mode, const char *names)
1343{
14a5cf38 1344 int code = 0;
53f1b6d2 1345 if (f && names) {
8772537c 1346 PerlIO_list_t * const layers = PerlIO_list_alloc(aTHX);
14a5cf38
JH
1347 code = PerlIO_parse_layers(aTHX_ layers, names);
1348 if (code == 0) {
d9dac8cd 1349 code = PerlIO_apply_layera(aTHX_ f, mode, layers, 0, layers->cur);
14a5cf38 1350 }
3a1ee7e8 1351 PerlIO_list_free(aTHX_ layers);
ac27b0f5 1352 }
14a5cf38 1353 return code;
ac27b0f5
NIS
1354}
1355
f3862f8b 1356
60382766 1357/*--------------------------------------------------------------------------------------*/
14a5cf38 1358/*
71200d45 1359 * Given the abstraction above the public API functions
14a5cf38 1360 */
60382766
NIS
1361
1362int
f5b9d040 1363PerlIO_binmode(pTHX_ PerlIO *f, int iotype, int mode, const char *names)
76ced9ad 1364{
68b5363f
PD
1365 PerlIO_debug("PerlIO_binmode f=%p %s %c %x %s\n", (void*)f,
1366 (PerlIOBase(f)) ? PerlIOBase(f)->tab->name : "(Null)",
1367 iotype, mode, (names) ? names : "(Null)");
1368
03c0554d
NIS
1369 if (names) {
1370 /* Do not flush etc. if (e.g.) switching encodings.
1371 if a pushed layer knows it needs to flush lower layers
1372 (for example :unix which is never going to call them)
1373 it can do the flush when it is pushed.
1374 */
1375 return PerlIO_apply_layers(aTHX_ f, NULL, names) == 0 ? TRUE : FALSE;
1376 }
1377 else {
86e05cf2 1378 /* Fake 5.6 legacy of using this call to turn ON O_TEXT */
35990314 1379#ifdef PERLIO_USING_CRLF
03c0554d
NIS
1380 /* Legacy binmode only has meaning if O_TEXT has a value distinct from
1381 O_BINARY so we can look for it in mode.
1382 */
1383 if (!(mode & O_BINARY)) {
1384 /* Text mode */
86e05cf2
NIS
1385 /* FIXME?: Looking down the layer stack seems wrong,
1386 but is a way of reaching past (say) an encoding layer
1387 to flip CRLF-ness of the layer(s) below
1388 */
03c0554d
NIS
1389 while (*f) {
1390 /* Perhaps we should turn on bottom-most aware layer
1391 e.g. Ilya's idea that UNIX TTY could serve
1392 */
1393 if (PerlIOBase(f)->tab->kind & PERLIO_K_CANCRLF) {
1394 if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF)) {
1395 /* Not in text mode - flush any pending stuff and flip it */
1396 PerlIO_flush(f);
1397 PerlIOBase(f)->flags |= PERLIO_F_CRLF;
1398 }
1399 /* Only need to turn it on in one layer so we are done */
1400 return TRUE;
ed53a2bb 1401 }
03c0554d 1402 f = PerlIONext(f);
14a5cf38 1403 }
03c0554d
NIS
1404 /* Not finding a CRLF aware layer presumably means we are binary
1405 which is not what was requested - so we failed
1406 We _could_ push :crlf layer but so could caller
1407 */
1408 return FALSE;
14a5cf38 1409 }
6ce75a77 1410#endif
86e05cf2
NIS
1411 /* Legacy binmode is now _defined_ as being equivalent to pushing :raw
1412 So code that used to be here is now in PerlIORaw_pushed().
03c0554d 1413 */
a0714e2c 1414 return PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_raw), NULL, NULL) ? TRUE : FALSE;
14a5cf38 1415 }
f5b9d040
NIS
1416}
1417
f5b9d040 1418int
e87a358a 1419PerlIO__close(pTHX_ PerlIO *f)
f5b9d040 1420{
37725cdc 1421 if (PerlIOValid(f)) {
46c461b5 1422 PerlIO_funcs * const tab = PerlIOBase(f)->tab;
37725cdc
NIS
1423 if (tab && tab->Close)
1424 return (*tab->Close)(aTHX_ f);
1425 else
1426 return PerlIOBase_close(aTHX_ f);
1427 }
14a5cf38 1428 else {
93189314 1429 SETERRNO(EBADF, SS_IVCHAN);
14a5cf38
JH
1430 return -1;
1431 }
76ced9ad
NIS
1432}
1433
b931b1d9 1434int
e87a358a 1435Perl_PerlIO_close(pTHX_ PerlIO *f)
b931b1d9 1436{
de009b76 1437 const int code = PerlIO__close(aTHX_ f);
37725cdc
NIS
1438 while (PerlIOValid(f)) {
1439 PerlIO_pop(aTHX_ f);
f6c77cf1 1440 }
14a5cf38 1441 return code;
b931b1d9
NIS
1442}
1443
b931b1d9 1444int
e87a358a 1445Perl_PerlIO_fileno(pTHX_ PerlIO *f)
b931b1d9 1446{
97aff369 1447 dVAR;
b32dd47e 1448 Perl_PerlIO_or_Base(f, Fileno, fileno, -1, (aTHX_ f));
b931b1d9
NIS
1449}
1450
1141d9f8 1451
fcf2db38 1452static PerlIO_funcs *
2edd7e44
NIS
1453PerlIO_layer_from_ref(pTHX_ SV *sv)
1454{
97aff369 1455 dVAR;
14a5cf38 1456 /*
71200d45 1457 * For any scalar type load the handler which is bundled with perl
14a5cf38 1458 */
75208dda
RGS
1459 if (SvTYPE(sv) < SVt_PVAV) {
1460 PerlIO_funcs *f = PerlIO_find_layer(aTHX_ STR_WITH_LEN("scalar"), 1);
1461 /* This isn't supposed to happen, since PerlIO::scalar is core,
1462 * but could happen anyway in smaller installs or with PAR */
1463 if (!f && ckWARN(WARN_LAYER))
1464 Perl_warner(aTHX_ packWARN(WARN_LAYER), "Unknown PerlIO layer \"scalar\"");
1465 return f;
1466 }
14a5cf38
JH
1467
1468 /*
71200d45 1469 * For other types allow if layer is known but don't try and load it
14a5cf38
JH
1470 */
1471 switch (SvTYPE(sv)) {
1472 case SVt_PVAV:
6a245ed1 1473 return PerlIO_find_layer(aTHX_ STR_WITH_LEN("Array"), 0);
14a5cf38 1474 case SVt_PVHV:
6a245ed1 1475 return PerlIO_find_layer(aTHX_ STR_WITH_LEN("Hash"), 0);
14a5cf38 1476 case SVt_PVCV:
6a245ed1 1477 return PerlIO_find_layer(aTHX_ STR_WITH_LEN("Code"), 0);
14a5cf38 1478 case SVt_PVGV:
6a245ed1 1479 return PerlIO_find_layer(aTHX_ STR_WITH_LEN("Glob"), 0);
42d0e0b7
AL
1480 default:
1481 return NULL;
14a5cf38 1482 }
2edd7e44
NIS
1483}
1484
fcf2db38 1485PerlIO_list_t *
14a5cf38
JH
1486PerlIO_resolve_layers(pTHX_ const char *layers,
1487 const char *mode, int narg, SV **args)
1488{
97aff369 1489 dVAR;
14a5cf38
JH
1490 PerlIO_list_t *def = PerlIO_default_layers(aTHX);
1491 int incdef = 1;
a1ea730d 1492 if (!PL_perlio)
14a5cf38
JH
1493 PerlIO_stdstreams(aTHX);
1494 if (narg) {
dcda55fc 1495 SV * const arg = *args;
14a5cf38 1496 /*
71200d45
NIS
1497 * If it is a reference but not an object see if we have a handler
1498 * for it
14a5cf38
JH
1499 */
1500 if (SvROK(arg) && !sv_isobject(arg)) {
46c461b5 1501 PerlIO_funcs * const handler = PerlIO_layer_from_ref(aTHX_ SvRV(arg));
14a5cf38 1502 if (handler) {
3a1ee7e8
NIS
1503 def = PerlIO_list_alloc(aTHX);
1504 PerlIO_list_push(aTHX_ def, handler, &PL_sv_undef);
14a5cf38
JH
1505 incdef = 0;
1506 }
1507 /*
e934609f 1508 * Don't fail if handler cannot be found :via(...) etc. may do
14a5cf38 1509 * something sensible else we will just stringfy and open
71200d45 1510 * resulting string.
14a5cf38
JH
1511 */
1512 }
1513 }
9fe371da 1514 if (!layers || !*layers)
11bcd5da 1515 layers = Perl_PerlIO_context_layers(aTHX_ mode);
14a5cf38
JH
1516 if (layers && *layers) {
1517 PerlIO_list_t *av;
1518 if (incdef) {
a951d81d 1519 av = PerlIO_clone_list(aTHX_ def, NULL);
14a5cf38
JH
1520 }
1521 else {
1522 av = def;
1523 }
0cff2cf3
NIS
1524 if (PerlIO_parse_layers(aTHX_ av, layers) == 0) {
1525 return av;
1526 }
1527 else {
1528 PerlIO_list_free(aTHX_ av);
b37c2d43 1529 return NULL;
0cff2cf3 1530 }
14a5cf38
JH
1531 }
1532 else {
1533 if (incdef)
1534 def->refcnt++;
1535 return def;
1536 }
ee518936
NIS
1537}
1538
1539PerlIO *
14a5cf38
JH
1540PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
1541 int imode, int perm, PerlIO *f, int narg, SV **args)
1542{
97aff369 1543 dVAR;
14a5cf38
JH
1544 if (!f && narg == 1 && *args == &PL_sv_undef) {
1545 if ((f = PerlIO_tmpfile())) {
9fe371da 1546 if (!layers || !*layers)
11bcd5da 1547 layers = Perl_PerlIO_context_layers(aTHX_ mode);
14a5cf38
JH
1548 if (layers && *layers)
1549 PerlIO_apply_layers(aTHX_ f, mode, layers);
1550 }
1551 }
1552 else {
de009b76 1553 PerlIO_list_t *layera;
14a5cf38
JH
1554 IV n;
1555 PerlIO_funcs *tab = NULL;
04892f78 1556 if (PerlIOValid(f)) {
14a5cf38 1557 /*
71200d45
NIS
1558 * This is "reopen" - it is not tested as perl does not use it
1559 * yet
14a5cf38
JH
1560 */
1561 PerlIOl *l = *f;
3a1ee7e8 1562 layera = PerlIO_list_alloc(aTHX);
14a5cf38 1563 while (l) {
a951d81d
BL
1564 SV *arg = NULL;
1565 if (l->tab->Getarg)
1566 arg = (*l->tab->Getarg) (aTHX_ &l, NULL, 0);
1567 PerlIO_list_push(aTHX_ layera, l->tab,
1568 (arg) ? arg : &PL_sv_undef);
1569 if (arg)
1570 SvREFCNT_dec(arg);
14a5cf38
JH
1571 l = *PerlIONext(&l);
1572 }
1573 }
1574 else {
1575 layera = PerlIO_resolve_layers(aTHX_ layers, mode, narg, args);
0cff2cf3
NIS
1576 if (!layera) {
1577 return NULL;
1578 }
14a5cf38
JH
1579 }
1580 /*
71200d45 1581 * Start at "top" of layer stack
14a5cf38
JH
1582 */
1583 n = layera->cur - 1;
1584 while (n >= 0) {
46c461b5 1585 PerlIO_funcs * const t = PerlIO_layer_fetch(aTHX_ layera, n, NULL);
14a5cf38
JH
1586 if (t && t->Open) {
1587 tab = t;
1588 break;
1589 }
1590 n--;
1591 }
1592 if (tab) {
1593 /*
71200d45 1594 * Found that layer 'n' can do opens - call it
14a5cf38 1595 */
7cf31beb 1596 if (narg > 1 && !(tab->kind & PERLIO_K_MULTIARG)) {
3b8752bb 1597 Perl_croak(aTHX_ "More than one argument to open(,':%s')",tab->name);
7cf31beb 1598 }
14a5cf38 1599 PerlIO_debug("openn(%s,'%s','%s',%d,%x,%o,%p,%d,%p)\n",
355d3743
PD
1600 tab->name, layers ? layers : "(Null)", mode, fd,
1601 imode, perm, (void*)f, narg, (void*)args);
210e727c
JH
1602 if (tab->Open)
1603 f = (*tab->Open) (aTHX_ tab, layera, n, mode, fd, imode, perm,
1604 f, narg, args);
1605 else {
1606 SETERRNO(EINVAL, LIB_INVARG);
1607 f = NULL;
1608 }
14a5cf38
JH
1609 if (f) {
1610 if (n + 1 < layera->cur) {
1611 /*
1612 * More layers above the one that we used to open -
71200d45 1613 * apply them now
14a5cf38 1614 */
d9dac8cd
NIS
1615 if (PerlIO_apply_layera(aTHX_ f, mode, layera, n + 1, layera->cur) != 0) {
1616 /* If pushing layers fails close the file */
1617 PerlIO_close(f);
14a5cf38
JH
1618 f = NULL;
1619 }
1620 }
1621 }
1622 }
3a1ee7e8 1623 PerlIO_list_free(aTHX_ layera);
14a5cf38
JH
1624 }
1625 return f;
ee518936 1626}
b931b1d9
NIS
1627
1628
9e353e3b 1629SSize_t
e87a358a 1630Perl_PerlIO_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 1631{
7918f24d
NC
1632 PERL_ARGS_ASSERT_PERLIO_READ;
1633
b32dd47e 1634 Perl_PerlIO_or_Base(f, Read, read, -1, (aTHX_ f, vbuf, count));
760ac839
LW
1635}
1636
313ca112 1637SSize_t
e87a358a 1638Perl_PerlIO_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
760ac839 1639{
7918f24d
NC
1640 PERL_ARGS_ASSERT_PERLIO_UNREAD;
1641
b32dd47e 1642 Perl_PerlIO_or_Base(f, Unread, unread, -1, (aTHX_ f, vbuf, count));
760ac839
LW
1643}
1644
9e353e3b 1645SSize_t
e87a358a 1646Perl_PerlIO_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
760ac839 1647{
7918f24d
NC
1648 PERL_ARGS_ASSERT_PERLIO_WRITE;
1649
b32dd47e 1650 Perl_PerlIO_or_fail(f, Write, -1, (aTHX_ f, vbuf, count));
760ac839
LW
1651}
1652
6f9d8c32 1653int
e87a358a 1654Perl_PerlIO_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
760ac839 1655{
b32dd47e 1656 Perl_PerlIO_or_fail(f, Seek, -1, (aTHX_ f, offset, whence));
760ac839
LW
1657}
1658
9e353e3b 1659Off_t
e87a358a 1660Perl_PerlIO_tell(pTHX_ PerlIO *f)
760ac839 1661{
b32dd47e 1662 Perl_PerlIO_or_fail(f, Tell, -1, (aTHX_ f));
760ac839
LW
1663}
1664
6f9d8c32 1665int
e87a358a 1666Perl_PerlIO_flush(pTHX_ PerlIO *f)
760ac839 1667{
97aff369 1668 dVAR;
14a5cf38
JH
1669 if (f) {
1670 if (*f) {
de009b76 1671 const PerlIO_funcs *tab = PerlIOBase(f)->tab;
1b7a0411
JH
1672
1673 if (tab && tab->Flush)
f62ce20a 1674 return (*tab->Flush) (aTHX_ f);
1b7a0411
JH
1675 else
1676 return 0; /* If no Flush defined, silently succeed. */
14a5cf38
JH
1677 }
1678 else {
fe5a182c 1679 PerlIO_debug("Cannot flush f=%p\n", (void*)f);
93189314 1680 SETERRNO(EBADF, SS_IVCHAN);
14a5cf38
JH
1681 return -1;
1682 }
1683 }
1684 else {
1685 /*
1686 * Is it good API design to do flush-all on NULL, a potentially
1687 * errorneous input? Maybe some magical value (PerlIO*
1688 * PERLIO_FLUSH_ALL = (PerlIO*)-1;)? Yes, stdio does similar
1689 * things on fflush(NULL), but should we be bound by their design
71200d45 1690 * decisions? --jhi
14a5cf38 1691 */
a1ea730d 1692 PerlIO **table = &PL_perlio;
14a5cf38
JH
1693 int code = 0;
1694 while ((f = *table)) {
1695 int i;
1696 table = (PerlIO **) (f++);
1697 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
1698 if (*f && PerlIO_flush(f) != 0)
1699 code = -1;
1700 f++;
1701 }
1702 }
1703 return code;
1704 }
760ac839
LW
1705}
1706
a9c883f6 1707void
f62ce20a 1708PerlIOBase_flush_linebuf(pTHX)
a9c883f6 1709{
97aff369 1710 dVAR;
a1ea730d 1711 PerlIO **table = &PL_perlio;
14a5cf38
JH
1712 PerlIO *f;
1713 while ((f = *table)) {
1714 int i;
1715 table = (PerlIO **) (f++);
1716 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
1717 if (*f
1718 && (PerlIOBase(f)->
1719 flags & (PERLIO_F_LINEBUF | PERLIO_F_CANWRITE))
1720 == (PERLIO_F_LINEBUF | PERLIO_F_CANWRITE))
1721 PerlIO_flush(f);
1722 f++;
1723 }
a9c883f6 1724 }
a9c883f6
NIS
1725}
1726
06da4f11 1727int
e87a358a 1728Perl_PerlIO_fill(pTHX_ PerlIO *f)
06da4f11 1729{
b32dd47e 1730 Perl_PerlIO_or_fail(f, Fill, -1, (aTHX_ f));
06da4f11
NIS
1731}
1732
f3862f8b
NIS
1733int
1734PerlIO_isutf8(PerlIO *f)
1735{
1b7a0411
JH
1736 if (PerlIOValid(f))
1737 return (PerlIOBase(f)->flags & PERLIO_F_UTF8) != 0;
1738 else
1739 SETERRNO(EBADF, SS_IVCHAN);
37725cdc 1740
1b7a0411 1741 return -1;
f3862f8b
NIS
1742}
1743
6f9d8c32 1744int
e87a358a 1745Perl_PerlIO_eof(pTHX_ PerlIO *f)
760ac839 1746{
b32dd47e 1747 Perl_PerlIO_or_Base(f, Eof, eof, -1, (aTHX_ f));
9e353e3b
NIS
1748}
1749
9e353e3b 1750int
e87a358a 1751Perl_PerlIO_error(pTHX_ PerlIO *f)
9e353e3b 1752{
b32dd47e 1753 Perl_PerlIO_or_Base(f, Error, error, -1, (aTHX_ f));
9e353e3b
NIS
1754}
1755
9e353e3b 1756void
e87a358a 1757Perl_PerlIO_clearerr(pTHX_ PerlIO *f)
9e353e3b 1758{
b32dd47e 1759 Perl_PerlIO_or_Base_void(f, Clearerr, clearerr, (aTHX_ f));
9e353e3b
NIS
1760}
1761
9e353e3b 1762void
e87a358a 1763Perl_PerlIO_setlinebuf(pTHX_ PerlIO *f)
9e353e3b 1764{
b32dd47e 1765 Perl_PerlIO_or_Base_void(f, Setlinebuf, setlinebuf, (aTHX_ f));
9e353e3b
NIS
1766}
1767
9e353e3b
NIS
1768int
1769PerlIO_has_base(PerlIO *f)
1770{
1b7a0411 1771 if (PerlIOValid(f)) {
46c461b5 1772 const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
1b7a0411
JH
1773
1774 if (tab)
1775 return (tab->Get_base != NULL);
1b7a0411 1776 }
1b7a0411
JH
1777
1778 return 0;
760ac839
LW
1779}
1780
9e353e3b
NIS
1781int
1782PerlIO_fast_gets(PerlIO *f)
760ac839 1783{
d7dfc388
SK
1784 if (PerlIOValid(f)) {
1785 if (PerlIOBase(f)->flags & PERLIO_F_FASTGETS) {
1786 const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
1b7a0411 1787
d7dfc388
SK
1788 if (tab)
1789 return (tab->Set_ptrcnt != NULL);
d7dfc388 1790 }
14a5cf38 1791 }
1b7a0411 1792
14a5cf38 1793 return 0;
9e353e3b
NIS
1794}
1795
9e353e3b
NIS
1796int
1797PerlIO_has_cntptr(PerlIO *f)
1798{
04892f78 1799 if (PerlIOValid(f)) {
46c461b5 1800 const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
1b7a0411
JH
1801
1802 if (tab)
1803 return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
14a5cf38 1804 }
1b7a0411 1805
14a5cf38 1806 return 0;
9e353e3b
NIS
1807}
1808
9e353e3b
NIS
1809int
1810PerlIO_canset_cnt(PerlIO *f)
1811{
04892f78 1812 if (PerlIOValid(f)) {
46c461b5 1813 const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
1b7a0411
JH
1814
1815 if (tab)
1816 return (tab->Set_ptrcnt != NULL);
14a5cf38 1817 }
1b7a0411 1818
14a5cf38 1819 return 0;
760ac839
LW
1820}
1821
888911fc 1822STDCHAR *
e87a358a 1823Perl_PerlIO_get_base(pTHX_ PerlIO *f)
760ac839 1824{
b32dd47e 1825 Perl_PerlIO_or_fail(f, Get_base, NULL, (aTHX_ f));
9e353e3b
NIS
1826}
1827
9e353e3b 1828int
e87a358a 1829Perl_PerlIO_get_bufsiz(pTHX_ PerlIO *f)
9e353e3b 1830{
b32dd47e 1831 Perl_PerlIO_or_fail(f, Get_bufsiz, -1, (aTHX_ f));
9e353e3b
NIS
1832}
1833
9e353e3b 1834STDCHAR *
e87a358a 1835Perl_PerlIO_get_ptr(pTHX_ PerlIO *f)
9e353e3b 1836{
b32dd47e 1837 Perl_PerlIO_or_fail(f, Get_ptr, NULL, (aTHX_ f));
9e353e3b
NIS
1838}
1839
05d1247b 1840int
e87a358a 1841Perl_PerlIO_get_cnt(pTHX_ PerlIO *f)
9e353e3b 1842{
b32dd47e 1843 Perl_PerlIO_or_fail(f, Get_cnt, -1, (aTHX_ f));
9e353e3b
NIS
1844}
1845
9e353e3b 1846void
e87a358a 1847Perl_PerlIO_set_cnt(pTHX_ PerlIO *f, int cnt)
9e353e3b 1848{
b32dd47e 1849 Perl_PerlIO_or_fail_void(f, Set_ptrcnt, (aTHX_ f, NULL, cnt));
9e353e3b
NIS
1850}
1851
9e353e3b 1852void
e87a358a 1853Perl_PerlIO_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, int cnt)
9e353e3b 1854{
b32dd47e 1855 Perl_PerlIO_or_fail_void(f, Set_ptrcnt, (aTHX_ f, ptr, cnt));
9e353e3b
NIS
1856}
1857
4ec2216f 1858
9e353e3b 1859/*--------------------------------------------------------------------------------------*/
14a5cf38 1860/*
71200d45 1861 * utf8 and raw dummy layers
14a5cf38 1862 */
dfebf958 1863
26fb694e 1864IV
2dc2558e 1865PerlIOUtf8_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
26fb694e 1866{
96a5add6 1867 PERL_UNUSED_CONTEXT;
8772537c
AL
1868 PERL_UNUSED_ARG(mode);
1869 PERL_UNUSED_ARG(arg);
00f51856 1870 if (PerlIOValid(f)) {
14a5cf38
JH
1871 if (tab->kind & PERLIO_K_UTF8)
1872 PerlIOBase(f)->flags |= PERLIO_F_UTF8;
1873 else
1874 PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
1875 return 0;
1876 }
1877 return -1;
26fb694e
NIS
1878}
1879
27da23d5 1880PERLIO_FUNCS_DECL(PerlIO_utf8) = {
2dc2558e 1881 sizeof(PerlIO_funcs),
14a5cf38 1882 "utf8",
2dc2558e 1883 0,
6874a2de 1884 PERLIO_K_DUMMY | PERLIO_K_UTF8,
14a5cf38
JH
1885 PerlIOUtf8_pushed,
1886 NULL,
1887 NULL,
1888 NULL,
1889 NULL,
1890 NULL,
1891 NULL,
1892 NULL,
1893 NULL,
1894 NULL,
1895 NULL,
de009b76
AL
1896 NULL,
1897 NULL,
22569500
NIS
1898 NULL, /* flush */
1899 NULL, /* fill */
14a5cf38
JH
1900 NULL,
1901 NULL,
1902 NULL,
1903 NULL,
22569500
NIS
1904 NULL, /* get_base */
1905 NULL, /* get_bufsiz */
1906 NULL, /* get_ptr */
1907 NULL, /* get_cnt */
1908 NULL, /* set_ptrcnt */
26fb694e
NIS
1909};
1910
27da23d5 1911PERLIO_FUNCS_DECL(PerlIO_byte) = {
2dc2558e 1912 sizeof(PerlIO_funcs),
14a5cf38 1913 "bytes",
2dc2558e 1914 0,
14a5cf38
JH
1915 PERLIO_K_DUMMY,
1916 PerlIOUtf8_pushed,
1917 NULL,
1918 NULL,
1919 NULL,
1920 NULL,
1921 NULL,
1922 NULL,
1923 NULL,
1924 NULL,
1925 NULL,
1926 NULL,
de009b76
AL
1927 NULL,
1928 NULL,
22569500
NIS
1929 NULL, /* flush */
1930 NULL, /* fill */
14a5cf38
JH
1931 NULL,
1932 NULL,
1933 NULL,
1934 NULL,
22569500
NIS
1935 NULL, /* get_base */
1936 NULL, /* get_bufsiz */
1937 NULL, /* get_ptr */
1938 NULL, /* get_cnt */
1939 NULL, /* set_ptrcnt */
dfebf958
NIS
1940};
1941
1942PerlIO *
14a5cf38
JH
1943PerlIORaw_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
1944 IV n, const char *mode, int fd, int imode, int perm,
1945 PerlIO *old, int narg, SV **args)
dfebf958 1946{
8772537c
AL
1947 PerlIO_funcs * const tab = PerlIO_default_btm();
1948 PERL_UNUSED_ARG(self);
210e727c
JH
1949 if (tab && tab->Open)
1950 return (*tab->Open) (aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
1951 old, narg, args);
1952 SETERRNO(EINVAL, LIB_INVARG);
1953 return NULL;
dfebf958
NIS
1954}
1955
27da23d5 1956PERLIO_FUNCS_DECL(PerlIO_raw) = {
2dc2558e 1957 sizeof(PerlIO_funcs),
14a5cf38 1958 "raw",
2dc2558e 1959 0,
14a5cf38
JH
1960 PERLIO_K_DUMMY,
1961 PerlIORaw_pushed,
1962 PerlIOBase_popped,
1963 PerlIORaw_open,
1964 NULL,
1965 NULL,
1966 NULL,
1967 NULL,
1968 NULL,
1969 NULL,
1970 NULL,
1971 NULL,
de009b76
AL
1972 NULL,
1973 NULL,
22569500
NIS
1974 NULL, /* flush */
1975 NULL, /* fill */
14a5cf38
JH
1976 NULL,
1977 NULL,
1978 NULL,
1979 NULL,
22569500
NIS
1980 NULL, /* get_base */
1981 NULL, /* get_bufsiz */
1982 NULL, /* get_ptr */
1983 NULL, /* get_cnt */
1984 NULL, /* set_ptrcnt */
dfebf958
NIS
1985};
1986/*--------------------------------------------------------------------------------------*/
1987/*--------------------------------------------------------------------------------------*/
14a5cf38 1988/*
71200d45 1989 * "Methods" of the "base class"
14a5cf38 1990 */
9e353e3b
NIS
1991
1992IV
f62ce20a 1993PerlIOBase_fileno(pTHX_ PerlIO *f)
9e353e3b 1994{
04892f78 1995 return PerlIOValid(f) ? PerlIO_fileno(PerlIONext(f)) : -1;
9e353e3b
NIS
1996}
1997
f5b9d040 1998char *
81428673 1999PerlIO_modestr(PerlIO * f, char *buf)
14a5cf38
JH
2000{
2001 char *s = buf;
81428673 2002 if (PerlIOValid(f)) {
de009b76 2003 const IV flags = PerlIOBase(f)->flags;
81428673
NIS
2004 if (flags & PERLIO_F_APPEND) {
2005 *s++ = 'a';
2006 if (flags & PERLIO_F_CANREAD) {
2007 *s++ = '+';
2008 }
14a5cf38 2009 }
81428673
NIS
2010 else if (flags & PERLIO_F_CANREAD) {
2011 *s++ = 'r';
2012 if (flags & PERLIO_F_CANWRITE)
2013 *s++ = '+';
2014 }
2015 else if (flags & PERLIO_F_CANWRITE) {
2016 *s++ = 'w';
2017 if (flags & PERLIO_F_CANREAD) {
2018 *s++ = '+';
2019 }
14a5cf38 2020 }
35990314 2021#ifdef PERLIO_USING_CRLF
81428673
NIS
2022 if (!(flags & PERLIO_F_CRLF))
2023 *s++ = 'b';
5f1a76d0 2024#endif
81428673 2025 }
14a5cf38
JH
2026 *s = '\0';
2027 return buf;
f5b9d040
NIS
2028}
2029
81428673 2030
76ced9ad 2031IV
2dc2558e 2032PerlIOBase_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
9e353e3b 2033{
de009b76 2034 PerlIOl * const l = PerlIOBase(f);
96a5add6 2035 PERL_UNUSED_CONTEXT;
8772537c 2036 PERL_UNUSED_ARG(arg);
de009b76 2037
14a5cf38
JH
2038 l->flags &= ~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE |
2039 PERLIO_F_TRUNCATE | PERLIO_F_APPEND);
2040 if (tab->Set_ptrcnt != NULL)
2041 l->flags |= PERLIO_F_FASTGETS;
2042 if (mode) {
3b6c1aba 2043 if (*mode == IoTYPE_NUMERIC || *mode == IoTYPE_IMPLICIT)
14a5cf38
JH
2044 mode++;
2045 switch (*mode++) {
2046 case 'r':
2047 l->flags |= PERLIO_F_CANREAD;
2048 break;
2049 case 'a':
2050 l->flags |= PERLIO_F_APPEND | PERLIO_F_CANWRITE;
2051 break;
2052 case 'w':
2053 l->flags |= PERLIO_F_TRUNCATE | PERLIO_F_CANWRITE;
2054 break;
2055 default:
93189314 2056 SETERRNO(EINVAL, LIB_INVARG);
14a5cf38
JH
2057 return -1;
2058 }
2059 while (*mode) {
2060 switch (*mode++) {
2061 case '+':
2062 l->flags |= PERLIO_F_CANREAD | PERLIO_F_CANWRITE;
2063 break;
2064 case 'b':
2065 l->flags &= ~PERLIO_F_CRLF;
2066 break;
2067 case 't':
2068 l->flags |= PERLIO_F_CRLF;
2069 break;
2070 default:
93189314 2071 SETERRNO(EINVAL, LIB_INVARG);
14a5cf38
JH
2072 return -1;
2073 }
2074 }
2075 }
2076 else {
2077 if (l->next) {
2078 l->flags |= l->next->flags &
2079 (PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_TRUNCATE |
2080 PERLIO_F_APPEND);
2081 }
2082 }
5e2ab84b 2083#if 0
14a5cf38 2084 PerlIO_debug("PerlIOBase_pushed f=%p %s %s fl=%08" UVxf " (%s)\n",
6c9570dc 2085 (void*)f, PerlIOBase(f)->tab->name, (omode) ? omode : "(Null)",
14a5cf38 2086 l->flags, PerlIO_modestr(f, temp));
5e2ab84b 2087#endif
14a5cf38 2088 return 0;
76ced9ad
NIS
2089}
2090
2091IV
f62ce20a 2092PerlIOBase_popped(pTHX_ PerlIO *f)
76ced9ad 2093{
96a5add6 2094 PERL_UNUSED_CONTEXT;
8772537c 2095 PERL_UNUSED_ARG(f);
14a5cf38 2096 return 0;
760ac839
LW
2097}
2098
9e353e3b 2099SSize_t
f62ce20a 2100PerlIOBase_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
9e353e3b 2101{
14a5cf38 2102 /*
71200d45 2103 * Save the position as current head considers it
14a5cf38 2104 */
de009b76 2105 const Off_t old = PerlIO_tell(f);
a0714e2c 2106 PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_pending), "r", NULL);
14a5cf38 2107 PerlIOSelf(f, PerlIOBuf)->posn = old;
de009b76 2108 return PerlIOBuf_unread(aTHX_ f, vbuf, count);
9e353e3b
NIS
2109}
2110
f6c77cf1 2111SSize_t
f62ce20a 2112PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
f6c77cf1 2113{
14a5cf38
JH
2114 STDCHAR *buf = (STDCHAR *) vbuf;
2115 if (f) {
263df5f1
JH
2116 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD)) {
2117 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
2118 SETERRNO(EBADF, SS_IVCHAN);
2119 return 0;
2120 }
14a5cf38 2121 while (count > 0) {
93c2c2ec
IZ
2122 get_cnt:
2123 {
14a5cf38
JH
2124 SSize_t avail = PerlIO_get_cnt(f);
2125 SSize_t take = 0;
2126 if (avail > 0)
bb7a0f54 2127 take = ((SSize_t)count < avail) ? (SSize_t)count : avail;
14a5cf38
JH
2128 if (take > 0) {
2129 STDCHAR *ptr = PerlIO_get_ptr(f);
2130 Copy(ptr, buf, take, STDCHAR);
2131 PerlIO_set_ptrcnt(f, ptr + take, (avail -= take));
2132 count -= take;
2133 buf += take;
93c2c2ec
IZ
2134 if (avail == 0) /* set_ptrcnt could have reset avail */
2135 goto get_cnt;
14a5cf38
JH
2136 }
2137 if (count > 0 && avail <= 0) {
2138 if (PerlIO_fill(f) != 0)
2139 break;
2140 }
93c2c2ec 2141 }
14a5cf38
JH
2142 }
2143 return (buf - (STDCHAR *) vbuf);
2144 }
f6c77cf1 2145 return 0;
f6c77cf1
NIS
2146}
2147
9e353e3b 2148IV
f62ce20a 2149PerlIOBase_noop_ok(pTHX_ PerlIO *f)
9e353e3b 2150{
96a5add6 2151 PERL_UNUSED_CONTEXT;
8772537c 2152 PERL_UNUSED_ARG(f);
14a5cf38 2153 return 0;
9e353e3b
NIS
2154}
2155
2156IV
f62ce20a 2157PerlIOBase_noop_fail(pTHX_ PerlIO *f)
06da4f11 2158{
96a5add6 2159 PERL_UNUSED_CONTEXT;
8772537c 2160 PERL_UNUSED_ARG(f);
14a5cf38 2161 return -1;
06da4f11
NIS
2162}
2163
2164IV
f62ce20a 2165PerlIOBase_close(pTHX_ PerlIO *f)
9e353e3b 2166{
37725cdc
NIS
2167 IV code = -1;
2168 if (PerlIOValid(f)) {
2169 PerlIO *n = PerlIONext(f);
2170 code = PerlIO_flush(f);
2171 PerlIOBase(f)->flags &=
2172 ~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_OPEN);
2173 while (PerlIOValid(n)) {
de009b76 2174 const PerlIO_funcs * const tab = PerlIOBase(n)->tab;
37725cdc
NIS
2175 if (tab && tab->Close) {
2176 if ((*tab->Close)(aTHX_ n) != 0)
2177 code = -1;
2178 break;
2179 }
2180 else {
2181 PerlIOBase(n)->flags &=
2182 ~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_OPEN);
2183 }
2184 n = PerlIONext(n);
2185 }
2186 }
2187 else {
2188 SETERRNO(EBADF, SS_IVCHAN);
2189 }
14a5cf38 2190 return code;
9e353e3b
NIS
2191}
2192
2193IV
f62ce20a 2194PerlIOBase_eof(pTHX_ PerlIO *f)
9e353e3b 2195{
96a5add6 2196 PERL_UNUSED_CONTEXT;
04892f78 2197 if (PerlIOValid(f)) {
14a5cf38
JH
2198 return (PerlIOBase(f)->flags & PERLIO_F_EOF) != 0;
2199 }
2200 return 1;
9e353e3b
NIS
2201}
2202
2203IV
f62ce20a 2204PerlIOBase_error(pTHX_ PerlIO *f)
9e353e3b 2205{
96a5add6 2206 PERL_UNUSED_CONTEXT;
04892f78 2207 if (PerlIOValid(f)) {
14a5cf38
JH
2208 return (PerlIOBase(f)->flags & PERLIO_F_ERROR) != 0;
2209 }
2210 return 1;
9e353e3b
NIS
2211}
2212
2213void
f62ce20a 2214PerlIOBase_clearerr(pTHX_ PerlIO *f)
9e353e3b 2215{
04892f78 2216 if (PerlIOValid(f)) {
dcda55fc 2217 PerlIO * const n = PerlIONext(f);
14a5cf38 2218 PerlIOBase(f)->flags &= ~(PERLIO_F_ERROR | PERLIO_F_EOF);
04892f78 2219 if (PerlIOValid(n))
14a5cf38
JH
2220 PerlIO_clearerr(n);
2221 }
9e353e3b
NIS
2222}
2223
2224void
f62ce20a 2225PerlIOBase_setlinebuf(pTHX_ PerlIO *f)
9e353e3b 2226{
96a5add6 2227 PERL_UNUSED_CONTEXT;
04892f78 2228 if (PerlIOValid(f)) {
14a5cf38
JH
2229 PerlIOBase(f)->flags |= PERLIO_F_LINEBUF;
2230 }
9e353e3b
NIS
2231}
2232
93a8090d
NIS
2233SV *
2234PerlIO_sv_dup(pTHX_ SV *arg, CLONE_PARAMS *param)
2235{
2236 if (!arg)
a0714e2c 2237 return NULL;
93a8090d
NIS
2238#ifdef sv_dup
2239 if (param) {
a951d81d
BL
2240 arg = sv_dup(arg, param);
2241 SvREFCNT_inc_simple_void_NN(arg);
2242 return arg;
93a8090d
NIS
2243 }
2244 else {
2245 return newSVsv(arg);
2246 }
2247#else
1b6737cc 2248 PERL_UNUSED_ARG(param);
93a8090d
NIS
2249 return newSVsv(arg);
2250#endif
2251}
2252
2253PerlIO *
ecdeb87c 2254PerlIOBase_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
93a8090d 2255{
1b6737cc 2256 PerlIO * const nexto = PerlIONext(o);
04892f78 2257 if (PerlIOValid(nexto)) {
de009b76 2258 const PerlIO_funcs * const tab = PerlIOBase(nexto)->tab;
37725cdc
NIS
2259 if (tab && tab->Dup)
2260 f = (*tab->Dup)(aTHX_ f, nexto, param, flags);
2261 else
2262 f = PerlIOBase_dup(aTHX_ f, nexto, param, flags);
93a8090d
NIS
2263 }
2264 if (f) {
dcda55fc 2265 PerlIO_funcs * const self = PerlIOBase(o)->tab;
a951d81d 2266 SV *arg = NULL;
93a8090d 2267 char buf[8];
fe5a182c
JH
2268 PerlIO_debug("PerlIOBase_dup %s f=%p o=%p param=%p\n",
2269 self->name, (void*)f, (void*)o, (void*)param);
210e727c
JH
2270 if (self->Getarg)
2271 arg = (*self->Getarg)(aTHX_ o, param, flags);
93a8090d 2272 f = PerlIO_push(aTHX_ f, self, PerlIO_modestr(o,buf), arg);
f0720f70
RGS
2273 if (PerlIOBase(o)->flags & PERLIO_F_UTF8)
2274 PerlIOBase(f)->flags |= PERLIO_F_UTF8;
a951d81d 2275 if (arg)
93a8090d 2276 SvREFCNT_dec(arg);
93a8090d
NIS
2277 }
2278 return f;
2279}
2280
27da23d5 2281/* PL_perlio_fd_refcnt[] is in intrpvar.h */
93a8090d 2282
8b84d7dd 2283/* Must be called with PL_perlio_mutex locked. */
22c96fc1
NC
2284static void
2285S_more_refcounted_fds(pTHX_ const int new_fd) {
7a89be66 2286 dVAR;
22c96fc1 2287 const int old_max = PL_perlio_fd_refcnt_size;
f4ae5be6 2288 const int new_max = 16 + (new_fd & ~15);
22c96fc1
NC
2289 int *new_array;
2290
2291 PerlIO_debug("More fds - old=%d, need %d, new=%d\n",
2292 old_max, new_fd, new_max);
2293
2294 if (new_fd < old_max) {
2295 return;
2296 }
2297
f4ae5be6
NC
2298 assert (new_max > new_fd);
2299
eae082a0
JH
2300 /* Use plain realloc() since we need this memory to be really
2301 * global and visible to all the interpreters and/or threads. */
2302 new_array = (int*) realloc(PL_perlio_fd_refcnt, new_max * sizeof(int));
22c96fc1
NC
2303
2304 if (!new_array) {
8b84d7dd 2305#ifdef USE_ITHREADS
6cb8cb21 2306 MUTEX_UNLOCK(&PL_perlio_mutex);
22c96fc1
NC
2307#endif
2308 /* Can't use PerlIO to write as it allocates memory */
2309 PerlLIO_write(PerlIO_fileno(Perl_error_log),
2310 PL_no_mem, strlen(PL_no_mem));
2311 my_exit(1);
2312 }
2313
2314 PL_perlio_fd_refcnt_size = new_max;
2315 PL_perlio_fd_refcnt = new_array;
2316
95b63a38
JH
2317 PerlIO_debug("Zeroing %p, %d\n",
2318 (void*)(new_array + old_max),
2319 new_max - old_max);
22c96fc1
NC
2320
2321 Zero(new_array + old_max, new_max - old_max, int);
2322}
2323
2324
93a8090d
NIS
2325void
2326PerlIO_init(pTHX)
2327{
8b84d7dd 2328 /* MUTEX_INIT(&PL_perlio_mutex) is done in PERL_SYS_INIT3(). */
96a5add6 2329 PERL_UNUSED_CONTEXT;
93a8090d
NIS
2330}
2331
168d5872
NIS
2332void
2333PerlIOUnix_refcnt_inc(int fd)
2334{
27da23d5 2335 dTHX;
22c96fc1 2336 if (fd >= 0) {
97aff369 2337 dVAR;
22c96fc1 2338
8b84d7dd 2339#ifdef USE_ITHREADS
6cb8cb21 2340 MUTEX_LOCK(&PL_perlio_mutex);
168d5872 2341#endif
22c96fc1
NC
2342 if (fd >= PL_perlio_fd_refcnt_size)
2343 S_more_refcounted_fds(aTHX_ fd);
2344
27da23d5 2345 PL_perlio_fd_refcnt[fd]++;
8b84d7dd
RGS
2346 if (PL_perlio_fd_refcnt[fd] <= 0) {
2347 Perl_croak(aTHX_ "refcnt_inc: fd %d: %d <= 0\n",
2348 fd, PL_perlio_fd_refcnt[fd]);
2349 }
2350 PerlIO_debug("refcnt_inc: fd %d refcnt=%d\n",
2351 fd, PL_perlio_fd_refcnt[fd]);
22c96fc1 2352
8b84d7dd 2353#ifdef USE_ITHREADS
6cb8cb21 2354 MUTEX_UNLOCK(&PL_perlio_mutex);
168d5872 2355#endif
8b84d7dd
RGS
2356 } else {
2357 Perl_croak(aTHX_ "refcnt_inc: fd %d < 0\n", fd);
168d5872
NIS
2358 }
2359}
2360
168d5872
NIS
2361int
2362PerlIOUnix_refcnt_dec(int fd)
2363{
27da23d5 2364 dTHX;
168d5872 2365 int cnt = 0;
22c96fc1 2366 if (fd >= 0) {
97aff369 2367 dVAR;
8b84d7dd 2368#ifdef USE_ITHREADS
6cb8cb21 2369 MUTEX_LOCK(&PL_perlio_mutex);
168d5872 2370#endif
8b84d7dd
RGS
2371 if (fd >= PL_perlio_fd_refcnt_size) {
2372 Perl_croak(aTHX_ "refcnt_dec: fd %d >= refcnt_size %d\n",
2373 fd, PL_perlio_fd_refcnt_size);
2374 }
2375 if (PL_perlio_fd_refcnt[fd] <= 0) {
2376 Perl_croak(aTHX_ "refcnt_dec: fd %d: %d <= 0\n",
2377 fd, PL_perlio_fd_refcnt[fd]);
2378 }
27da23d5 2379 cnt = --PL_perlio_fd_refcnt[fd];
8b84d7dd
RGS
2380 PerlIO_debug("refcnt_dec: fd %d refcnt=%d\n", fd, cnt);
2381#ifdef USE_ITHREADS
6cb8cb21 2382 MUTEX_UNLOCK(&PL_perlio_mutex);
168d5872 2383#endif
8b84d7dd
RGS
2384 } else {
2385 Perl_croak(aTHX_ "refcnt_dec: fd %d < 0\n", fd);
168d5872
NIS
2386 }
2387 return cnt;
2388}
2389
694c95cf
JH
2390void
2391PerlIO_cleanup(pTHX)
2392{
97aff369 2393 dVAR;
694c95cf
JH
2394 int i;
2395#ifdef USE_ITHREADS
a25429c6 2396 PerlIO_debug("Cleanup layers for %p\n",(void*)aTHX);
9f4bd222
NIS
2397#else
2398 PerlIO_debug("Cleanup layers\n");
694c95cf 2399#endif
e47547a8 2400
694c95cf
JH
2401 /* Raise STDIN..STDERR refcount so we don't close them */
2402 for (i=0; i < 3; i++)
2403 PerlIOUnix_refcnt_inc(i);
2404 PerlIO_cleantable(aTHX_ &PL_perlio);
2405 /* Restore STDIN..STDERR refcount */
2406 for (i=0; i < 3; i++)
2407 PerlIOUnix_refcnt_dec(i);
9f4bd222
NIS
2408
2409 if (PL_known_layers) {
2410 PerlIO_list_free(aTHX_ PL_known_layers);
2411 PL_known_layers = NULL;
2412 }
27da23d5 2413 if (PL_def_layerlist) {
9f4bd222
NIS
2414 PerlIO_list_free(aTHX_ PL_def_layerlist);
2415 PL_def_layerlist = NULL;
2416 }
6cb8cb21
RGS
2417}
2418
0934c9d9 2419void PerlIO_teardown(void) /* Call only from PERL_SYS_TERM(). */
6cb8cb21 2420{
53d44271 2421 dVAR;
4f3da17a
DM
2422#if 0
2423/* XXX we can't rely on an interpreter being present at this late stage,
2424 XXX so we can't use a function like PerlLIO_write that relies on one
2425 being present (at least in win32) :-(.
2426 Disable for now.
2427*/
6cb8cb21
RGS
2428#ifdef DEBUGGING
2429 {
2430 /* By now all filehandles should have been closed, so any
2431 * stray (non-STD-)filehandles indicate *possible* (PerlIO)
2432 * errors. */
77db880c
JH
2433#define PERLIO_TEARDOWN_MESSAGE_BUF_SIZE 64
2434#define PERLIO_TEARDOWN_MESSAGE_FD 2
2435 char buf[PERLIO_TEARDOWN_MESSAGE_BUF_SIZE];
6cb8cb21
RGS
2436 int i;
2437 for (i = 3; i < PL_perlio_fd_refcnt_size; i++) {
77db880c
JH
2438 if (PL_perlio_fd_refcnt[i]) {
2439 const STRLEN len =
2440 my_snprintf(buf, sizeof(buf),
2441 "PerlIO_teardown: fd %d refcnt=%d\n",
2442 i, PL_perlio_fd_refcnt[i]);
2443 PerlLIO_write(PERLIO_TEARDOWN_MESSAGE_FD, buf, len);
2444 }
6cb8cb21
RGS
2445 }
2446 }
2447#endif
4f3da17a 2448#endif
eae082a0
JH
2449 /* Not bothering with PL_perlio_mutex since by now
2450 * all the interpreters are gone. */
1cd82952
RGS
2451 if (PL_perlio_fd_refcnt_size /* Assuming initial size of zero. */
2452 && PL_perlio_fd_refcnt) {
eae082a0 2453 free(PL_perlio_fd_refcnt); /* To match realloc() in S_more_refcounted_fds(). */
432ce874
YO
2454 PL_perlio_fd_refcnt = NULL;
2455 PL_perlio_fd_refcnt_size = 0;
1cd82952 2456 }
694c95cf
JH
2457}
2458
9e353e3b 2459/*--------------------------------------------------------------------------------------*/
14a5cf38 2460/*
71200d45 2461 * Bottom-most level for UNIX-like case
14a5cf38 2462 */
9e353e3b 2463
14a5cf38 2464typedef struct {
22569500
NIS
2465 struct _PerlIO base; /* The generic part */
2466 int fd; /* UNIX like file descriptor */
2467 int oflags; /* open/fcntl flags */
9e353e3b
NIS
2468} PerlIOUnix;
2469
6f9d8c32 2470int
9e353e3b 2471PerlIOUnix_oflags(const char *mode)
760ac839 2472{
14a5cf38 2473 int oflags = -1;
3b6c1aba 2474 if (*mode == IoTYPE_IMPLICIT || *mode == IoTYPE_NUMERIC)
14a5cf38
JH
2475 mode++;
2476 switch (*mode) {
2477 case 'r':
2478 oflags = O_RDONLY;
2479 if (*++mode == '+') {
2480 oflags = O_RDWR;
2481 mode++;
2482 }
2483 break;
2484
2485 case 'w':
2486 oflags = O_CREAT | O_TRUNC;
2487 if (*++mode == '+') {
2488 oflags |= O_RDWR;
2489 mode++;
2490 }
2491 else
2492 oflags |= O_WRONLY;
2493 break;
2494
2495 case 'a':
2496 oflags = O_CREAT | O_APPEND;
2497 if (*++mode == '+') {
2498 oflags |= O_RDWR;
2499 mode++;
2500 }
2501 else
2502 oflags |= O_WRONLY;
2503 break;
2504 }
2505 if (*mode == 'b') {
2506 oflags |= O_BINARY;
2507 oflags &= ~O_TEXT;
2508 mode++;
2509 }
2510 else if (*mode == 't') {
2511 oflags |= O_TEXT;
2512 oflags &= ~O_BINARY;
2513 mode++;
2514 }
2515 /*
71200d45 2516 * Always open in binary mode
14a5cf38
JH
2517 */
2518 oflags |= O_BINARY;
2519 if (*mode || oflags == -1) {
93189314 2520 SETERRNO(EINVAL, LIB_INVARG);
14a5cf38
JH
2521 oflags = -1;
2522 }
2523 return oflags;
9e353e3b
NIS
2524}
2525
2526IV
f62ce20a 2527PerlIOUnix_fileno(pTHX_ PerlIO *f)
9e353e3b 2528{
96a5add6 2529 PERL_UNUSED_CONTEXT;
14a5cf38 2530 return PerlIOSelf(f, PerlIOUnix)->fd;
9e353e3b
NIS
2531}
2532
aa063c35
NIS
2533static void
2534PerlIOUnix_setfd(pTHX_ PerlIO *f, int fd, int imode)
4b803d04 2535{
de009b76 2536 PerlIOUnix * const s = PerlIOSelf(f, PerlIOUnix);
6caa5a9c 2537#if defined(WIN32)
aa063c35
NIS
2538 Stat_t st;
2539 if (PerlLIO_fstat(fd, &st) == 0) {
6caa5a9c 2540 if (!S_ISREG(st.st_mode)) {
aa063c35 2541 PerlIO_debug("%d is not regular file\n",fd);
6caa5a9c
NIS
2542 PerlIOBase(f)->flags |= PERLIO_F_NOTREG;
2543 }
aa063c35
NIS
2544 else {
2545 PerlIO_debug("%d _is_ a regular file\n",fd);
2546 }
6caa5a9c
NIS
2547 }
2548#endif
aa063c35
NIS
2549 s->fd = fd;
2550 s->oflags = imode;
2551 PerlIOUnix_refcnt_inc(fd);
96a5add6 2552 PERL_UNUSED_CONTEXT;
aa063c35
NIS
2553}
2554
2555IV
2556PerlIOUnix_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
2557{
2558 IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
14a5cf38 2559 if (*PerlIONext(f)) {
4b069b44 2560 /* We never call down so do any pending stuff now */
03c0554d 2561 PerlIO_flush(PerlIONext(f));
14a5cf38 2562 /*
71200d45 2563 * XXX could (or should) we retrieve the oflags from the open file
14a5cf38 2564 * handle rather than believing the "mode" we are passed in? XXX
71200d45 2565 * Should the value on NULL mode be 0 or -1?
14a5cf38 2566 */
acbd16bf 2567 PerlIOUnix_setfd(aTHX_ f, PerlIO_fileno(PerlIONext(f)),
aa063c35 2568 mode ? PerlIOUnix_oflags(mode) : -1);
14a5cf38
JH
2569 }
2570 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
6caa5a9c 2571
14a5cf38 2572 return code;
4b803d04
NIS
2573}
2574
c2fcde81
JH
2575IV
2576PerlIOUnix_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
2577{
de009b76 2578 const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
0723351e 2579 Off_t new_loc;
96a5add6 2580 PERL_UNUSED_CONTEXT;
c2fcde81
JH
2581 if (PerlIOBase(f)->flags & PERLIO_F_NOTREG) {
2582#ifdef ESPIPE
2583 SETERRNO(ESPIPE, LIB_INVARG);
2584#else
2585 SETERRNO(EINVAL, LIB_INVARG);
2586#endif
2587 return -1;
2588 }
0723351e
NC
2589 new_loc = PerlLIO_lseek(fd, offset, whence);
2590 if (new_loc == (Off_t) - 1)
dcda55fc 2591 return -1;
c2fcde81
JH
2592 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
2593 return 0;
2594}
2595
9e353e3b 2596PerlIO *
14a5cf38
JH
2597PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
2598 IV n, const char *mode, int fd, int imode,
2599 int perm, PerlIO *f, int narg, SV **args)
2600{
d9dac8cd 2601 if (PerlIOValid(f)) {
14a5cf38 2602 if (PerlIOBase(f)->flags & PERLIO_F_OPEN)
f62ce20a 2603 (*PerlIOBase(f)->tab->Close)(aTHX_ f);
14a5cf38
JH
2604 }
2605 if (narg > 0) {
3b6c1aba 2606 if (*mode == IoTYPE_NUMERIC)
14a5cf38
JH
2607 mode++;
2608 else {
2609 imode = PerlIOUnix_oflags(mode);
2610 perm = 0666;
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",