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