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