This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
toke.c: PL_in_eval purge
[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) {
985213f2
AB
453 if (!PL_tainting &&
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) {
14a5cf38 469 dTHX;
70ace5da 470#ifdef USE_ITHREADS
dcda55fc 471 const char * const s = CopFILE(PL_curcop);
70ace5da
NIS
472 /* Use fixed buffer as sv_catpvf etc. needs SVs */
473 char buffer[1024];
1208b3dd
JH
474 const STRLEN len1 = my_snprintf(buffer, sizeof(buffer), "%.40s:%" IVdf " ", s ? s : "(none)", (IV) CopLINE(PL_curcop));
475 const STRLEN len2 = my_vsnprintf(buffer + len1, sizeof(buffer) - len1, fmt, ap);
476 PerlLIO_write(PL_perlio_debug_fd, buffer, len1 + len2);
70ace5da 477#else
dcda55fc
AL
478 const char *s = CopFILE(PL_curcop);
479 STRLEN len;
550e2ce0
NC
480 SV * const sv = Perl_newSVpvf(aTHX_ "%s:%" IVdf " ", s ? s : "(none)",
481 (IV) CopLINE(PL_curcop));
14a5cf38
JH
482 Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap);
483
b83604b4 484 s = SvPV_const(sv, len);
27da23d5 485 PerlLIO_write(PL_perlio_debug_fd, s, len);
14a5cf38 486 SvREFCNT_dec(sv);
70ace5da 487#endif
14a5cf38
JH
488 }
489 va_end(ap);
6f9d8c32
NIS
490}
491
9e353e3b
NIS
492/*--------------------------------------------------------------------------------------*/
493
14a5cf38 494/*
71200d45 495 * Inner level routines
14a5cf38 496 */
9e353e3b 497
16865ff7
DM
498/* check that the head field of each layer points back to the head */
499
500#ifdef DEBUGGING
501# define VERIFY_HEAD(f) PerlIO_verify_head(aTHX_ f)
502static void
503PerlIO_verify_head(pTHX_ PerlIO *f)
504{
505 PerlIOl *head, *p;
506 int seen = 0;
507 if (!PerlIOValid(f))
508 return;
509 p = head = PerlIOBase(f)->head;
510 assert(p);
511 do {
512 assert(p->head == head);
513 if (p == (PerlIOl*)f)
514 seen = 1;
515 p = p->next;
516 } while (p);
517 assert(seen);
518}
519#else
520# define VERIFY_HEAD(f)
521#endif
522
523
14a5cf38 524/*
71200d45 525 * Table of pointers to the PerlIO structs (malloc'ed)
14a5cf38 526 */
05d1247b 527#define PERLIO_TABLE_SIZE 64
6f9d8c32 528
8995e67d
DM
529static void
530PerlIO_init_table(pTHX)
531{
532 if (PL_perlio)
533 return;
534 Newxz(PL_perlio, PERLIO_TABLE_SIZE, PerlIOl);
535}
536
537
538
760ac839 539PerlIO *
5f1a76d0 540PerlIO_allocate(pTHX)
6f9d8c32 541{
97aff369 542 dVAR;
14a5cf38 543 /*
71200d45 544 * Find a free slot in the table, allocating new table as necessary
14a5cf38 545 */
303f2dc3
DM
546 PerlIOl **last;
547 PerlIOl *f;
a1ea730d 548 last = &PL_perlio;
14a5cf38
JH
549 while ((f = *last)) {
550 int i;
303f2dc3 551 last = (PerlIOl **) (f);
14a5cf38 552 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
303f2dc3 553 if (!((++f)->next)) {
abf9167d 554 f->flags = 0; /* lockcnt */
303f2dc3 555 f->tab = NULL;
16865ff7 556 f->head = f;
303f2dc3 557 return (PerlIO *)f;
14a5cf38
JH
558 }
559 }
560 }
303f2dc3 561 Newxz(f,PERLIO_TABLE_SIZE,PerlIOl);
14a5cf38
JH
562 if (!f) {
563 return NULL;
564 }
303f2dc3 565 *last = (PerlIOl*) f++;
abf9167d 566 f->flags = 0; /* lockcnt */
303f2dc3 567 f->tab = NULL;
16865ff7 568 f->head = f;
303f2dc3 569 return (PerlIO*) f;
05d1247b
NIS
570}
571
a1ea730d
NIS
572#undef PerlIO_fdupopen
573PerlIO *
ecdeb87c 574PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
a1ea730d 575{
04892f78 576 if (PerlIOValid(f)) {
de009b76 577 const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
fe5a182c 578 PerlIO_debug("fdupopen f=%p param=%p\n",(void*)f,(void*)param);
210e727c
JH
579 if (tab && tab->Dup)
580 return (*tab->Dup)(aTHX_ PerlIO_allocate(aTHX), f, param, flags);
37725cdc
NIS
581 else {
582 return PerlIOBase_dup(aTHX_ PerlIO_allocate(aTHX), f, param, flags);
583 }
a1ea730d 584 }
210e727c
JH
585 else
586 SETERRNO(EBADF, SS_IVCHAN);
587
588 return NULL;
a1ea730d
NIS
589}
590
591void
303f2dc3 592PerlIO_cleantable(pTHX_ PerlIOl **tablep)
05d1247b 593{
303f2dc3 594 PerlIOl * const table = *tablep;
14a5cf38
JH
595 if (table) {
596 int i;
303f2dc3 597 PerlIO_cleantable(aTHX_(PerlIOl **) & (table[0]));
14a5cf38 598 for (i = PERLIO_TABLE_SIZE - 1; i > 0; i--) {
303f2dc3
DM
599 PerlIOl * const f = table + i;
600 if (f->next) {
601 PerlIO_close(&(f->next));
14a5cf38
JH
602 }
603 }
3a1ee7e8 604 Safefree(table);
14a5cf38 605 *tablep = NULL;
05d1247b 606 }
05d1247b
NIS
607}
608
fcf2db38
NIS
609
610PerlIO_list_t *
3a1ee7e8 611PerlIO_list_alloc(pTHX)
fcf2db38 612{
14a5cf38 613 PerlIO_list_t *list;
96a5add6 614 PERL_UNUSED_CONTEXT;
a02a5408 615 Newxz(list, 1, PerlIO_list_t);
14a5cf38
JH
616 list->refcnt = 1;
617 return list;
fcf2db38
NIS
618}
619
620void
3a1ee7e8 621PerlIO_list_free(pTHX_ PerlIO_list_t *list)
fcf2db38 622{
14a5cf38
JH
623 if (list) {
624 if (--list->refcnt == 0) {
625 if (list->array) {
14a5cf38 626 IV i;
ef8d46e8
VP
627 for (i = 0; i < list->cur; i++)
628 SvREFCNT_dec(list->array[i].arg);
14a5cf38
JH
629 Safefree(list->array);
630 }
631 Safefree(list);
632 }
633 }
fcf2db38
NIS
634}
635
636void
3a1ee7e8 637PerlIO_list_push(pTHX_ PerlIO_list_t *list, PerlIO_funcs *funcs, SV *arg)
14a5cf38 638{
97aff369 639 dVAR;
334e202e 640 PerlIO_pair_t *p;
b37c2d43
AL
641 PERL_UNUSED_CONTEXT;
642
14a5cf38
JH
643 if (list->cur >= list->len) {
644 list->len += 8;
645 if (list->array)
646 Renew(list->array, list->len, PerlIO_pair_t);
647 else
a02a5408 648 Newx(list->array, list->len, PerlIO_pair_t);
14a5cf38
JH
649 }
650 p = &(list->array[list->cur++]);
651 p->funcs = funcs;
652 if ((p->arg = arg)) {
f84c484e 653 SvREFCNT_inc_simple_void_NN(arg);
14a5cf38 654 }
fcf2db38
NIS
655}
656
3a1ee7e8
NIS
657PerlIO_list_t *
658PerlIO_clone_list(pTHX_ PerlIO_list_t *proto, CLONE_PARAMS *param)
659{
b37c2d43 660 PerlIO_list_t *list = NULL;
694c95cf
JH
661 if (proto) {
662 int i;
663 list = PerlIO_list_alloc(aTHX);
664 for (i=0; i < proto->cur; i++) {
a951d81d
BL
665 SV *arg = proto->array[i].arg;
666#ifdef sv_dup
667 if (arg && param)
668 arg = sv_dup(arg, param);
669#else
670 PERL_UNUSED_ARG(param);
671#endif
694c95cf
JH
672 PerlIO_list_push(aTHX_ list, proto->array[i].funcs, arg);
673 }
3a1ee7e8
NIS
674 }
675 return list;
676}
4a4a6116 677
05d1247b 678void
3a1ee7e8 679PerlIO_clone(pTHX_ PerlInterpreter *proto, CLONE_PARAMS *param)
9a6404c5 680{
3aaf42a7 681#ifdef USE_ITHREADS
303f2dc3
DM
682 PerlIOl **table = &proto->Iperlio;
683 PerlIOl *f;
3a1ee7e8
NIS
684 PL_perlio = NULL;
685 PL_known_layers = PerlIO_clone_list(aTHX_ proto->Iknown_layers, param);
686 PL_def_layerlist = PerlIO_clone_list(aTHX_ proto->Idef_layerlist, param);
8995e67d 687 PerlIO_init_table(aTHX);
a25429c6 688 PerlIO_debug("Clone %p from %p\n",(void*)aTHX,(void*)proto);
3a1ee7e8
NIS
689 while ((f = *table)) {
690 int i;
303f2dc3 691 table = (PerlIOl **) (f++);
3a1ee7e8 692 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
303f2dc3
DM
693 if (f->next) {
694 (void) fp_dup(&(f->next), 0, param);
3a1ee7e8
NIS
695 }
696 f++;
697 }
698 }
1b6737cc 699#else
a25429c6 700 PERL_UNUSED_CONTEXT;
1b6737cc
AL
701 PERL_UNUSED_ARG(proto);
702 PERL_UNUSED_ARG(param);
3aaf42a7 703#endif
9a6404c5
DM
704}
705
706void
13621cfb
NIS
707PerlIO_destruct(pTHX)
708{
97aff369 709 dVAR;
303f2dc3
DM
710 PerlIOl **table = &PL_perlio;
711 PerlIOl *f;
694c95cf 712#ifdef USE_ITHREADS
a25429c6 713 PerlIO_debug("Destruct %p\n",(void*)aTHX);
694c95cf 714#endif
14a5cf38
JH
715 while ((f = *table)) {
716 int i;
303f2dc3 717 table = (PerlIOl **) (f++);
14a5cf38 718 for (i = 1; i < PERLIO_TABLE_SIZE; i++) {
303f2dc3 719 PerlIO *x = &(f->next);
dcda55fc 720 const PerlIOl *l;
14a5cf38 721 while ((l = *x)) {
cc6623a8 722 if (l->tab && l->tab->kind & PERLIO_K_DESTRUCT) {
14a5cf38
JH
723 PerlIO_debug("Destruct popping %s\n", l->tab->name);
724 PerlIO_flush(x);
725 PerlIO_pop(aTHX_ x);
726 }
727 else {
728 x = PerlIONext(x);
729 }
730 }
731 f++;
732 }
733 }
13621cfb
NIS
734}
735
736void
a999f61b 737PerlIO_pop(pTHX_ PerlIO *f)
760ac839 738{
dcda55fc 739 const PerlIOl *l = *f;
16865ff7 740 VERIFY_HEAD(f);
14a5cf38 741 if (l) {
cc6623a8
DM
742 PerlIO_debug("PerlIO_pop f=%p %s\n", (void*)f,
743 l->tab ? l->tab->name : "(Null)");
744 if (l->tab && l->tab->Popped) {
14a5cf38
JH
745 /*
746 * If popped returns non-zero do not free its layer structure
747 * it has either done so itself, or it is shared and still in
71200d45 748 * use
14a5cf38 749 */
f62ce20a 750 if ((*l->tab->Popped) (aTHX_ f) != 0)
14a5cf38
JH
751 return;
752 }
abf9167d
DM
753 if (PerlIO_lockcnt(f)) {
754 /* we're in use; defer freeing the structure */
755 PerlIOBase(f)->flags = PERLIO_F_CLEARED;
756 PerlIOBase(f)->tab = NULL;
757 }
758 else {
759 *f = l->next;
760 Safefree(l);
761 }
762
a8c08ecd 763 }
6f9d8c32
NIS
764}
765
39f7a870
JH
766/* Return as an array the stack of layers on a filehandle. Note that
767 * the stack is returned top-first in the array, and there are three
768 * times as many array elements as there are layers in the stack: the
769 * first element of a layer triplet is the name, the second one is the
770 * arguments, and the third one is the flags. */
771
772AV *
773PerlIO_get_layers(pTHX_ PerlIO *f)
774{
97aff369 775 dVAR;
dcda55fc 776 AV * const av = newAV();
39f7a870 777
dcda55fc
AL
778 if (PerlIOValid(f)) {
779 PerlIOl *l = PerlIOBase(f);
780
781 while (l) {
92e45a3e
NC
782 /* There is some collusion in the implementation of
783 XS_PerlIO_get_layers - it knows that name and flags are
784 generated as fresh SVs here, and takes advantage of that to
785 "copy" them by taking a reference. If it changes here, it needs
786 to change there too. */
dcda55fc
AL
787 SV * const name = l->tab && l->tab->name ?
788 newSVpv(l->tab->name, 0) : &PL_sv_undef;
789 SV * const arg = l->tab && l->tab->Getarg ?
790 (*l->tab->Getarg)(aTHX_ &l, 0, 0) : &PL_sv_undef;
791 av_push(av, name);
792 av_push(av, arg);
793 av_push(av, newSViv((IV)l->flags));
794 l = l->next;
795 }
796 }
39f7a870 797
dcda55fc 798 return av;
39f7a870
JH
799}
800
9e353e3b 801/*--------------------------------------------------------------------------------------*/
14a5cf38 802/*
71200d45 803 * XS Interface for perl code
14a5cf38 804 */
9e353e3b 805
fcf2db38 806PerlIO_funcs *
2edd7e44 807PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
f3862f8b 808{
27da23d5 809 dVAR;
14a5cf38
JH
810 IV i;
811 if ((SSize_t) len <= 0)
812 len = strlen(name);
3a1ee7e8 813 for (i = 0; i < PL_known_layers->cur; i++) {
46c461b5 814 PerlIO_funcs * const f = PL_known_layers->array[i].funcs;
a9f76400 815 if (memEQ(f->name, name, len) && f->name[len] == 0) {
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++;
1009 } while (isALNUM(*e));
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) {
bd61b366 1158 const char * const s = (PL_tainting) ? 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)
bb7a0f54 2159 take = ((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
NC
2339#endif
2340 /* Can't use PerlIO to write as it allocates memory */
2341 PerlLIO_write(PerlIO_fileno(Perl_error_log),
2342 PL_no_mem, strlen(PL_no_mem));
2343 my_exit(1);
2344 }
2345
2346 PL_perlio_fd_refcnt_size = new_max;
2347 PL_perlio_fd_refcnt = new_array;
2348
95b63a38
JH
2349 PerlIO_debug("Zeroing %p, %d\n",
2350 (void*)(new_array + old_max),
2351 new_max - old_max);
22c96fc1
NC
2352
2353 Zero(new_array + old_max, new_max - old_max, int);
2354}
2355
2356
93a8090d
NIS
2357void
2358PerlIO_init(pTHX)
2359{
8b84d7dd 2360 /* MUTEX_INIT(&PL_perlio_mutex) is done in PERL_SYS_INIT3(). */
96a5add6 2361 PERL_UNUSED_CONTEXT;
93a8090d
NIS
2362}
2363
168d5872
NIS
2364void
2365PerlIOUnix_refcnt_inc(int fd)
2366{
27da23d5 2367 dTHX;
22c96fc1 2368 if (fd >= 0) {
97aff369 2369 dVAR;
22c96fc1 2370
8b84d7dd 2371#ifdef USE_ITHREADS
6cb8cb21 2372 MUTEX_LOCK(&PL_perlio_mutex);
168d5872 2373#endif
22c96fc1
NC
2374 if (fd >= PL_perlio_fd_refcnt_size)
2375 S_more_refcounted_fds(aTHX_ fd);
2376
27da23d5 2377 PL_perlio_fd_refcnt[fd]++;
8b84d7dd 2378 if (PL_perlio_fd_refcnt[fd] <= 0) {
12605ff9 2379 /* diag_listed_as: refcnt_inc: fd %d%s */
8b84d7dd
RGS
2380 Perl_croak(aTHX_ "refcnt_inc: fd %d: %d <= 0\n",
2381 fd, PL_perlio_fd_refcnt[fd]);
2382 }
2383 PerlIO_debug("refcnt_inc: fd %d refcnt=%d\n",
2384 fd, PL_perlio_fd_refcnt[fd]);
22c96fc1 2385
8b84d7dd 2386#ifdef USE_ITHREADS
6cb8cb21 2387 MUTEX_UNLOCK(&PL_perlio_mutex);
168d5872 2388#endif
8b84d7dd 2389 } else {
12605ff9 2390 /* diag_listed_as: refcnt_inc: fd %d%s */
8b84d7dd 2391 Perl_croak(aTHX_ "refcnt_inc: fd %d < 0\n", fd);
168d5872
NIS
2392 }
2393}
2394
168d5872
NIS
2395int
2396PerlIOUnix_refcnt_dec(int fd)
2397{
27da23d5 2398 dTHX;
168d5872 2399 int cnt = 0;
22c96fc1 2400 if (fd >= 0) {
97aff369 2401 dVAR;
8b84d7dd 2402#ifdef USE_ITHREADS
6cb8cb21 2403 MUTEX_LOCK(&PL_perlio_mutex);
168d5872 2404#endif
8b84d7dd 2405 if (fd >= PL_perlio_fd_refcnt_size) {
12605ff9 2406 /* diag_listed_as: refcnt_dec: fd %d%s */
8b84d7dd
RGS
2407 Perl_croak(aTHX_ "refcnt_dec: fd %d >= refcnt_size %d\n",
2408 fd, PL_perlio_fd_refcnt_size);
2409 }
2410 if (PL_perlio_fd_refcnt[fd] <= 0) {
12605ff9 2411 /* diag_listed_as: refcnt_dec: fd %d%s */
8b84d7dd
RGS
2412 Perl_croak(aTHX_ "refcnt_dec: fd %d: %d <= 0\n",
2413 fd, PL_perlio_fd_refcnt[fd]);
2414 }
27da23d5 2415 cnt = --PL_perlio_fd_refcnt[fd];
8b84d7dd
RGS
2416 PerlIO_debug("refcnt_dec: fd %d refcnt=%d\n", fd, cnt);
2417#ifdef USE_ITHREADS
6cb8cb21 2418 MUTEX_UNLOCK(&PL_perlio_mutex);
168d5872 2419#endif
8b84d7dd 2420 } else {
12605ff9 2421 /* diag_listed_as: refcnt_dec: fd %d%s */
8b84d7dd 2422 Perl_croak(aTHX_ "refcnt_dec: fd %d < 0\n", fd);
168d5872
NIS
2423 }
2424 return cnt;
2425}
2426
2e0cfa16
FC
2427int
2428PerlIOUnix_refcnt(int fd)
2429{
2430 dTHX;
2431 int cnt = 0;
2432 if (fd >= 0) {
2433 dVAR;
2434#ifdef USE_ITHREADS
2435 MUTEX_LOCK(&PL_perlio_mutex);
2436#endif
2437 if (fd >= PL_perlio_fd_refcnt_size) {
2438 /* diag_listed_as: refcnt: fd %d%s */
2439 Perl_croak(aTHX_ "refcnt: fd %d >= refcnt_size %d\n",
2440 fd, PL_perlio_fd_refcnt_size);
2441 }
2442 if (PL_perlio_fd_refcnt[fd] <= 0) {
2443 /* diag_listed_as: refcnt: fd %d%s */
2444 Perl_croak(aTHX_ "refcnt: fd %d: %d <= 0\n",
2445 fd, PL_perlio_fd_refcnt[fd]);
2446 }
2447 cnt = PL_perlio_fd_refcnt[fd];
2448#ifdef USE_ITHREADS
2449 MUTEX_UNLOCK(&PL_perlio_mutex);
2450#endif
2451 } else {
2452 /* diag_listed_as: refcnt: fd %d%s */
2453 Perl_croak(aTHX_ "refcnt: fd %d < 0\n", fd);
2454 }
2455 return cnt;
2456}
2457
694c95cf
JH
2458void
2459PerlIO_cleanup(pTHX)
2460{
97aff369 2461 dVAR;
694c95cf
JH
2462 int i;
2463#ifdef USE_ITHREADS
a25429c6 2464 PerlIO_debug("Cleanup layers for %p\n",(void*)aTHX);
9f4bd222
NIS
2465#else
2466 PerlIO_debug("Cleanup layers\n");
694c95cf 2467#endif
e47547a8 2468
694c95cf
JH
2469 /* Raise STDIN..STDERR refcount so we don't close them */
2470 for (i=0; i < 3; i++)
2471 PerlIOUnix_refcnt_inc(i);
2472 PerlIO_cleantable(aTHX_ &PL_perlio);
2473 /* Restore STDIN..STDERR refcount */
2474 for (i=0; i < 3; i++)
2475 PerlIOUnix_refcnt_dec(i);
9f4bd222
NIS
2476
2477 if (PL_known_layers) {
2478 PerlIO_list_free(aTHX_ PL_known_layers);
2479 PL_known_layers = NULL;
2480 }
27da23d5 2481 if (PL_def_layerlist) {
9f4bd222
NIS
2482 PerlIO_list_free(aTHX_ PL_def_layerlist);
2483 PL_def_layerlist = NULL;
2484 }
6cb8cb21
RGS
2485}
2486
0934c9d9 2487void PerlIO_teardown(void) /* Call only from PERL_SYS_TERM(). */
6cb8cb21 2488{
53d44271 2489 dVAR;
4f3da17a
DM
2490#if 0
2491/* XXX we can't rely on an interpreter being present at this late stage,
2492 XXX so we can't use a function like PerlLIO_write that relies on one
2493 being present (at least in win32) :-(.
2494 Disable for now.
2495*/
6cb8cb21
RGS
2496#ifdef DEBUGGING
2497 {
2498 /* By now all filehandles should have been closed, so any
2499 * stray (non-STD-)filehandles indicate *possible* (PerlIO)
2500 * errors. */
77db880c
JH
2501#define PERLIO_TEARDOWN_MESSAGE_BUF_SIZE 64
2502#define PERLIO_TEARDOWN_MESSAGE_FD 2
2503 char buf[PERLIO_TEARDOWN_MESSAGE_BUF_SIZE];
6cb8cb21
RGS
2504 int i;
2505 for (i = 3; i < PL_perlio_fd_refcnt_size; i++) {
77db880c
JH
2506 if (PL_perlio_fd_refcnt[i]) {
2507 const STRLEN len =
2508 my_snprintf(buf, sizeof(buf),
2509 "PerlIO_teardown: fd %d refcnt=%d\n",
2510 i, PL_perlio_fd_refcnt[i]);
2511 PerlLIO_write(PERLIO_TEARDOWN_MESSAGE_FD, buf, len);
2512 }
6cb8cb21
RGS
2513 }
2514 }
2515#endif
4f3da17a 2516#endif
eae082a0
JH
2517 /* Not bothering with PL_perlio_mutex since by now
2518 * all the interpreters are gone. */
1cd82952
RGS
2519 if (PL_perlio_fd_refcnt_size /* Assuming initial size of zero. */
2520 && PL_perlio_fd_refcnt) {
eae082a0 2521 free(PL_perlio_fd_refcnt); /* To match realloc() in S_more_refcounted_fds(). */
432ce874
YO
2522 PL_perlio_fd_refcnt = NULL;
2523 PL_perlio_fd_refcnt_size = 0;
1cd82952 2524 }
694c95cf
JH
2525}
2526
9e353e3b 2527/*--------------------------------------------------------------------------------------*/
14a5cf38 2528/*
71200d45 2529 * Bottom-most level for UNIX-like case
14a5cf38 2530 */
9e353e3b 2531
14a5cf38 2532typedef struct {
22569500
NIS
2533 struct _PerlIO base; /* The generic part */
2534 int fd; /* UNIX like file descriptor */
2535 int oflags; /* open/fcntl flags */
9e353e3b
NIS
2536} PerlIOUnix;
2537
abf9167d
DM
2538static void
2539S_lockcnt_dec(pTHX_ const void* f)
2540{
2541 PerlIO_lockcnt((PerlIO*)f)--;
2542}
2543
2544
2545/* call the signal handler, and if that handler happens to clear
2546 * this handle, free what we can and return true */
2547
2548static bool
2549S_perlio_async_run(pTHX_ PerlIO* f) {
2550 ENTER;
2551 SAVEDESTRUCTOR_X(S_lockcnt_dec, (void*)f);
2552 PerlIO_lockcnt(f)++;
2553 PERL_ASYNC_CHECK();
be48bbe8
CS
2554 if ( !(PerlIOBase(f)->flags & PERLIO_F_CLEARED) ) {
2555 LEAVE;
abf9167d 2556 return 0;
be48bbe8 2557 }
abf9167d
DM
2558 /* we've just run some perl-level code that could have done
2559 * anything, including closing the file or clearing this layer.
2560 * If so, free any lower layers that have already been
2561 * cleared, then return an error. */
2562 while (PerlIOValid(f) &&
2563 (PerlIOBase(f)->flags & PERLIO_F_CLEARED))
2564 {
2565 const PerlIOl *l = *f;
2566 *f = l->next;
2567 Safefree(l);
2568 }
be48bbe8 2569 LEAVE;
abf9167d
DM
2570 return 1;
2571}
2572
6f9d8c32 2573int
9e353e3b 2574PerlIOUnix_oflags(const char *mode)
760ac839 2575{
14a5cf38 2576 int oflags = -1;
3b6c1aba 2577 if (*mode == IoTYPE_IMPLICIT || *mode == IoTYPE_NUMERIC)
14a5cf38
JH
2578 mode++;
2579 switch (*mode) {
2580 case 'r':
2581 oflags = O_RDONLY;
2582 if (*++mode == '+') {
2583 oflags = O_RDWR;
2584 mode++;
2585 }
2586 break;
2587
2588 case 'w':
2589 oflags = O_CREAT | O_TRUNC;
2590 if (*++mode == '+') {
2591 oflags |= O_RDWR;
2592 mode++;
2593 }
2594 else
2595 oflags |= O_WRONLY;
2596 break;
2597
2598 case 'a':
2599 oflags = O_CREAT | O_APPEND;
2600 if (*++mode == '+') {
2601 oflags |= O_RDWR;
2602 mode++;
2603 }
2604 else
2605 oflags |= O_WRONLY;
2606 break;
2607 }
2608 if (*mode == 'b') {
2609 oflags |= O_BINARY;
2610 oflags &= ~O_TEXT;
2611 mode++;
2612 }
2613 else if (*mode == 't') {
2614 oflags |= O_TEXT;
2615 oflags &= ~O_BINARY;
2616 mode++;
2617 }
2618 /*
71200d45 2619 * Always open in binary mode
14a5cf38
JH
2620 */
2621 oflags |= O_BINARY;
2622 if (*mode || oflags == -1) {
93189314 2623 SETERRNO(EINVAL, LIB_INVARG);
14a5cf38
JH
2624 oflags = -1;
2625 }
2626 return oflags;
9e353e3b
NIS
2627}
2628
2629IV
f62ce20a 2630PerlIOUnix_fileno(pTHX_ PerlIO *f)
9e353e3b 2631{
96a5add6 2632 PERL_UNUSED_CONTEXT;
14a5cf38 2633 return PerlIOSelf(f, PerlIOUnix)->fd;
9e353e3b
NIS
2634}
2635
aa063c35
NIS
2636static void
2637PerlIOUnix_setfd(pTHX_ PerlIO *f, int fd, int imode)
4b803d04 2638{
de009b76 2639 PerlIOUnix * const s = PerlIOSelf(f, PerlIOUnix);
6caa5a9c 2640#if defined(WIN32)
aa063c35
NIS
2641 Stat_t st;
2642 if (PerlLIO_fstat(fd, &st) == 0) {
6caa5a9c 2643 if (!S_ISREG(st.st_mode)) {
aa063c35 2644 PerlIO_debug("%d is not regular file\n",fd);
6caa5a9c
NIS
2645 PerlIOBase(f)->flags |= PERLIO_F_NOTREG;
2646 }
aa063c35
NIS
2647 else {
2648 PerlIO_debug("%d _is_ a regular file\n",fd);
2649 }
6caa5a9c
NIS
2650 }
2651#endif
aa063c35
NIS
2652 s->fd = fd;
2653 s->oflags = imode;
2654 PerlIOUnix_refcnt_inc(fd);
96a5add6 2655 PERL_UNUSED_CONTEXT;
aa063c35
NIS
2656}
2657
2658IV
2659PerlIOUnix_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
2660{
2661 IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
14a5cf38 2662 if (*PerlIONext(f)) {
4b069b44 2663 /* We never call down so do any pending stuff now */
03c0554d 2664 PerlIO_flush(PerlIONext(f));
14a5cf38 2665 /*
71200d45 2666 * XXX could (or should) we retrieve the oflags from the open file
14a5cf38 2667 * handle rather than believing the "mode" we are passed in? XXX
71200d45 2668 * Should the value on NULL mode be 0 or -1?
14a5cf38 2669 */
acbd16bf 2670 PerlIOUnix_setfd(aTHX_ f, PerlIO_fileno(PerlIONext(f)),
aa063c35 2671 mode ? PerlIOUnix_oflags(mode) : -1);
14a5cf38
JH
2672 }
2673 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
6caa5a9c 2674
14a5cf38 2675 return code;
4b803d04
NIS
2676}
2677
c2fcde81
JH
2678IV
2679PerlIOUnix_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
2680{
de009b76 2681 const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
0723351e 2682 Off_t new_loc;
96a5add6 2683 PERL_UNUSED_CONTEXT;
c2fcde81
JH
2684 if (PerlIOBase(f)->flags & PERLIO_F_NOTREG) {
2685#ifdef ESPIPE
2686 SETERRNO(ESPIPE, LIB_INVARG);
2687#else
2688 SETERRNO(EINVAL, LIB_INVARG);
2689#endif
2690 return -1;
2691 }
0723351e
NC
2692 new_loc = PerlLIO_lseek(fd, offset, whence);
2693 if (new_loc == (Off_t) - 1)
dcda55fc 2694 return -1;
c2fcde81
JH
2695 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
2696 return 0;
2697}
2698
9e353e3b 2699PerlIO *
14a5cf38
JH
2700PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
2701 IV n, const char *mode, int fd, int imode,
2702 int perm, PerlIO *f, int narg, SV **args)
2703{
d9dac8cd 2704 if (PerlIOValid(f)) {
cc6623a8 2705 if (PerlIOBase(f)->tab && PerlIOBase(f)->flags & PERLIO_F_OPEN)
f62ce20a 2706 (*PerlIOBase(f)->tab->Close)(aTHX_ f);
14a5cf38
JH
2707 }
2708 if (narg > 0) {
3b6c1aba 2709 if (*mode == IoTYPE_NUMERIC)
14a5cf38
JH
2710 mode++;
2711 else {
2712 imode = PerlIOUnix_oflags(mode);
5e2ce0f3
CB
2713#ifdef VMS
2714 perm = 0777; /* preserve RMS defaults, ACL inheritance, etc. */
2715#else
14a5cf38 2716 perm = 0666;
5e2ce0f3 2717#endif
14a5cf38
JH
2718 }
2719 if (imode != -1) {
e62f0680 2720 const char *path = SvPV_nolen_const(*args);
14a5cf38
JH
2721 fd = PerlLIO_open3(path, imode, perm);
2722 }
2723 }
2724 if (fd >= 0) {
3b6c1aba 2725 if (*mode == IoTYPE_IMPLICIT)
14a5cf38
JH
2726 mode++;
2727 if (!f) {
2728 f = PerlIO_allocate(aTHX);
d9dac8cd
NIS
2729 }
2730 if (!PerlIOValid(f)) {
a33cf58c
NIS
2731 if (!(f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg))) {
2732 return NULL;
2733 }
d9dac8cd 2734 }
aa063c35 2735 PerlIOUnix_setfd(aTHX_ f, fd, imode);
14a5cf38 2736 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
c2fcde81
JH
2737 if (*mode == IoTYPE_APPEND)
2738 PerlIOUnix_seek(aTHX_ f, 0, SEEK_END);
14a5cf38
JH
2739 return f;
2740 }
2741 else {
2742 if (f) {
6f207bd3 2743 NOOP;
14a5cf38 2744 /*
71200d45 2745 * FIXME: pop layers ???
14a5cf38
JH
2746 */
2747 }
2748 return NULL;
2749 }
9e353e3b
NIS
2750}
2751
71200d45 2752PerlIO *
ecdeb87c 2753PerlIOUnix_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
71200d45 2754{
dcda55fc 2755 const PerlIOUnix * const os = PerlIOSelf(o, PerlIOUnix);
93a8090d 2756 int fd = os->fd;
ecdeb87c
NIS
2757 if (flags & PERLIO_DUP_FD) {
2758 fd = PerlLIO_dup(fd);
2759 }
22c96fc1 2760 if (fd >= 0) {
ecdeb87c 2761 f = PerlIOBase_dup(aTHX_ f, o, param, flags);
71200d45
NIS
2762 if (f) {
2763 /* If all went well overwrite fd in dup'ed lay with the dup()'ed fd */
aa063c35 2764 PerlIOUnix_setfd(aTHX_ f, fd, os->oflags);
71200d45
NIS
2765 return f;
2766 }
71200d45
NIS
2767 }
2768 return NULL;
2769}
2770
2771
9e353e3b 2772SSize_t
f62ce20a 2773PerlIOUnix_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
9e353e3b 2774{
97aff369 2775 dVAR;
abf9167d
DM
2776 int fd;
2777 if (PerlIO_lockcnt(f)) /* in use: abort ungracefully */
2778 return -1;
2779 fd = PerlIOSelf(f, PerlIOUnix)->fd;
27da23d5
JH
2780#ifdef PERLIO_STD_SPECIAL
2781 if (fd == 0)
2782 return PERLIO_STD_IN(fd, vbuf, count);
2783#endif
81428673 2784 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD) ||
1fd8f4ce 2785 PerlIOBase(f)->flags & (PERLIO_F_EOF|PERLIO_F_ERROR)) {
263df5f1 2786 return 0;
1fd8f4ce 2787 }
14a5cf38 2788 while (1) {
b464bac0 2789 const SSize_t len = PerlLIO_read(fd, vbuf, count);
14a5cf38 2790 if (len >= 0 || errno != EINTR) {
ba85f2ea
NIS
2791 if (len < 0) {
2792 if (errno != EAGAIN) {
2793 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
2794 }
2795 }
2796 else if (len == 0 && count != 0) {
14a5cf38 2797 PerlIOBase(f)->flags |= PERLIO_F_EOF;
ba85f2ea
NIS
2798 SETERRNO(0,0);
2799 }
14a5cf38
JH
2800 return len;
2801 }
abf9167d
DM
2802 /* EINTR */
2803 if (PL_sig_pending && S_perlio_async_run(aTHX_ f))
2804 return -1;
14a5cf38 2805 }
b464bac0 2806 /*NOTREACHED*/
9e353e3b
NIS
2807}
2808
2809SSize_t
f62ce20a 2810PerlIOUnix_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
9e353e3b 2811{
97aff369 2812 dVAR;
abf9167d
DM
2813 int fd;
2814 if (PerlIO_lockcnt(f)) /* in use: abort ungracefully */
2815 return -1;
2816 fd = PerlIOSelf(f, PerlIOUnix)->fd;
27da23d5
JH
2817#ifdef PERLIO_STD_SPECIAL
2818 if (fd == 1 || fd == 2)
2819 return PERLIO_STD_OUT(fd, vbuf, count);
2820#endif
14a5cf38 2821 while (1) {
de009b76 2822 const SSize_t len = PerlLIO_write(fd, vbuf, count);
14a5cf38 2823 if (len >= 0 || errno != EINTR) {
ba85f2ea
NIS
2824 if (len < 0) {
2825 if (errno != EAGAIN) {
2826 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
2827 }
2828 }
14a5cf38
JH
2829 return len;
2830 }
abf9167d
DM
2831 /* EINTR */
2832 if (PL_sig_pending && S_perlio_async_run(aTHX_ f))
2833 return -1;
06da4f11 2834 }
1b6737cc 2835 /*NOTREACHED*/
9e353e3b
NIS
2836}
2837
9e353e3b 2838Off_t
f62ce20a 2839PerlIOUnix_tell(pTHX_ PerlIO *f)
9e353e3b 2840{
96a5add6
AL
2841 PERL_UNUSED_CONTEXT;
2842
14a5cf38 2843 return PerlLIO_lseek(PerlIOSelf(f, PerlIOUnix)->fd, 0, SEEK_CUR);
9e353e3b
NIS
2844}
2845
2556f95e
GF
2846
2847IV
2376d97d 2848PerlIOUnix_close(pTHX_ PerlIO *f)
2556f95e 2849{
97aff369 2850 dVAR;
de009b76 2851 const int fd = PerlIOSelf(f, PerlIOUnix)->fd;
14a5cf38 2852 int code = 0;
168d5872
NIS
2853 if (PerlIOBase(f)->flags & PERLIO_F_OPEN) {
2854 if (PerlIOUnix_refcnt_dec(fd) > 0) {
93a8090d
NIS
2855 PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
2856 return 0;
22569500 2857 }
93a8090d
NIS
2858 }
2859 else {
93189314 2860 SETERRNO(EBADF,SS_IVCHAN);
93a8090d
NIS
2861 return -1;
2862 }
14a5cf38
JH
2863 while (PerlLIO_close(fd) != 0) {
2864 if (errno != EINTR) {
2865 code = -1;
2866 break;
2867 }
abf9167d
DM
2868 /* EINTR */
2869 if (PL_sig_pending && S_perlio_async_run(aTHX_ f))
2870 return -1;
14a5cf38
JH
2871 }
2872 if (code == 0) {
2873 PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
2874 }
2875 return code;
9e353e3b
NIS
2876}
2877
27da23d5 2878PERLIO_FUNCS_DECL(PerlIO_unix) = {
2dc2558e 2879 sizeof(PerlIO_funcs),
14a5cf38
JH
2880 "unix",
2881 sizeof(PerlIOUnix),
2882 PERLIO_K_RAW,
2883 PerlIOUnix_pushed,
2376d97d 2884 PerlIOBase_popped,
14a5cf38 2885 PerlIOUnix_open,
86e05cf2 2886 PerlIOBase_binmode, /* binmode */
14a5cf38
JH
2887 NULL,
2888 PerlIOUnix_fileno,
71200d45 2889 PerlIOUnix_dup,
14a5cf38
JH
2890 PerlIOUnix_read,
2891 PerlIOBase_unread,
2892 PerlIOUnix_write,
2893 PerlIOUnix_seek,
2894 PerlIOUnix_tell,
2895 PerlIOUnix_close,
22569500
NIS
2896 PerlIOBase_noop_ok, /* flush */
2897 PerlIOBase_noop_fail, /* fill */
14a5cf38
JH
2898 PerlIOBase_eof,
2899 PerlIOBase_error,
2900 PerlIOBase_clearerr,
2901 PerlIOBase_setlinebuf,
22569500
NIS
2902 NULL, /* get_base */
2903 NULL, /* get_bufsiz */
2904 NULL, /* get_ptr */
2905 NULL, /* get_cnt */
2906 NULL, /* set_ptrcnt */
9e353e3b
NIS
2907};
2908
2909/*--------------------------------------------------------------------------------------*/
14a5cf38 2910/*
71200d45 2911 * stdio as a layer
14a5cf38 2912 */
9e353e3b 2913
313e59c8
NIS
2914#if defined(VMS) && !defined(STDIO_BUFFER_WRITABLE)
2915/* perl5.8 - This ensures the last minute VMS ungetc fix is not
2916 broken by the last second glibc 2.3 fix
2917 */
2918#define STDIO_BUFFER_WRITABLE
2919#endif
2920
2921
14a5cf38
JH
2922typedef struct {
2923 struct _PerlIO base;
22569500 2924 FILE *stdio; /* The stream */
9e353e3b
NIS
2925} PerlIOStdio;
2926
2927IV
f62ce20a 2928PerlIOStdio_fileno(pTHX_ PerlIO *f)
9e353e3b 2929{
96a5add6
AL
2930 PERL_UNUSED_CONTEXT;
2931
c4420975
AL
2932 if (PerlIOValid(f)) {
2933 FILE * const s = PerlIOSelf(f, PerlIOStdio)->stdio;
2934 if (s)
2935 return PerlSIO_fileno(s);
439ba545
NIS
2936 }
2937 errno = EBADF;
2938 return -1;
9e353e3b
NIS
2939}
2940
766a733e 2941char *
14a5cf38
JH
2942PerlIOStdio_mode(const char *mode, char *tmode)
2943{
de009b76 2944 char * const ret = tmode;
a0625d38
SR
2945 if (mode) {
2946 while (*mode) {
2947 *tmode++ = *mode++;
2948 }
14a5cf38 2949 }
95005ad8 2950#if defined(PERLIO_USING_CRLF) || defined(__CYGWIN__)
6ce75a77
JH
2951 *tmode++ = 'b';
2952#endif
14a5cf38
JH
2953 *tmode = '\0';
2954 return ret;
2955}
2956
4b803d04 2957IV
2dc2558e 2958PerlIOStdio_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
4b803d04 2959{
1fd8f4ce
NIS
2960 PerlIO *n;
2961 if (PerlIOValid(f) && PerlIOValid(n = PerlIONext(f))) {
46c461b5 2962 PerlIO_funcs * const toptab = PerlIOBase(n)->tab;
1fd8f4ce
NIS
2963 if (toptab == tab) {
2964 /* Top is already stdio - pop self (duplicate) and use original */
2965 PerlIO_pop(aTHX_ f);
2966 return 0;
2967 } else {
de009b76 2968 const int fd = PerlIO_fileno(n);
1fd8f4ce
NIS
2969 char tmode[8];
2970 FILE *stdio;
81428673 2971 if (fd >= 0 && (stdio = PerlSIO_fdopen(fd,
1fd8f4ce
NIS
2972 mode = PerlIOStdio_mode(mode, tmode)))) {
2973 PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
2974 /* We never call down so do any pending stuff now */
2975 PerlIO_flush(PerlIONext(f));
81428673 2976 }
1fd8f4ce
NIS
2977 else {
2978 return -1;
2979 }
2980 }
14a5cf38 2981 }
2dc2558e 2982 return PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
4b803d04
NIS
2983}
2984
22569500 2985
9e353e3b 2986PerlIO *
4b069b44 2987PerlIO_importFILE(FILE *stdio, const char *mode)
9e353e3b 2988{
14a5cf38
JH
2989 dTHX;
2990 PerlIO *f = NULL;
2991 if (stdio) {
22569500 2992 PerlIOStdio *s;
4b069b44
NIS
2993 if (!mode || !*mode) {
2994 /* We need to probe to see how we can open the stream
2995 so start with read/write and then try write and read
2996 we dup() so that we can fclose without loosing the fd.
2997
2998 Note that the errno value set by a failing fdopen
2999 varies between stdio implementations.
3000 */
de009b76 3001 const int fd = PerlLIO_dup(fileno(stdio));
a33cf58c 3002 FILE *f2 = PerlSIO_fdopen(fd, (mode = "r+"));
4b069b44 3003 if (!f2) {
a33cf58c 3004 f2 = PerlSIO_fdopen(fd, (mode = "w"));
4b069b44
NIS
3005 }
3006 if (!f2) {
a33cf58c 3007 f2 = PerlSIO_fdopen(fd, (mode = "r"));
4b069b44
NIS
3008 }
3009 if (!f2) {
3010 /* Don't seem to be able to open */
3011 PerlLIO_close(fd);
3012 return f;
3013 }
3014 fclose(f2);
22569500 3015 }
a0714e2c 3016 if ((f = PerlIO_push(aTHX_(f = PerlIO_allocate(aTHX)), PERLIO_FUNCS_CAST(&PerlIO_stdio), mode, NULL))) {
a33cf58c
NIS
3017 s = PerlIOSelf(f, PerlIOStdio);
3018 s->stdio = stdio;
c586124f 3019 PerlIOUnix_refcnt_inc(fileno(stdio));
a33cf58c 3020 }
14a5cf38
JH
3021 }
3022 return f;
9e353e3b
NIS
3023}
3024
3025PerlIO *
14a5cf38
JH
3026PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
3027 IV n, const char *mode, int fd, int imode,
3028 int perm, PerlIO *f, int narg, SV **args)
3029{
3030 char tmode[8];
d9dac8cd 3031 if (PerlIOValid(f)) {
dcda55fc
AL
3032 const char * const path = SvPV_nolen_const(*args);
3033 PerlIOStdio * const s = PerlIOSelf(f, PerlIOStdio);
1751d015
NIS
3034 FILE *stdio;
3035 PerlIOUnix_refcnt_dec(fileno(s->stdio));
3036 stdio = PerlSIO_freopen(path, (mode = PerlIOStdio_mode(mode, tmode)),
14a5cf38
JH
3037 s->stdio);
3038 if (!s->stdio)
3039 return NULL;
3040 s->stdio = stdio;
1751d015 3041 PerlIOUnix_refcnt_inc(fileno(s->stdio));
14a5cf38
JH
3042 return f;
3043 }
3044 else {
3045 if (narg > 0) {
dcda55fc 3046 const char * const path = SvPV_nolen_const(*args);
3b6c1aba 3047 if (*mode == IoTYPE_NUMERIC) {
14a5cf38
JH
3048 mode++;
3049 fd = PerlLIO_open3(path, imode, perm);
3050 }
3051 else {
95005ad8
GH
3052 FILE *stdio;
3053 bool appended = FALSE;
3054#ifdef __CYGWIN__
3055 /* Cygwin wants its 'b' early. */
3056 appended = TRUE;
3057 mode = PerlIOStdio_mode(mode, tmode);
3058#endif
3059 stdio = PerlSIO_fopen(path, mode);
6f0313ac 3060 if (stdio) {
6f0313ac
JH
3061 if (!f) {
3062 f = PerlIO_allocate(aTHX);
3063 }
95005ad8
GH
3064 if (!appended)
3065 mode = PerlIOStdio_mode(mode, tmode);
3066 f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg);
3067 if (f) {
0f0f9e2b
JH
3068 PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
3069 PerlIOUnix_refcnt_inc(fileno(stdio));
3070 } else {
3071 PerlSIO_fclose(stdio);
6f0313ac
JH
3072 }
3073 return f;
3074 }
3075 else {
3076 return NULL;
3077 }
14a5cf38
JH
3078 }
3079 }
3080 if (fd >= 0) {
3081 FILE *stdio = NULL;
3082 int init = 0;
3b6c1aba 3083 if (*mode == IoTYPE_IMPLICIT) {
14a5cf38
JH
3084 init = 1;
3085 mode++;
3086 }
3087 if (init) {
3088 switch (fd) {
3089 case 0:
3090 stdio = PerlSIO_stdin;
3091 break;
3092 case 1:
3093 stdio = PerlSIO_stdout;
3094 break;
3095 case 2:
3096 stdio = PerlSIO_stderr;
3097 break;
3098 }
3099 }
3100 else {
3101 stdio = PerlSIO_fdopen(fd, mode =
3102 PerlIOStdio_mode(mode, tmode));
3103 }
3104 if (stdio) {
d9dac8cd
NIS
3105 if (!f) {
3106 f = PerlIO_allocate(aTHX);
3107 }
a33cf58c 3108 if ((f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg))) {
1a159fba
JH
3109 PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
3110 PerlIOUnix_refcnt_inc(fileno(stdio));
a33cf58c 3111 }
14a5cf38
JH
3112 return f;
3113 }
3114 }
3115 }
ee518936 3116 return NULL;
9e353e3b
NIS
3117}
3118
1751d015 3119PerlIO *
ecdeb87c 3120PerlIOStdio_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
1751d015
NIS
3121{
3122 /* This assumes no layers underneath - which is what
3123 happens, but is not how I remember it. NI-S 2001/10/16
3124 */
ecdeb87c 3125 if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
694c95cf 3126 FILE *stdio = PerlIOSelf(o, PerlIOStdio)->stdio;
de009b76 3127 const int fd = fileno(stdio);
9217ff3f 3128 char mode[8];
ecdeb87c 3129 if (flags & PERLIO_DUP_FD) {
de009b76 3130 const int dfd = PerlLIO_dup(fileno(stdio));
9217ff3f
NIS
3131 if (dfd >= 0) {
3132 stdio = PerlSIO_fdopen(dfd, PerlIO_modestr(o,mode));
3133 goto set_this;
ecdeb87c
NIS
3134 }
3135 else {
6f207bd3 3136 NOOP;
ecdeb87c
NIS
3137 /* FIXME: To avoid messy error recovery if dup fails
3138 re-use the existing stdio as though flag was not set
3139 */
3140 }
3141 }
9217ff3f
NIS
3142 stdio = PerlSIO_fdopen(fd, PerlIO_modestr(o,mode));
3143 set_this:
694c95cf 3144 PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
40596bc5
SP
3145 if(stdio) {
3146 PerlIOUnix_refcnt_inc(fileno(stdio));
3147 }
1751d015
NIS
3148 }
3149 return f;
3150}
3151
0d7a5398
NIS
3152static int
3153PerlIOStdio_invalidate_fileno(pTHX_ FILE *f)
3154{
96a5add6
AL
3155 PERL_UNUSED_CONTEXT;
3156
0d7a5398 3157 /* XXX this could use PerlIO_canset_fileno() and
37725cdc 3158 * PerlIO_set_fileno() support from Configure
0d7a5398 3159 */
ef8eacb8
AT
3160# if defined(__UCLIBC__)
3161 /* uClibc must come before glibc because it defines __GLIBC__ as well. */
3162 f->__filedes = -1;
3163 return 1;
3164# elif defined(__GLIBC__)
0d7a5398 3165 /* There may be a better way for GLIBC:
37725cdc 3166 - libio.h defines a flag to not close() on cleanup
0d7a5398
NIS
3167 */
3168 f->_fileno = -1;
3169 return 1;
3170# elif defined(__sun__)
f5992bc4 3171 PERL_UNUSED_ARG(f);
cfedb851 3172 return 0;
0d7a5398
NIS
3173# elif defined(__hpux)
3174 f->__fileH = 0xff;
3175 f->__fileL = 0xff;
3176 return 1;
9837d373 3177 /* Next one ->_file seems to be a reasonable fallback, i.e. if
37725cdc 3178 your platform does not have special entry try this one.
9837d373
NIS
3179 [For OSF only have confirmation for Tru64 (alpha)
3180 but assume other OSFs will be similar.]
37725cdc 3181 */
9837d373 3182# elif defined(_AIX) || defined(__osf__) || defined(__irix__)
0d7a5398
NIS
3183 f->_file = -1;
3184 return 1;
3185# elif defined(__FreeBSD__)
3186 /* There may be a better way on FreeBSD:
37725cdc
NIS
3187 - we could insert a dummy func in the _close function entry
3188 f->_close = (int (*)(void *)) dummy_close;
0d7a5398
NIS
3189 */
3190 f->_file = -1;
0c49ea6a
SU
3191 return 1;
3192# elif defined(__OpenBSD__)
3193 /* There may be a better way on OpenBSD:
3194 - we could insert a dummy func in the _close function entry
3195 f->_close = (int (*)(void *)) dummy_close;
3196 */
3197 f->_file = -1;
0d7a5398 3198 return 1;
59ad941d
IZ
3199# elif defined(__EMX__)
3200 /* f->_flags &= ~_IOOPEN; */ /* Will leak stream->_buffer */
3201 f->_handle = -1;
3202 return 1;
0d7a5398
NIS
3203# elif defined(__CYGWIN__)
3204 /* There may be a better way on CYGWIN:
37725cdc
NIS
3205 - we could insert a dummy func in the _close function entry
3206 f->_close = (int (*)(void *)) dummy_close;
0d7a5398
NIS
3207 */
3208 f->_file = -1;
3209 return 1;
3210# elif defined(WIN32)
378eeda7 3211# if defined(UNDER_CE)
b475b3e6
JH
3212 /* WIN_CE does not have access to FILE internals, it hardly has FILE
3213 structure at all
3214 */
0d7a5398
NIS
3215# else
3216 f->_file = -1;
3217# endif
3218 return 1;
3219# else
3220#if 0
37725cdc 3221 /* Sarathy's code did this - we fall back to a dup/dup2 hack
0d7a5398 3222 (which isn't thread safe) instead
37725cdc 3223 */
0d7a5398
NIS
3224# error "Don't know how to set FILE.fileno on your platform"
3225#endif
8772537c 3226 PERL_UNUSED_ARG(f);
0d7a5398
NIS
3227 return 0;
3228# endif
3229}
3230
1751d015 3231IV
f62ce20a 3232PerlIOStdio_close(pTHX_ PerlIO *f)
1751d015 3233{
c4420975 3234 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
439ba545
NIS
3235 if (!stdio) {
3236 errno = EBADF;
3237 return -1;
3238 }
9217ff3f 3239 else {
de009b76 3240 const int fd = fileno(stdio);
0d7a5398 3241 int invalidate = 0;
bbfd922f 3242 IV result = 0;
1d791a44 3243 int dupfd = -1;
4ee39169 3244 dSAVEDERRNO;
a2e578da
MHM
3245#ifdef USE_ITHREADS
3246 dVAR;
3247#endif
0d7a5398 3248#ifdef SOCKS5_VERSION_NAME
37725cdc
NIS
3249 /* Socks lib overrides close() but stdio isn't linked to
3250 that library (though we are) - so we must call close()
3251 on sockets on stdio's behalf.
3252 */
0d7a5398
NIS
3253 int optval;
3254 Sock_size_t optlen = sizeof(int);
6b4ce6c8 3255 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *) &optval, &optlen) == 0)
37725cdc 3256 invalidate = 1;
0d7a5398 3257#endif
d8723f43
NC
3258 /* Test for -1, as *BSD stdio (at least) on fclose sets the FILE* such
3259 that a subsequent fileno() on it returns -1. Don't want to croak()
3260 from within PerlIOUnix_refcnt_dec() if some buggy caller code is
3261 trying to close an already closed handle which somehow it still has
3262 a reference to. (via.xs, I'm looking at you). */
3263 if (fd != -1 && PerlIOUnix_refcnt_dec(fd) > 0) {
3264 /* File descriptor still in use */
0d7a5398 3265 invalidate = 1;
d8723f43 3266 }
0d7a5398 3267 if (invalidate) {
6b4ce6c8
AL
3268 /* For STD* handles, don't close stdio, since we shared the FILE *, too. */
3269 if (stdio == stdin) /* Some stdios are buggy fflush-ing inputs */
3270 return 0;
3271 if (stdio == stdout || stdio == stderr)
3272 return PerlIO_flush(f);
37725cdc
NIS
3273 /* Tricky - must fclose(stdio) to free memory but not close(fd)
3274 Use Sarathy's trick from maint-5.6 to invalidate the
3275 fileno slot of the FILE *
3276 */
bbfd922f 3277 result = PerlIO_flush(f);
4ee39169 3278 SAVE_ERRNO;
6b4ce6c8 3279 invalidate = PerlIOStdio_invalidate_fileno(aTHX_ stdio);
711e8db2 3280 if (!invalidate) {
9bab90c0
NC
3281#ifdef USE_ITHREADS
3282 MUTEX_LOCK(&PL_perlio_mutex);
5ca745d2
NC
3283 /* Right. We need a mutex here because for a brief while we
3284 will have the situation that fd is actually closed. Hence if
3285 a second thread were to get into this block, its dup() would
3286 likely return our fd as its dupfd. (after all, it is closed)
9bab90c0
NC
3287 Then if we get to the dup2() first, we blat the fd back
3288 (messing up its temporary as a side effect) only for it to
3289 then close its dupfd (== our fd) in its close(dupfd) */
3290
3291 /* There is, of course, a race condition, that any other thread
3292 trying to input/output/whatever on this fd will be stuffed
5ca745d2
NC
3293 for the duration of this little manoeuvrer. Perhaps we
3294 should hold an IO mutex for the duration of every IO
3295 operation if we know that invalidate doesn't work on this
3296 platform, but that would suck, and could kill performance.
9bab90c0
NC
3297
3298 Except that correctness trumps speed.
3299 Advice from klortho #11912. */
3300#endif
6b4ce6c8 3301 dupfd = PerlLIO_dup(fd);
711e8db2 3302#ifdef USE_ITHREADS
9bab90c0
NC
3303 if (dupfd < 0) {
3304 MUTEX_UNLOCK(&PL_perlio_mutex);
711e8db2
NC
3305 /* Oh cXap. This isn't going to go well. Not sure if we can
3306 recover from here, or if closing this particular FILE *
3307 is a good idea now. */
3308 }
3309#endif
3310 }
94ccb807
JH
3311 } else {
3312 SAVE_ERRNO; /* This is here only to silence compiler warnings */
37725cdc 3313 }
0d7a5398 3314 result = PerlSIO_fclose(stdio);
37725cdc
NIS
3315 /* We treat error from stdio as success if we invalidated
3316 errno may NOT be expected EBADF
e8529473
NIS
3317 */
3318 if (invalidate && result != 0) {
4ee39169 3319 RESTORE_ERRNO;
0d7a5398 3320 result = 0;
37725cdc 3321 }
6b4ce6c8
AL
3322#ifdef SOCKS5_VERSION_NAME
3323 /* in SOCKS' case, let close() determine return value */
3324 result = close(fd);
3325#endif
1d791a44 3326 if (dupfd >= 0) {
0d7a5398 3327 PerlLIO_dup2(dupfd,fd);
9bab90c0 3328 PerlLIO_close(dupfd);
711e8db2 3329#ifdef USE_ITHREADS
9bab90c0 3330 MUTEX_UNLOCK(&PL_perlio_mutex);
711e8db2 3331#endif
9217ff3f
NIS
3332 }
3333 return result;
37725cdc 3334 }
1751d015
NIS
3335}
3336
9e353e3b 3337SSize_t
f62ce20a 3338PerlIOStdio_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
9e353e3b 3339{
97aff369 3340 dVAR;
abf9167d 3341 FILE * s;
14a5cf38 3342 SSize_t got = 0;
abf9167d
DM
3343 if (PerlIO_lockcnt(f)) /* in use: abort ungracefully */
3344 return -1;
3345 s = PerlIOSelf(f, PerlIOStdio)->stdio;
4d948241
NIS
3346 for (;;) {
3347 if (count == 1) {
3348 STDCHAR *buf = (STDCHAR *) vbuf;
3349 /*
3350 * Perl is expecting PerlIO_getc() to fill the buffer Linux's
3351 * stdio does not do that for fread()
3352 */
de009b76 3353 const int ch = PerlSIO_fgetc(s);
4d948241
NIS
3354 if (ch != EOF) {
3355 *buf = ch;
3356 got = 1;
3357 }
14a5cf38 3358 }
4d948241
NIS
3359 else
3360 got = PerlSIO_fread(vbuf, 1, count, s);
b1d8b47a
CS
3361 if (got == 0 && PerlSIO_ferror(s))
3362 got = -1;
42a7a32f 3363 if (got >= 0 || errno != EINTR)
4d948241 3364 break;
abf9167d
DM
3365 if (PL_sig_pending && S_perlio_async_run(aTHX_ f))
3366 return -1;
42a7a32f 3367 SETERRNO(0,0); /* just in case */
14a5cf38 3368 }
14a5cf38 3369 return got;
9e353e3b
NIS
3370}
3371
3372SSize_t
f62ce20a 3373PerlIOStdio_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
9e353e3b 3374{
14a5cf38 3375 SSize_t unread = 0;
c4420975 3376 FILE * const s = PerlIOSelf(f, PerlIOStdio)->stdio;
93679785 3377
313e59c8 3378#ifdef STDIO_BUFFER_WRITABLE
9f7cd136 3379 if (PerlIO_fast_gets(f) && PerlIO_has_base(f)) {
93679785
NIS
3380 STDCHAR *buf = ((STDCHAR *) vbuf) + count;
3381 STDCHAR *base = PerlIO_get_base(f);
3382 SSize_t cnt = PerlIO_get_cnt(f);
3383 STDCHAR *ptr = PerlIO_get_ptr(f);
3384 SSize_t avail = ptr - base;
3385 if (avail > 0) {
3386 if (avail > count) {
3387 avail = count;
3388 }
3389 ptr -= avail;
3390 Move(buf-avail,ptr,avail,STDCHAR);
3391 count -= avail;
3392 unread += avail;
3393 PerlIO_set_ptrcnt(f,ptr,cnt+avail);
9f7cd136
NIS
3394 if (PerlSIO_feof(s) && unread >= 0)
3395 PerlSIO_clearerr(s);
3396 }
3397 }
313e59c8
NIS
3398 else
3399#endif
3400 if (PerlIO_has_cntptr(f)) {
9f7cd136
NIS
3401 /* We can get pointer to buffer but not its base
3402 Do ungetc() but check chars are ending up in the
3403 buffer
3404 */
3405 STDCHAR *eptr = (STDCHAR*)PerlSIO_get_ptr(s);
3406 STDCHAR *buf = ((STDCHAR *) vbuf) + count;
3407 while (count > 0) {
de009b76 3408 const int ch = *--buf & 0xFF;
9f7cd136
NIS
3409 if (ungetc(ch,s) != ch) {
3410 /* ungetc did not work */
3411 break;
3412 }
3413 if ((STDCHAR*)PerlSIO_get_ptr(s) != --eptr || ((*eptr & 0xFF) != ch)) {
3414 /* Did not change pointer as expected */
3415 fgetc(s); /* get char back again */
3416 break;
3417 }
3418 /* It worked ! */
3419 count--;
3420 unread++;
93679785
NIS
3421 }
3422 }
3423
3424 if (count > 0) {
3425 unread += PerlIOBase_unread(aTHX_ f, vbuf, count);
14a5cf38
JH
3426 }
3427 return unread;
9e353e3b
NIS
3428}
3429
3430SSize_t
f62ce20a 3431PerlIOStdio_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
9e353e3b 3432{
97aff369 3433 dVAR;
4d948241 3434 SSize_t got;
abf9167d
DM
3435 if (PerlIO_lockcnt(f)) /* in use: abort ungracefully */
3436 return -1;
4d948241
NIS
3437 for (;;) {
3438 got = PerlSIO_fwrite(vbuf, 1, count,
3439 PerlIOSelf(f, PerlIOStdio)->stdio);
42a7a32f 3440 if (got >= 0 || errno != EINTR)
4d948241 3441 break;
abf9167d
DM
3442 if (PL_sig_pending && S_perlio_async_run(aTHX_ f))
3443 return -1;
42a7a32f 3444 SETERRNO(0,0); /* just in case */
4d948241
NIS
3445 }
3446 return got;
9e353e3b
NIS
3447}
3448
94a175e1 3449IV
f62ce20a 3450PerlIOStdio_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
9e353e3b 3451{
c4420975 3452 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
96a5add6
AL
3453 PERL_UNUSED_CONTEXT;
3454
94a175e1 3455 return PerlSIO_fseek(stdio, offset, whence);
9e353e3b
NIS
3456}
3457
3458Off_t
f62ce20a 3459PerlIOStdio_tell(pTHX_ PerlIO *f)
9e353e3b 3460{
c4420975 3461 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
96a5add6
AL
3462 PERL_UNUSED_CONTEXT;
3463
94a175e1 3464 return PerlSIO_ftell(stdio);
9e353e3b
NIS
3465}
3466
3467IV
f62ce20a 3468PerlIOStdio_flush(pTHX_ PerlIO *f)
9e353e3b 3469{
c4420975 3470 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
96a5add6
AL
3471 PERL_UNUSED_CONTEXT;
3472
14a5cf38
JH
3473 if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) {
3474 return PerlSIO_fflush(stdio);
3475 }
3476 else {
6f207bd3 3477 NOOP;
88b61e10 3478#if 0
14a5cf38
JH
3479 /*
3480 * FIXME: This discards ungetc() and pre-read stuff which is not
71200d45 3481 * right if this is just a "sync" from a layer above Suspect right
14a5cf38 3482 * design is to do _this_ but not have layer above flush this
71200d45 3483 * layer read-to-read
14a5cf38
JH
3484 */
3485 /*
71200d45 3486 * Not writeable - sync by attempting a seek
14a5cf38 3487 */
4ee39169 3488 dSAVE_ERRNO;
14a5cf38 3489 if (PerlSIO_fseek(stdio, (Off_t) 0, SEEK_CUR) != 0)
4ee39169 3490 RESTORE_ERRNO;
88b61e10 3491#endif
14a5cf38
JH
3492 }
3493 return 0;
9e353e3b
NIS
3494}
3495
3496IV
f62ce20a 3497PerlIOStdio_eof(pTHX_ PerlIO *f)
9e353e3b 3498{
96a5add6
AL
3499 PERL_UNUSED_CONTEXT;
3500
14a5cf38 3501 return PerlSIO_feof(PerlIOSelf(f, PerlIOStdio)->stdio);
9e353e3b
NIS
3502}
3503
3504IV
f62ce20a 3505PerlIOStdio_error(pTHX_ PerlIO *f)
9e353e3b 3506{
96a5add6
AL
3507 PERL_UNUSED_CONTEXT;
3508
263df5f1 3509 return PerlSIO_ferror(PerlIOSelf(f, PerlIOStdio)->stdio);
9e353e3b
NIS
3510}
3511
3512void
f62ce20a 3513PerlIOStdio_clearerr(pTHX_ PerlIO *f)
9e353e3b 3514{
96a5add6
AL
3515 PERL_UNUSED_CONTEXT;
3516
14a5cf38 3517 PerlSIO_clearerr(PerlIOSelf(f, PerlIOStdio)->stdio);
9e353e3b
NIS
3518}
3519
3520void
f62ce20a 3521PerlIOStdio_setlinebuf(pTHX_ PerlIO *f)
9e353e3b 3522{
96a5add6
AL
3523 PERL_UNUSED_CONTEXT;
3524
9e353e3b 3525#ifdef HAS_SETLINEBUF
14a5cf38 3526 PerlSIO_setlinebuf(PerlIOSelf(f, PerlIOStdio)->stdio);
9e353e3b 3527#else
bd61b366 3528 PerlSIO_setvbuf(PerlIOSelf(f, PerlIOStdio)->stdio, NULL, _IOLBF, 0);
9e353e3b
NIS
3529#endif
3530}
3531
3532#ifdef FILE_base
3533STDCHAR *
f62ce20a 3534PerlIOStdio_get_base(pTHX_ PerlIO *f)
9e353e3b 3535{
c4420975 3536 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
cc00df79 3537 return (STDCHAR*)PerlSIO_get_base(stdio);
9e353e3b
NIS
3538}
3539
3540Size_t
f62ce20a 3541PerlIOStdio_get_bufsiz(pTHX_ PerlIO *f)
9e353e3b 3542{
c4420975 3543 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
14a5cf38 3544 return PerlSIO_get_bufsiz(stdio);
9e353e3b
NIS
3545}
3546#endif
3547
3548#ifdef USE_STDIO_PTR
3549STDCHAR *
f62ce20a 3550PerlIOStdio_get_ptr(pTHX_ PerlIO *f)
9e353e3b 3551{
c4420975 3552 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
cc00df79 3553 return (STDCHAR*)PerlSIO_get_ptr(stdio);
9e353e3b
NIS
3554}
3555
3556SSize_t
f62ce20a 3557PerlIOStdio_get_cnt(pTHX_ PerlIO *f)
9e353e3b 3558{
c4420975 3559 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
14a5cf38 3560 return PerlSIO_get_cnt(stdio);
9e353e3b
NIS
3561}
3562
3563void
f62ce20a 3564PerlIOStdio_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
9e353e3b 3565{
c4420975 3566 FILE * const stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
14a5cf38 3567 if (ptr != NULL) {
9e353e3b 3568#ifdef STDIO_PTR_LVALUE
d06fc7d4 3569 PerlSIO_set_ptr(stdio, ptr); /* LHS STDCHAR* cast non-portable */
9e353e3b 3570#ifdef STDIO_PTR_LVAL_SETS_CNT
f8a4dbc5 3571 assert(PerlSIO_get_cnt(stdio) == (cnt));
9e353e3b
NIS
3572#endif
3573#if (!defined(STDIO_PTR_LVAL_NOCHANGE_CNT))
14a5cf38 3574 /*
71200d45 3575 * Setting ptr _does_ change cnt - we are done
14a5cf38
JH
3576 */
3577 return;
9e353e3b 3578#endif
22569500 3579#else /* STDIO_PTR_LVALUE */
14a5cf38 3580 PerlProc_abort();
22569500 3581#endif /* STDIO_PTR_LVALUE */
14a5cf38
JH
3582 }
3583 /*
71200d45 3584 * Now (or only) set cnt
14a5cf38 3585 */
9e353e3b 3586#ifdef STDIO_CNT_LVALUE
14a5cf38 3587 PerlSIO_set_cnt(stdio, cnt);
22569500 3588#else /* STDIO_CNT_LVALUE */
9e353e3b 3589#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
14a5cf38
JH
3590 PerlSIO_set_ptr(stdio,
3591 PerlSIO_get_ptr(stdio) + (PerlSIO_get_cnt(stdio) -
3592 cnt));
22569500 3593#else /* STDIO_PTR_LVAL_SETS_CNT */
14a5cf38 3594 PerlProc_abort();
22569500
NIS
3595#endif /* STDIO_PTR_LVAL_SETS_CNT */
3596#endif /* STDIO_CNT_LVALUE */
9e353e3b
NIS
3597}
3598
93679785 3599
9e353e3b
NIS
3600#endif
3601
93679785
NIS
3602IV
3603PerlIOStdio_fill(pTHX_ PerlIO *f)
3604{
abf9167d 3605 FILE * stdio;
93679785 3606 int c;
96a5add6 3607 PERL_UNUSED_CONTEXT;
abf9167d
DM
3608 if (PerlIO_lockcnt(f)) /* in use: abort ungracefully */
3609 return -1;
3610 stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
96a5add6 3611
93679785
NIS
3612 /*
3613 * fflush()ing read-only streams can cause trouble on some stdio-s
3614 */
3615 if ((PerlIOBase(f)->flags & PERLIO_F_CANWRITE)) {
3616 if (PerlSIO_fflush(stdio) != 0)
3617 return EOF;
3618 }
f3be3723
BL
3619 for (;;) {
3620 c = PerlSIO_fgetc(stdio);
3621 if (c != EOF)
3622 break;
3623 if (! PerlSIO_ferror(stdio) || errno != EINTR)
3624 return EOF;
abf9167d
DM
3625 if (PL_sig_pending && S_perlio_async_run(aTHX_ f))
3626 return -1;
f3be3723
BL
3627 SETERRNO(0,0);
3628 }
93679785
NIS
3629
3630#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
313e59c8
NIS
3631
3632#ifdef STDIO_BUFFER_WRITABLE
9f7cd136 3633 if (PerlIO_fast_gets(f) && PerlIO_has_base(f)) {
93679785
NIS
3634 /* Fake ungetc() to the real buffer in case system's ungetc
3635 goes elsewhere
3636 */
3637 STDCHAR *base = (STDCHAR*)PerlSIO_get_base(stdio);
3638 SSize_t cnt = PerlSIO_get_cnt(stdio);
3639 STDCHAR *ptr = (STDCHAR*)PerlSIO_get_ptr(stdio);
3640 if (ptr == base+1) {
3641 *--ptr = (STDCHAR) c;
3642 PerlIOStdio_set_ptrcnt(aTHX_ f,ptr,cnt+1);
3643 if (PerlSIO_feof(stdio))
3644 PerlSIO_clearerr(stdio);
3645 return 0;
3646 }
3647 }
313e59c8
NIS
3648 else
3649#endif
3650 if (PerlIO_has_cntptr(f)) {
9f7cd136
NIS
3651 STDCHAR ch = c;
3652 if (PerlIOStdio_unread(aTHX_ f,&ch,1) == 1) {
3653 return 0;
3654 }
3655 }
93679785
NIS
3656#endif
3657
3658#if defined(VMS)
3659 /* An ungetc()d char is handled separately from the regular
3660 * buffer, so we stuff it in the buffer ourselves.
3661 * Should never get called as should hit code above
3662 */
bad9695d
NIS
3663 *(--((*stdio)->_ptr)) = (unsigned char) c;
3664 (*stdio)->_cnt++;
93679785
NIS
3665#else
3666 /* If buffer snoop scheme above fails fall back to
9f7cd136 3667 using ungetc().
93679785
NIS
3668 */
3669 if (PerlSIO_ungetc(c, stdio) != c)
3670 return EOF;
3671#endif
3672 return 0;
3673}
3674
3675
3676
27da23d5 3677PERLIO_FUNCS_DECL(PerlIO_stdio) = {
2dc2558e 3678 sizeof(PerlIO_funcs),
14a5cf38
JH
3679 "stdio",
3680 sizeof(PerlIOStdio),
86e05cf2 3681 PERLIO_K_BUFFERED|PERLIO_K_RAW,
1fd8f4ce 3682 PerlIOStdio_pushed,
2376d97d 3683 PerlIOBase_popped,
14a5cf38 3684 PerlIOStdio_open,
86e05cf2 3685 PerlIOBase_binmode, /* binmode */
14a5cf38
JH
3686 NULL,
3687 PerlIOStdio_fileno,
71200d45 3688 PerlIOStdio_dup,
14a5cf38
JH
3689 PerlIOStdio_read,
3690 PerlIOStdio_unread,
3691 PerlIOStdio_write,
3692 PerlIOStdio_seek,
3693 PerlIOStdio_tell,
3694 PerlIOStdio_close,
3695 PerlIOStdio_flush,
3696 PerlIOStdio_fill,
3697 PerlIOStdio_eof,
3698 PerlIOStdio_error,
3699 PerlIOStdio_clearerr,
3700 PerlIOStdio_setlinebuf,
9e353e3b 3701#ifdef FILE_base
14a5cf38
JH
3702 PerlIOStdio_get_base,
3703 PerlIOStdio_get_bufsiz,
9e353e3b 3704#else
14a5cf38
JH
3705 NULL,
3706 NULL,
9e353e3b
NIS
3707#endif
3708#ifdef USE_STDIO_PTR
14a5cf38
JH
3709 PerlIOStdio_get_ptr,
3710 PerlIOStdio_get_cnt,
15b61c98 3711# if defined(HAS_FAST_STDIO) && defined(USE_FAST_STDIO)
79ed0f43 3712 PerlIOStdio_set_ptrcnt,
15b61c98
JH
3713# else
3714 NULL,
3715# endif /* HAS_FAST_STDIO && USE_FAST_STDIO */
3716#else
3717 NULL,
14a5cf38
JH
3718 NULL,
3719 NULL,
15b61c98 3720#endif /* USE_STDIO_PTR */
9e353e3b
NIS
3721};
3722
b9d6bf13
JH
3723/* Note that calls to PerlIO_exportFILE() are reversed using
3724 * PerlIO_releaseFILE(), not importFILE. */
9e353e3b 3725FILE *
81428673 3726PerlIO_exportFILE(PerlIO * f, const char *mode)
9e353e3b 3727{
e87a358a 3728 dTHX;
81428673
NIS
3729 FILE *stdio = NULL;
3730 if (PerlIOValid(f)) {
3731 char buf[8];
3732 PerlIO_flush(f);
3733 if (!mode || !*mode) {
3734 mode = PerlIO_modestr(f, buf);
3735 }
3736 stdio = PerlSIO_fdopen(PerlIO_fileno(f), mode);
3737 if (stdio) {
3738 PerlIOl *l = *f;
9f75cc58 3739 PerlIO *f2;
81428673
NIS
3740 /* De-link any lower layers so new :stdio sticks */
3741 *f = NULL;
a0714e2c 3742 if ((f2 = PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_stdio), buf, NULL))) {
9f75cc58 3743 PerlIOStdio *s = PerlIOSelf((f = f2), PerlIOStdio);
81428673 3744 s->stdio = stdio;
6b54a403 3745 PerlIOUnix_refcnt_inc(fileno(stdio));
81428673
NIS
3746 /* Link previous lower layers under new one */
3747 *PerlIONext(f) = l;
3748 }
3749 else {
3750 /* restore layers list */
3751 *f = l;
3752 }
a33cf58c 3753 }
14a5cf38
JH
3754 }
3755 return stdio;
9e353e3b
NIS
3756}
3757
81428673 3758
9e353e3b
NIS
3759FILE *
3760PerlIO_findFILE(PerlIO *f)
3761{
14a5cf38 3762 PerlIOl *l = *f;
bbbc33d0 3763 FILE *stdio;
14a5cf38
JH
3764 while (l) {
3765 if (l->tab == &PerlIO_stdio) {
3766 PerlIOStdio *s = PerlIOSelf(&l, PerlIOStdio);
3767 return s->stdio;
3768 }
3769 l = *PerlIONext(&l);
f7e7eb72 3770 }
4b069b44 3771 /* Uses fallback "mode" via PerlIO_modestr() in PerlIO_exportFILE */
bbbc33d0
NC
3772 /* However, we're not really exporting a FILE * to someone else (who
3773 becomes responsible for closing it, or calling PerlIO_releaseFILE())
486ec47a 3774 So we need to undo its reference count increase on the underlying file
bbbc33d0
NC
3775 descriptor. We have to do this, because if the loop above returns you
3776 the FILE *, then *it* didn't increase any reference count. So there's
3777 only one way to be consistent. */
3778 stdio = PerlIO_exportFILE(f, NULL);
3779 if (stdio) {
3780 const int fd = fileno(stdio);
3781 if (fd >= 0)
3782 PerlIOUnix_refcnt_dec(fd);
3783 }
3784 return stdio;
9e353e3b
NIS
3785}
3786
b9d6bf13 3787/* Use this to reverse PerlIO_exportFILE calls. */
9e353e3b
NIS
3788void
3789PerlIO_releaseFILE(PerlIO *p, FILE *f)
3790{
27da23d5 3791 dVAR;
22569500
NIS
3792 PerlIOl *l;
3793 while ((l = *p)) {
3794 if (l->tab == &PerlIO_stdio) {
3795 PerlIOStdio *s = PerlIOSelf(&l, PerlIOStdio);
3796 if (s->stdio == f) {
3797 dTHX;
6b54a403
NC
3798 const int fd = fileno(f);
3799 if (fd >= 0)
3800 PerlIOUnix_refcnt_dec(fd);
22569500
NIS
3801 PerlIO_pop(aTHX_ p);
3802 return;
3803 }
3804 }
3805 p = PerlIONext(p);
3806 }
3807 return;
9e353e3b
NIS
3808}
3809
3810/*--------------------------------------------------------------------------------------*/
14a5cf38 3811/*
71200d45 3812 * perlio buffer layer
14a5cf38 3813 */
9e353e3b 3814
5e2ab84b 3815IV
2dc2558e 3816PerlIOBuf_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
5e2ab84b 3817{
14a5cf38 3818 PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
de009b76 3819 const int fd = PerlIO_fileno(f);
14a5cf38
JH
3820 if (fd >= 0 && PerlLIO_isatty(fd)) {
3821 PerlIOBase(f)->flags |= PERLIO_F_LINEBUF | PERLIO_F_TTY;
3822 }
4b069b44 3823 if (*PerlIONext(f)) {
de009b76 3824 const Off_t posn = PerlIO_tell(PerlIONext(f));
4b069b44
NIS
3825 if (posn != (Off_t) - 1) {
3826 b->posn = posn;
3827 }
14a5cf38 3828 }
2dc2558e 3829 return PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
5e2ab84b
NIS
3830}
3831
9e353e3b 3832PerlIO *
14a5cf38
JH
3833PerlIOBuf_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
3834 IV n, const char *mode, int fd, int imode, int perm,
3835 PerlIO *f, int narg, SV **args)
3836{
04892f78 3837 if (PerlIOValid(f)) {
14a5cf38 3838 PerlIO *next = PerlIONext(f);
67363c0d
JH
3839 PerlIO_funcs *tab =
3840 PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIOBase(next)->tab);
3841 if (tab && tab->Open)
3842 next =
3843 (*tab->Open)(aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
3844 next, narg, args);
2dc2558e 3845 if (!next || (*PerlIOBase(f)->tab->Pushed) (aTHX_ f, mode, PerlIOArg, self) != 0) {
14a5cf38
JH
3846 return NULL;
3847 }
3848 }
3849 else {
04892f78 3850 PerlIO_funcs *tab = PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIO_default_btm());
14a5cf38 3851 int init = 0;
3b6c1aba 3852 if (*mode == IoTYPE_IMPLICIT) {
14a5cf38
JH
3853 init = 1;
3854 /*
71200d45 3855 * mode++;
14a5cf38
JH
3856 */
3857 }
67363c0d
JH
3858 if (tab && tab->Open)
3859 f = (*tab->Open)(aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
3860 f, narg, args);
3861 else
3862 SETERRNO(EINVAL, LIB_INVARG);
14a5cf38 3863 if (f) {
22569500 3864 if (PerlIO_push(aTHX_ f, self, mode, PerlIOArg) == 0) {
b26b1ab5
NC
3865 /*
3866 * if push fails during open, open fails. close will pop us.
3867 */
3868 PerlIO_close (f);
3869 return NULL;
3870 } else {
3871 fd = PerlIO_fileno(f);
b26b1ab5
NC
3872 if (init && fd == 2) {
3873 /*
3874 * Initial stderr is unbuffered
3875 */
3876 PerlIOBase(f)->flags |= PERLIO_F_UNBUF;
3877 }
23b84778
IZ
3878#ifdef PERLIO_USING_CRLF
3879# ifdef PERLIO_IS_BINMODE_FD
3880 if (PERLIO_IS_BINMODE_FD(fd))
bd61b366 3881 PerlIO_binmode(aTHX_ f, '<'/*not used*/, O_BINARY, NULL);
23b84778
IZ
3882 else
3883# endif
3884 /*
3885 * do something about failing setmode()? --jhi
3886 */
3887 PerlLIO_setmode(fd, O_BINARY);
3888#endif
8c8488cd 3889#ifdef VMS
8c8488cd
CB
3890 /* Enable line buffering with record-oriented regular files
3891 * so we don't introduce an extraneous record boundary when
3892 * the buffer fills up.
3893 */
3894 if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) {
3895 Stat_t st;
3896 if (PerlLIO_fstat(fd, &st) == 0
3897 && S_ISREG(st.st_mode)
3898 && (st.st_fab_rfm == FAB$C_VAR
3899 || st.st_fab_rfm == FAB$C_VFC)) {
3900 PerlIOBase(f)->flags |= PERLIO_F_LINEBUF;
3901 }
3902 }
3903#endif
14a5cf38
JH
3904 }
3905 }
ee518936 3906 }
14a5cf38 3907 return f;
9e353e3b
NIS
3908}
3909
14a5cf38
JH
3910/*
3911 * This "flush" is akin to sfio's sync in that it handles files in either
93c2c2ec
IZ
3912 * read or write state. For write state, we put the postponed data through
3913 * the next layers. For read state, we seek() the next layers to the
3914 * offset given by current position in the buffer, and discard the buffer
3915 * state (XXXX supposed to be for seek()able buffers only, but now it is done
3916 * in any case?). Then the pass the stick further in chain.
14a5cf38 3917 */
9e353e3b 3918IV
f62ce20a 3919PerlIOBuf_flush(pTHX_ PerlIO *f)
6f9d8c32 3920{
dcda55fc 3921 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38 3922 int code = 0;
04892f78 3923 PerlIO *n = PerlIONext(f);
14a5cf38
JH
3924 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF) {
3925 /*
71200d45 3926 * write() the buffer
14a5cf38 3927 */
de009b76
AL
3928 const STDCHAR *buf = b->buf;
3929 const STDCHAR *p = buf;
14a5cf38
JH
3930 while (p < b->ptr) {
3931 SSize_t count = PerlIO_write(n, p, b->ptr - p);
3932 if (count > 0) {
3933 p += count;
3934 }
3935 else if (count < 0 || PerlIO_error(n)) {
3936 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
3937 code = -1;
3938 break;
3939 }
3940 }
3941 b->posn += (p - buf);
3942 }
3943 else if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
3944 STDCHAR *buf = PerlIO_get_base(f);
3945 /*
71200d45 3946 * Note position change
14a5cf38
JH
3947 */
3948 b->posn += (b->ptr - buf);
3949 if (b->ptr < b->end) {
4b069b44
NIS
3950 /* We did not consume all of it - try and seek downstream to
3951 our logical position
14a5cf38 3952 */
4b069b44 3953 if (PerlIOValid(n) && PerlIO_seek(n, b->posn, SEEK_SET) == 0) {
04892f78
NIS
3954 /* Reload n as some layers may pop themselves on seek */
3955 b->posn = PerlIO_tell(n = PerlIONext(f));
14a5cf38 3956 }
ba5c3fe9 3957 else {
4b069b44
NIS
3958 /* Seek failed (e.g. pipe or tty). Do NOT clear buffer or pre-read
3959 data is lost for good - so return saying "ok" having undone
3960 the position adjust
3961 */
3962 b->posn -= (b->ptr - buf);
ba5c3fe9
NIS
3963 return code;
3964 }
14a5cf38
JH
3965 }
3966 }
3967 b->ptr = b->end = b->buf;
3968 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
04892f78 3969 /* We check for Valid because of dubious decision to make PerlIO_flush(NULL) flush all */
04892f78 3970 if (PerlIOValid(n) && PerlIO_flush(n) != 0)
14a5cf38
JH
3971 code = -1;
3972 return code;
6f9d8c32
NIS
3973}
3974
93c2c2ec
IZ
3975/* This discards the content of the buffer after b->ptr, and rereads
3976 * the buffer from the position off in the layer downstream; here off
3977 * is at offset corresponding to b->ptr - b->buf.
3978 */
06da4f11 3979IV
f62ce20a 3980PerlIOBuf_fill(pTHX_ PerlIO *f)
06da4f11 3981{
dcda55fc 3982 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
3983 PerlIO *n = PerlIONext(f);
3984 SSize_t avail;
3985 /*
4b069b44
NIS
3986 * Down-stream flush is defined not to loose read data so is harmless.
3987 * we would not normally be fill'ing if there was data left in anycase.
14a5cf38 3988 */
93c2c2ec 3989 if (PerlIO_flush(f) != 0) /* XXXX Check that its seek() succeeded?! */
14a5cf38
JH
3990 return -1;
3991 if (PerlIOBase(f)->flags & PERLIO_F_TTY)
f62ce20a 3992 PerlIOBase_flush_linebuf(aTHX);
14a5cf38
JH
3993
3994 if (!b->buf)
22569500 3995 PerlIO_get_base(f); /* allocate via vtable */
14a5cf38 3996
0f0eef27 3997 assert(b->buf); /* The b->buf does get allocated via the vtable system. */
ec6fa4f0 3998
14a5cf38 3999 b->ptr = b->end = b->buf;
4b069b44
NIS
4000
4001 if (!PerlIOValid(n)) {
4002 PerlIOBase(f)->flags |= PERLIO_F_EOF;
4003 return -1;
4004 }
4005
14a5cf38
JH
4006 if (PerlIO_fast_gets(n)) {
4007 /*
04892f78 4008 * Layer below is also buffered. We do _NOT_ want to call its
14a5cf38
JH
4009 * ->Read() because that will loop till it gets what we asked for
4010 * which may hang on a pipe etc. Instead take anything it has to
71200d45 4011 * hand, or ask it to fill _once_.
14a5cf38
JH
4012 */
4013 avail = PerlIO_get_cnt(n);
4014 if (avail <= 0) {
4015 avail = PerlIO_fill(n);
4016 if (avail == 0)
4017 avail = PerlIO_get_cnt(n);
4018 else {
4019 if (!PerlIO_error(n) && PerlIO_eof(n))
4020 avail = 0;
4021 }
4022 }
4023 if (avail > 0) {
4024 STDCHAR *ptr = PerlIO_get_ptr(n);
dcda55fc 4025 const SSize_t cnt = avail;
eb160463 4026 if (avail > (SSize_t)b->bufsiz)
14a5cf38
JH
4027 avail = b->bufsiz;
4028 Copy(ptr, b->buf, avail, STDCHAR);
4029 PerlIO_set_ptrcnt(n, ptr + avail, cnt - avail);
4030 }
4031 }
4032 else {
4033 avail = PerlIO_read(n, b->ptr, b->bufsiz);
4034 }
4035 if (avail <= 0) {
4036 if (avail == 0)
4037 PerlIOBase(f)->flags |= PERLIO_F_EOF;
4038 else
4039 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
4040 return -1;
4041 }
4042 b->end = b->buf + avail;
4043 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
4044 return 0;
06da4f11
NIS
4045}
4046
6f9d8c32 4047SSize_t
f62ce20a 4048PerlIOBuf_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 4049{
04892f78 4050 if (PerlIOValid(f)) {
dcda55fc 4051 const PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4052 if (!b->ptr)
4053 PerlIO_get_base(f);
f62ce20a 4054 return PerlIOBase_read(aTHX_ f, vbuf, count);
14a5cf38
JH
4055 }
4056 return 0;
6f9d8c32
NIS
4057}
4058
9e353e3b 4059SSize_t
f62ce20a 4060PerlIOBuf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
760ac839 4061{
14a5cf38 4062 const STDCHAR *buf = (const STDCHAR *) vbuf + count;
dcda55fc 4063 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4064 SSize_t unread = 0;
4065 SSize_t avail;
4066 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
4067 PerlIO_flush(f);
4068 if (!b->buf)
4069 PerlIO_get_base(f);
4070 if (b->buf) {
4071 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
4072 /*
4073 * Buffer is already a read buffer, we can overwrite any chars
71200d45 4074 * which have been read back to buffer start
14a5cf38
JH
4075 */
4076 avail = (b->ptr - b->buf);
4077 }
4078 else {
4079 /*
4080 * Buffer is idle, set it up so whole buffer is available for
71200d45 4081 * unread
14a5cf38
JH
4082 */
4083 avail = b->bufsiz;
4084 b->end = b->buf + avail;
4085 b->ptr = b->end;
4086 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
4087 /*
71200d45 4088 * Buffer extends _back_ from where we are now
14a5cf38
JH
4089 */
4090 b->posn -= b->bufsiz;
4091 }
4092 if (avail > (SSize_t) count) {
4093 /*
71200d45 4094 * If we have space for more than count, just move count
14a5cf38
JH
4095 */
4096 avail = count;
4097 }
4098 if (avail > 0) {
4099 b->ptr -= avail;
4100 buf -= avail;
4101 /*
4102 * In simple stdio-like ungetc() case chars will be already
71200d45 4103 * there
14a5cf38
JH
4104 */
4105 if (buf != b->ptr) {
4106 Copy(buf, b->ptr, avail, STDCHAR);
4107 }
4108 count -= avail;
4109 unread += avail;
4110 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
4111 }
4112 }
93679785
NIS
4113 if (count > 0) {
4114 unread += PerlIOBase_unread(aTHX_ f, vbuf, count);
4115 }
14a5cf38 4116 return unread;
760ac839
LW
4117}
4118
9e353e3b 4119SSize_t
f62ce20a 4120PerlIOBuf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
760ac839 4121{
de009b76 4122 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38 4123 const STDCHAR *buf = (const STDCHAR *) vbuf;
ee56a6b9 4124 const STDCHAR *flushptr = buf;
14a5cf38
JH
4125 Size_t written = 0;
4126 if (!b->buf)
4127 PerlIO_get_base(f);
4128 if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
4129 return 0;
0678cb22
NIS
4130 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
4131 if (PerlIO_flush(f) != 0) {
4132 return 0;
4133 }
4134 }
ee56a6b9
CS
4135 if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
4136 flushptr = buf + count;
4137 while (flushptr > buf && *(flushptr - 1) != '\n')
4138 --flushptr;
4139 }
14a5cf38
JH
4140 while (count > 0) {
4141 SSize_t avail = b->bufsiz - (b->ptr - b->buf);
4142 if ((SSize_t) count < avail)
4143 avail = count;
ee56a6b9
CS
4144 if (flushptr > buf && flushptr <= buf + avail)
4145 avail = flushptr - buf;
14a5cf38 4146 PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
ee56a6b9
CS
4147 if (avail) {
4148 Copy(buf, b->ptr, avail, STDCHAR);
4149 count -= avail;
4150 buf += avail;
4151 written += avail;
4152 b->ptr += avail;
4153 if (buf == flushptr)
4154 PerlIO_flush(f);
14a5cf38
JH
4155 }
4156 if (b->ptr >= (b->buf + b->bufsiz))
abf9167d
DM
4157 if (PerlIO_flush(f) == -1)
4158 return -1;
14a5cf38
JH
4159 }
4160 if (PerlIOBase(f)->flags & PERLIO_F_UNBUF)
4161 PerlIO_flush(f);
4162 return written;
9e353e3b
NIS
4163}
4164
94a175e1 4165IV
f62ce20a 4166PerlIOBuf_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
9e353e3b 4167{
14a5cf38
JH
4168 IV code;
4169 if ((code = PerlIO_flush(f)) == 0) {
14a5cf38
JH
4170 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
4171 code = PerlIO_seek(PerlIONext(f), offset, whence);
4172 if (code == 0) {
de009b76 4173 PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4174 b->posn = PerlIO_tell(PerlIONext(f));
4175 }
9e353e3b 4176 }
14a5cf38 4177 return code;
9e353e3b
NIS
4178}
4179
4180Off_t
f62ce20a 4181PerlIOBuf_tell(pTHX_ PerlIO *f)
9e353e3b 4182{
dcda55fc 4183 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38 4184 /*
71200d45 4185 * b->posn is file position where b->buf was read, or will be written
14a5cf38
JH
4186 */
4187 Off_t posn = b->posn;
37725cdc 4188 if ((PerlIOBase(f)->flags & PERLIO_F_APPEND) &&
0678cb22
NIS
4189 (PerlIOBase(f)->flags & PERLIO_F_WRBUF)) {
4190#if 1
4191 /* As O_APPEND files are normally shared in some sense it is better
4192 to flush :
4193 */
4194 PerlIO_flush(f);
4195#else
37725cdc 4196 /* when file is NOT shared then this is sufficient */
0678cb22
NIS
4197 PerlIO_seek(PerlIONext(f),0, SEEK_END);
4198#endif
4199 posn = b->posn = PerlIO_tell(PerlIONext(f));
4200 }
14a5cf38
JH
4201 if (b->buf) {
4202 /*
71200d45 4203 * If buffer is valid adjust position by amount in buffer
14a5cf38
JH
4204 */
4205 posn += (b->ptr - b->buf);
4206 }
4207 return posn;
9e353e3b
NIS
4208}
4209
4210IV
44798d05
NIS
4211PerlIOBuf_popped(pTHX_ PerlIO *f)
4212{
de009b76
AL
4213 const IV code = PerlIOBase_popped(aTHX_ f);
4214 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
44798d05
NIS
4215 if (b->buf && b->buf != (STDCHAR *) & b->oneword) {
4216 Safefree(b->buf);
4217 }
dcda55fc 4218 b->ptr = b->end = b->buf = NULL;
44798d05
NIS
4219 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
4220 return code;
4221}
4222
4223IV
f62ce20a 4224PerlIOBuf_close(pTHX_ PerlIO *f)
9e353e3b 4225{
de009b76
AL
4226 const IV code = PerlIOBase_close(aTHX_ f);
4227 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38 4228 if (b->buf && b->buf != (STDCHAR *) & b->oneword) {
3a1ee7e8 4229 Safefree(b->buf);
14a5cf38 4230 }
dcda55fc 4231 b->ptr = b->end = b->buf = NULL;
14a5cf38
JH
4232 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
4233 return code;
760ac839
LW
4234}
4235
9e353e3b 4236STDCHAR *
f62ce20a 4237PerlIOBuf_get_ptr(pTHX_ PerlIO *f)
9e353e3b 4238{
dcda55fc 4239 const PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4240 if (!b->buf)
4241 PerlIO_get_base(f);
4242 return b->ptr;
9e353e3b
NIS
4243}
4244
05d1247b 4245SSize_t
f62ce20a 4246PerlIOBuf_get_cnt(pTHX_ PerlIO *f)
9e353e3b 4247{
dcda55fc 4248 const PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4249 if (!b->buf)
4250 PerlIO_get_base(f);
4251 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
4252 return (b->end - b->ptr);
4253 return 0;
9e353e3b
NIS
4254}
4255
4256STDCHAR *
f62ce20a 4257PerlIOBuf_get_base(pTHX_ PerlIO *f)
9e353e3b 4258{
dcda55fc 4259 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
96a5add6
AL
4260 PERL_UNUSED_CONTEXT;
4261
14a5cf38
JH
4262 if (!b->buf) {
4263 if (!b->bufsiz)
1810cd7c 4264 b->bufsiz = PERLIOBUF_DEFAULT_BUFSIZ;
e05a0d74 4265 Newxz(b->buf,b->bufsiz, STDCHAR);
14a5cf38
JH
4266 if (!b->buf) {
4267 b->buf = (STDCHAR *) & b->oneword;
4268 b->bufsiz = sizeof(b->oneword);
4269 }
dcda55fc 4270 b->end = b->ptr = b->buf;
06da4f11 4271 }
14a5cf38 4272 return b->buf;
9e353e3b
NIS
4273}
4274
4275Size_t
f62ce20a 4276PerlIOBuf_bufsiz(pTHX_ PerlIO *f)
9e353e3b 4277{
dcda55fc 4278 const PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4279 if (!b->buf)
4280 PerlIO_get_base(f);
4281 return (b->end - b->buf);
9e353e3b
NIS
4282}
4283
4284void
f62ce20a 4285PerlIOBuf_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
9e353e3b 4286{
dcda55fc 4287 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
babfacb9
JH
4288#ifndef DEBUGGING
4289 PERL_UNUSED_ARG(cnt);
4290#endif
14a5cf38
JH
4291 if (!b->buf)
4292 PerlIO_get_base(f);
4293 b->ptr = ptr;
b727803b
RGS
4294 assert(PerlIO_get_cnt(f) == cnt);
4295 assert(b->ptr >= b->buf);
14a5cf38 4296 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
760ac839
LW
4297}
4298
71200d45 4299PerlIO *
ecdeb87c 4300PerlIOBuf_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
71200d45 4301{
ecdeb87c 4302 return PerlIOBase_dup(aTHX_ f, o, param, flags);
71200d45
NIS
4303}
4304
4305
4306
27da23d5 4307PERLIO_FUNCS_DECL(PerlIO_perlio) = {
2dc2558e 4308 sizeof(PerlIO_funcs),
14a5cf38
JH
4309 "perlio",
4310 sizeof(PerlIOBuf),
86e05cf2 4311 PERLIO_K_BUFFERED|PERLIO_K_RAW,
14a5cf38 4312 PerlIOBuf_pushed,
44798d05 4313 PerlIOBuf_popped,
14a5cf38 4314 PerlIOBuf_open,
86e05cf2 4315 PerlIOBase_binmode, /* binmode */
14a5cf38
JH
4316 NULL,
4317 PerlIOBase_fileno,
71200d45 4318 PerlIOBuf_dup,
14a5cf38
JH
4319 PerlIOBuf_read,
4320 PerlIOBuf_unread,
4321 PerlIOBuf_write,
4322 PerlIOBuf_seek,
4323 PerlIOBuf_tell,
4324 PerlIOBuf_close,
4325 PerlIOBuf_flush,
4326 PerlIOBuf_fill,
4327 PerlIOBase_eof,
4328 PerlIOBase_error,
4329 PerlIOBase_clearerr,
4330 PerlIOBase_setlinebuf,
4331 PerlIOBuf_get_base,
4332 PerlIOBuf_bufsiz,
4333 PerlIOBuf_get_ptr,
4334 PerlIOBuf_get_cnt,
4335 PerlIOBuf_set_ptrcnt,
9e353e3b
NIS
4336};
4337
66ecd56b 4338/*--------------------------------------------------------------------------------------*/
14a5cf38 4339/*
71200d45 4340 * Temp layer to hold unread chars when cannot do it any other way
14a5cf38 4341 */
5e2ab84b
NIS
4342
4343IV
f62ce20a 4344PerlIOPending_fill(pTHX_ PerlIO *f)
5e2ab84b 4345{
14a5cf38 4346 /*
71200d45 4347 * Should never happen
14a5cf38
JH
4348 */
4349 PerlIO_flush(f);
4350 return 0;
5e2ab84b
NIS
4351}
4352
4353IV
f62ce20a 4354PerlIOPending_close(pTHX_ PerlIO *f)
5e2ab84b 4355{
14a5cf38 4356 /*
71200d45 4357 * A tad tricky - flush pops us, then we close new top
14a5cf38
JH
4358 */
4359 PerlIO_flush(f);
4360 return PerlIO_close(f);
5e2ab84b
NIS
4361}
4362
94a175e1 4363IV
f62ce20a 4364PerlIOPending_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
5e2ab84b 4365{
14a5cf38 4366 /*
71200d45 4367 * A tad tricky - flush pops us, then we seek new top
14a5cf38
JH
4368 */
4369 PerlIO_flush(f);
4370 return PerlIO_seek(f, offset, whence);
5e2ab84b
NIS
4371}
4372
4373
4374IV
f62ce20a 4375PerlIOPending_flush(pTHX_ PerlIO *f)
5e2ab84b 4376{
dcda55fc 4377 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38 4378 if (b->buf && b->buf != (STDCHAR *) & b->oneword) {
3a1ee7e8 4379 Safefree(b->buf);
14a5cf38
JH
4380 b->buf = NULL;
4381 }
4382 PerlIO_pop(aTHX_ f);
4383 return 0;
5e2ab84b
NIS
4384}
4385
4386void
f62ce20a 4387PerlIOPending_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
5e2ab84b 4388{
14a5cf38
JH
4389 if (cnt <= 0) {
4390 PerlIO_flush(f);
4391 }
4392 else {
f62ce20a 4393 PerlIOBuf_set_ptrcnt(aTHX_ f, ptr, cnt);
14a5cf38 4394 }
5e2ab84b
NIS
4395}
4396
4397IV
2dc2558e 4398PerlIOPending_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
5e2ab84b 4399{
de009b76 4400 const IV code = PerlIOBase_pushed(aTHX_ f, mode, arg, tab);
dcda55fc 4401 PerlIOl * const l = PerlIOBase(f);
14a5cf38 4402 /*
71200d45
NIS
4403 * Our PerlIO_fast_gets must match what we are pushed on, or sv_gets()
4404 * etc. get muddled when it changes mid-string when we auto-pop.
14a5cf38
JH
4405 */
4406 l->flags = (l->flags & ~(PERLIO_F_FASTGETS | PERLIO_F_UTF8)) |
4407 (PerlIOBase(PerlIONext(f))->
4408 flags & (PERLIO_F_FASTGETS | PERLIO_F_UTF8));
4409 return code;
5e2ab84b
NIS
4410}
4411
4412SSize_t
f62ce20a 4413PerlIOPending_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
5e2ab84b 4414{
14a5cf38
JH
4415 SSize_t avail = PerlIO_get_cnt(f);
4416 SSize_t got = 0;
eb160463 4417 if ((SSize_t)count < avail)
14a5cf38
JH
4418 avail = count;
4419 if (avail > 0)
f62ce20a 4420 got = PerlIOBuf_read(aTHX_ f, vbuf, avail);
eb160463 4421 if (got >= 0 && got < (SSize_t)count) {
de009b76 4422 const SSize_t more =
14a5cf38
JH
4423 PerlIO_read(f, ((STDCHAR *) vbuf) + got, count - got);
4424 if (more >= 0 || got == 0)
4425 got += more;
4426 }
4427 return got;
5e2ab84b
NIS
4428}
4429
27da23d5 4430PERLIO_FUNCS_DECL(PerlIO_pending) = {
2dc2558e 4431 sizeof(PerlIO_funcs),
14a5cf38
JH
4432 "pending",
4433 sizeof(PerlIOBuf),
86e05cf2 4434 PERLIO_K_BUFFERED|PERLIO_K_RAW, /* not sure about RAW here */
14a5cf38 4435 PerlIOPending_pushed,
44798d05 4436 PerlIOBuf_popped,
14a5cf38 4437 NULL,
86e05cf2 4438 PerlIOBase_binmode, /* binmode */
14a5cf38
JH
4439 NULL,
4440 PerlIOBase_fileno,
71200d45 4441 PerlIOBuf_dup,
14a5cf38
JH
4442 PerlIOPending_read,
4443 PerlIOBuf_unread,
4444 PerlIOBuf_write,
4445 PerlIOPending_seek,
4446 PerlIOBuf_tell,
4447 PerlIOPending_close,
4448 PerlIOPending_flush,
4449 PerlIOPending_fill,
4450 PerlIOBase_eof,
4451 PerlIOBase_error,
4452 PerlIOBase_clearerr,
4453 PerlIOBase_setlinebuf,
4454 PerlIOBuf_get_base,
4455 PerlIOBuf_bufsiz,
4456 PerlIOBuf_get_ptr,
4457 PerlIOBuf_get_cnt,
4458 PerlIOPending_set_ptrcnt,
5e2ab84b
NIS
4459};
4460
4461
4462
4463/*--------------------------------------------------------------------------------------*/
14a5cf38
JH
4464/*
4465 * crlf - translation On read translate CR,LF to "\n" we do this by
4466 * overriding ptr/cnt entries to hand back a line at a time and keeping a
71200d45 4467 * record of which nl we "lied" about. On write translate "\n" to CR,LF
93c2c2ec
IZ
4468 *
4469 * c->nl points on the first byte of CR LF pair when it is temporarily
4470 * replaced by LF, or to the last CR of the buffer. In the former case
4471 * the caller thinks that the buffer ends at c->nl + 1, in the latter
4472 * that it ends at c->nl; these two cases can be distinguished by
4473 * *c->nl. c->nl is set during _getcnt() call, and unset during
4474 * _unread() and _flush() calls.
4475 * It only matters for read operations.
66ecd56b
NIS
4476 */
4477
14a5cf38 4478typedef struct {
22569500
NIS
4479 PerlIOBuf base; /* PerlIOBuf stuff */
4480 STDCHAR *nl; /* Position of crlf we "lied" about in the
14a5cf38 4481 * buffer */
99efab12
NIS
4482} PerlIOCrlf;
4483
ff1e3883
JD
4484/* Inherit the PERLIO_F_UTF8 flag from previous layer.
4485 * Otherwise the :crlf layer would always revert back to
4486 * raw mode.
4487 */
4488static void
4489S_inherit_utf8_flag(PerlIO *f)
4490{
4491 PerlIO *g = PerlIONext(f);
4492 if (PerlIOValid(g)) {
4493 if (PerlIOBase(g)->flags & PERLIO_F_UTF8) {
4494 PerlIOBase(f)->flags |= PERLIO_F_UTF8;
4495 }
4496 }
4497}
4498
f5b9d040 4499IV
2dc2558e 4500PerlIOCrlf_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
f5b9d040 4501{
14a5cf38
JH
4502 IV code;
4503 PerlIOBase(f)->flags |= PERLIO_F_CRLF;
2dc2558e 4504 code = PerlIOBuf_pushed(aTHX_ f, mode, arg, tab);
5e2ab84b 4505#if 0
14a5cf38 4506 PerlIO_debug("PerlIOCrlf_pushed f=%p %s %s fl=%08" UVxf "\n",
6c9570dc 4507 (void*)f, PerlIOBase(f)->tab->name, (mode) ? mode : "(Null)",
14a5cf38 4508 PerlIOBase(f)->flags);
5e2ab84b 4509#endif
8229d19f 4510 {
5da08ab0
LT
4511 /* If the old top layer is a CRLF layer, reactivate it (if
4512 * necessary) and remove this new layer from the stack */
8229d19f 4513 PerlIO *g = PerlIONext(f);
7826b36f 4514 if (PerlIOValid(g)) {
8229d19f
JH
4515 PerlIOl *b = PerlIOBase(g);
4516 if (b && b->tab == &PerlIO_crlf) {
4517 if (!(b->flags & PERLIO_F_CRLF))
4518 b->flags |= PERLIO_F_CRLF;
ff1e3883 4519 S_inherit_utf8_flag(g);
8229d19f
JH
4520 PerlIO_pop(aTHX_ f);
4521 return code;
7826b36f 4522 }
8229d19f
JH
4523 }
4524 }
ff1e3883 4525 S_inherit_utf8_flag(f);
14a5cf38 4526 return code;
f5b9d040
NIS
4527}
4528
4529
99efab12 4530SSize_t
f62ce20a 4531PerlIOCrlf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
99efab12 4532{
dcda55fc 4533 PerlIOCrlf * const c = PerlIOSelf(f, PerlIOCrlf);
93c2c2ec 4534 if (c->nl) { /* XXXX Shouldn't it be done only if b->ptr > c->nl? */
14a5cf38
JH
4535 *(c->nl) = 0xd;
4536 c->nl = NULL;
4537 }
4538 if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF))
f62ce20a 4539 return PerlIOBuf_unread(aTHX_ f, vbuf, count);
14a5cf38
JH
4540 else {
4541 const STDCHAR *buf = (const STDCHAR *) vbuf + count;
4542 PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
4543 SSize_t unread = 0;
4544 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
4545 PerlIO_flush(f);
4546 if (!b->buf)
4547 PerlIO_get_base(f);
4548 if (b->buf) {
4549 if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF)) {
4550 b->end = b->ptr = b->buf + b->bufsiz;
4551 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
4552 b->posn -= b->bufsiz;
4553 }
4554 while (count > 0 && b->ptr > b->buf) {
dcda55fc 4555 const int ch = *--buf;
14a5cf38
JH
4556 if (ch == '\n') {
4557 if (b->ptr - 2 >= b->buf) {
4558 *--(b->ptr) = 0xa;
4559 *--(b->ptr) = 0xd;
4560 unread++;
4561 count--;
4562 }
4563 else {
93c2c2ec
IZ
4564 /* If b->ptr - 1 == b->buf, we are undoing reading 0xa */
4565 *--(b->ptr) = 0xa; /* Works even if 0xa == '\r' */
4566 unread++;
4567 count--;
14a5cf38
JH
4568 }
4569 }
4570 else {
4571 *--(b->ptr) = ch;
4572 unread++;
4573 count--;
4574 }
4575 }
4576 }
4577 return unread;
4578 }
99efab12
NIS
4579}
4580
93c2c2ec 4581/* XXXX This code assumes that buffer size >=2, but does not check it... */
99efab12 4582SSize_t
f62ce20a 4583PerlIOCrlf_get_cnt(pTHX_ PerlIO *f)
99efab12 4584{
dcda55fc 4585 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38
JH
4586 if (!b->buf)
4587 PerlIO_get_base(f);
4588 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
dcda55fc 4589 PerlIOCrlf * const c = PerlIOSelf(f, PerlIOCrlf);
23b3c6af
NIS
4590 if ((PerlIOBase(f)->flags & PERLIO_F_CRLF) && (!c->nl || *c->nl == 0xd)) {
4591 STDCHAR *nl = (c->nl) ? c->nl : b->ptr;
14a5cf38
JH
4592 scan:
4593 while (nl < b->end && *nl != 0xd)
4594 nl++;
4595 if (nl < b->end && *nl == 0xd) {
4596 test:
4597 if (nl + 1 < b->end) {
4598 if (nl[1] == 0xa) {
4599 *nl = '\n';
4600 c->nl = nl;
4601 }
4602 else {
4603 /*
71200d45 4604 * Not CR,LF but just CR
14a5cf38
JH
4605 */
4606 nl++;
4607 goto scan;
4608 }
4609 }
4610 else {
4611 /*
71200d45 4612 * Blast - found CR as last char in buffer
14a5cf38 4613 */
e87a358a 4614
14a5cf38
JH
4615 if (b->ptr < nl) {
4616 /*
4617 * They may not care, defer work as long as
71200d45 4618 * possible
14a5cf38 4619 */
a0d1d361 4620 c->nl = nl;
14a5cf38
JH
4621 return (nl - b->ptr);
4622 }
4623 else {
4624 int code;
22569500 4625 b->ptr++; /* say we have read it as far as
14a5cf38 4626 * flush() is concerned */
22569500 4627 b->buf++; /* Leave space in front of buffer */
e949e37c
NIS
4628 /* Note as we have moved buf up flush's
4629 posn += ptr-buf
4630 will naturally make posn point at CR
4631 */
22569500
NIS
4632 b->bufsiz--; /* Buffer is thus smaller */
4633 code = PerlIO_fill(f); /* Fetch some more */
4634 b->bufsiz++; /* Restore size for next time */
4635 b->buf--; /* Point at space */
4636 b->ptr = nl = b->buf; /* Which is what we hand
14a5cf38 4637 * off */
22569500 4638 *nl = 0xd; /* Fill in the CR */
14a5cf38 4639 if (code == 0)
22569500 4640 goto test; /* fill() call worked */
14a5cf38 4641 /*
71200d45 4642 * CR at EOF - just fall through
14a5cf38 4643 */
a0d1d361 4644 /* Should we clear EOF though ??? */
14a5cf38
JH
4645 }
4646 }
4647 }
4648 }
4649 return (((c->nl) ? (c->nl + 1) : b->end) - b->ptr);
4650 }
4651 return 0;
99efab12
NIS
4652}
4653
4654void
f62ce20a 4655PerlIOCrlf_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
14a5cf38 4656{
dcda55fc
AL
4657 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
4658 PerlIOCrlf * const c = PerlIOSelf(f, PerlIOCrlf);
14a5cf38
JH
4659 if (!b->buf)
4660 PerlIO_get_base(f);
4661 if (!ptr) {
a0d1d361 4662 if (c->nl) {
14a5cf38 4663 ptr = c->nl + 1;
22569500 4664 if (ptr == b->end && *c->nl == 0xd) {
486ec47a 4665 /* Deferred CR at end of buffer case - we lied about count */
22569500
NIS
4666 ptr--;
4667 }
4668 }
14a5cf38
JH
4669 else {
4670 ptr = b->end;
14a5cf38
JH
4671 }
4672 ptr -= cnt;
4673 }
4674 else {
6f207bd3 4675 NOOP;
3b4bd3fd 4676#if 0
14a5cf38 4677 /*
71200d45 4678 * Test code - delete when it works ...
14a5cf38 4679 */
3b4bd3fd 4680 IV flags = PerlIOBase(f)->flags;
ba7abf9d 4681 STDCHAR *chk = (c->nl) ? (c->nl+1) : b->end;
22569500 4682 if (ptr+cnt == c->nl && c->nl+1 == b->end && *c->nl == 0xd) {
486ec47a 4683 /* Deferred CR at end of buffer case - we lied about count */
a0d1d361 4684 chk--;
22569500 4685 }
14a5cf38
JH
4686 chk -= cnt;
4687
a0d1d361 4688 if (ptr != chk ) {
99ef548b 4689 Perl_croak(aTHX_ "ptr wrong %p != %p fl=%08" UVxf
6c9570dc
MHM
4690 " nl=%p e=%p for %d", (void*)ptr, (void*)chk,
4691 flags, c->nl, b->end, cnt);
14a5cf38 4692 }
99ef548b 4693#endif
14a5cf38
JH
4694 }
4695 if (c->nl) {
4696 if (ptr > c->nl) {
4697 /*
71200d45 4698 * They have taken what we lied about
14a5cf38
JH
4699 */
4700 *(c->nl) = 0xd;
4701 c->nl = NULL;
4702 ptr++;
4703 }
4704 }
4705 b->ptr = ptr;
4706 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
99efab12
NIS
4707}
4708
4709SSize_t
f62ce20a 4710PerlIOCrlf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
99efab12 4711{
14a5cf38 4712 if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF))
f62ce20a 4713 return PerlIOBuf_write(aTHX_ f, vbuf, count);
14a5cf38 4714 else {
dcda55fc 4715 PerlIOBuf * const b = PerlIOSelf(f, PerlIOBuf);
14a5cf38 4716 const STDCHAR *buf = (const STDCHAR *) vbuf;
dcda55fc 4717 const STDCHAR * const ebuf = buf + count;
14a5cf38
JH
4718 if (!b->buf)
4719 PerlIO_get_base(f);
4720 if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
4721 return 0;
4722 while (buf < ebuf) {
dcda55fc 4723 const STDCHAR * const eptr = b->buf + b->bufsiz;
14a5cf38
JH
4724 PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
4725 while (buf < ebuf && b->ptr < eptr) {
4726 if (*buf == '\n') {
4727 if ((b->ptr + 2) > eptr) {
4728 /*
71200d45 4729 * Not room for both
14a5cf38
JH
4730 */
4731 PerlIO_flush(f);
4732 break;
4733 }
4734 else {
22569500
NIS
4735 *(b->ptr)++ = 0xd; /* CR */
4736 *(b->ptr)++ = 0xa; /* LF */
14a5cf38
JH
4737 buf++;
4738 if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
4739 PerlIO_flush(f);
4740 break;
4741 }
4742 }
4743 }
4744 else {
dcda55fc 4745 *(b->ptr)++ = *buf++;
14a5cf38
JH
4746 }
4747 if (b->ptr >= eptr) {
4748 PerlIO_flush(f);
4749 break;
4750 }
4751 }
4752 }
4753 if (PerlIOBase(f)->flags & PERLIO_F_UNBUF)
4754 PerlIO_flush(f);
4755 return (buf - (STDCHAR *) vbuf);
4756 }
99efab12
NIS
4757}
4758
4759IV
f62ce20a 4760PerlIOCrlf_flush(pTHX_ PerlIO *f)
99efab12 4761{
dcda55fc 4762 PerlIOCrlf * const c = PerlIOSelf(f, PerlIOCrlf);
14a5cf38
JH
4763 if (c->nl) {
4764 *(c->nl) = 0xd;
4765 c->nl = NULL;
4766 }
f62ce20a 4767 return PerlIOBuf_flush(aTHX_ f);
99efab12
NIS
4768}
4769
86e05cf2
NIS
4770IV
4771PerlIOCrlf_binmode(pTHX_ PerlIO *f)
4772{
4773 if ((PerlIOBase(f)->flags & PERLIO_F_CRLF)) {
4774 /* In text mode - flush any pending stuff and flip it */
4775 PerlIOBase(f)->flags &= ~PERLIO_F_CRLF;
4776#ifndef PERLIO_USING_CRLF
4777 /* CRLF is unusual case - if this is just the :crlf layer pop it */
5fae6dc1 4778 PerlIO_pop(aTHX_ f);
86e05cf2
NIS
4779#endif
4780 }
4781 return 0;
4782}
4783
27da23d5 4784PERLIO_FUNCS_DECL(PerlIO_crlf) = {
2dc2558e 4785 sizeof(PerlIO_funcs),
14a5cf38
JH
4786 "crlf",
4787 sizeof(PerlIOCrlf),
86e05cf2 4788 PERLIO_K_BUFFERED | PERLIO_K_CANCRLF | PERLIO_K_RAW,
14a5cf38 4789 PerlIOCrlf_pushed,
44798d05 4790 PerlIOBuf_popped, /* popped */
14a5cf38 4791 PerlIOBuf_open,
86e05cf2 4792 PerlIOCrlf_binmode, /* binmode */
14a5cf38
JH
4793 NULL,
4794 PerlIOBase_fileno,
71200d45 4795 PerlIOBuf_dup,
de009b76 4796 PerlIOBuf_read, /* generic read works with ptr/cnt lies */
22569500
NIS
4797 PerlIOCrlf_unread, /* Put CR,LF in buffer for each '\n' */
4798 PerlIOCrlf_write, /* Put CR,LF in buffer for each '\n' */
14a5cf38
JH
4799 PerlIOBuf_seek,
4800 PerlIOBuf_tell,
4801 PerlIOBuf_close,
4802 PerlIOCrlf_flush,
4803 PerlIOBuf_fill,
4804 PerlIOBase_eof,
4805 PerlIOBase_error,
4806 PerlIOBase_clearerr,
4807 PerlIOBase_setlinebuf,
4808 PerlIOBuf_get_base,
4809 PerlIOBuf_bufsiz,
4810 PerlIOBuf_get_ptr,
4811 PerlIOCrlf_get_cnt,
4812 PerlIOCrlf_set_ptrcnt,
66ecd56b
NIS
4813};
4814
9e353e3b 4815PerlIO *
e87a358a 4816Perl_PerlIO_stdin(pTHX)
9e353e3b 4817{
97aff369 4818 dVAR;
a1ea730d 4819 if (!PL_perlio) {
14a5cf38
JH
4820 PerlIO_stdstreams(aTHX);
4821 }
303f2dc3 4822 return (PerlIO*)&PL_perlio[1];
9e353e3b
NIS
4823}
4824
9e353e3b 4825PerlIO *
e87a358a 4826Perl_PerlIO_stdout(pTHX)
9e353e3b 4827{
97aff369 4828 dVAR;
a1ea730d 4829 if (!PL_perlio) {
14a5cf38
JH
4830 PerlIO_stdstreams(aTHX);
4831 }
303f2dc3 4832 return (PerlIO*)&PL_perlio[2];
9e353e3b
NIS
4833}
4834
9e353e3b 4835PerlIO *
e87a358a 4836Perl_PerlIO_stderr(pTHX)
9e353e3b 4837{
97aff369 4838 dVAR;
a1ea730d 4839 if (!PL_perlio) {
14a5cf38
JH
4840 PerlIO_stdstreams(aTHX);
4841 }
303f2dc3 4842 return (PerlIO*)&PL_perlio[3];
9e353e3b
NIS
4843}
4844
4845/*--------------------------------------------------------------------------------------*/
4846
9e353e3b
NIS
4847char *
4848PerlIO_getname(PerlIO *f, char *buf)
4849{
14a5cf38 4850 dTHX;
a15cef0c 4851#ifdef VMS
73d840c0 4852 char *name = NULL;
7659f319 4853 bool exported = FALSE;
14a5cf38 4854 FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
7659f319
CB
4855 if (!stdio) {
4856 stdio = PerlIO_exportFILE(f,0);
4857 exported = TRUE;
4858 }
4859 if (stdio) {
14a5cf38 4860 name = fgetname(stdio, buf);
7659f319
CB
4861 if (exported) PerlIO_releaseFILE(f,stdio);
4862 }
73d840c0 4863 return name;
a15cef0c 4864#else
8772537c
AL
4865 PERL_UNUSED_ARG(f);
4866 PERL_UNUSED_ARG(buf);
14a5cf38 4867 Perl_croak(aTHX_ "Don't know how to get file name");
bd61b366 4868 return NULL;
a15cef0c 4869#endif
9e353e3b
NIS
4870}
4871
4872
4873/*--------------------------------------------------------------------------------------*/
14a5cf38
JH
4874/*
4875 * Functions which can be called on any kind of PerlIO implemented in
71200d45 4876 * terms of above
14a5cf38 4877 */
9e353e3b 4878
e87a358a
NIS
4879#undef PerlIO_fdopen
4880PerlIO *
4881PerlIO_fdopen(int fd, const char *mode)
4882{
4883 dTHX;
bd61b366 4884 return PerlIO_openn(aTHX_ NULL, mode, fd, 0, 0, NULL, 0, NULL);
e87a358a
NIS
4885}
4886
4887#undef PerlIO_open
4888PerlIO *
4889PerlIO_open(const char *path, const char *mode)
4890{
4891 dTHX;
42d9b98d 4892 SV *name = sv_2mortal(newSVpv(path, 0));
bd61b366 4893 return PerlIO_openn(aTHX_ NULL, mode, -1, 0, 0, NULL, 1, &name);
e87a358a
NIS
4894}
4895
4896#undef Perlio_reopen
4897PerlIO *
4898PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
4899{
4900 dTHX;
42d9b98d 4901 SV *name = sv_2mortal(newSVpv(path,0));
bd61b366 4902 return PerlIO_openn(aTHX_ NULL, mode, -1, 0, 0, f, 1, &name);
e87a358a
NIS
4903}
4904
9e353e3b 4905#undef PerlIO_getc
6f9d8c32 4906int
9e353e3b 4907PerlIO_getc(PerlIO *f)
760ac839 4908{
e87a358a 4909 dTHX;
14a5cf38 4910 STDCHAR buf[1];
de009b76 4911 if ( 1 == PerlIO_read(f, buf, 1) ) {
14a5cf38
JH
4912 return (unsigned char) buf[0];
4913 }
4914 return EOF;
313ca112
NIS
4915}
4916
4917#undef PerlIO_ungetc
4918int
4919PerlIO_ungetc(PerlIO *f, int ch)
4920{
e87a358a 4921 dTHX;
14a5cf38
JH
4922 if (ch != EOF) {
4923 STDCHAR buf = ch;
4924 if (PerlIO_unread(f, &buf, 1) == 1)
4925 return ch;
4926 }
4927 return EOF;
760ac839
LW
4928}
4929
9e353e3b
NIS
4930#undef PerlIO_putc
4931int
4932PerlIO_putc(PerlIO *f, int ch)
760ac839 4933{
e87a358a 4934 dTHX;
14a5cf38
JH
4935 STDCHAR buf = ch;
4936 return PerlIO_write(f, &buf, 1);
760ac839
LW
4937}
4938
9e353e3b 4939#undef PerlIO_puts
760ac839 4940int
9e353e3b 4941PerlIO_puts(PerlIO *f, const char *s)
760ac839 4942{
e87a358a 4943 dTHX;
dcda55fc 4944 return PerlIO_write(f, s, strlen(s));
760ac839
LW
4945}
4946
4947#undef PerlIO_rewind
4948void
c78749f2 4949PerlIO_rewind(PerlIO *f)
760ac839 4950{
e87a358a 4951 dTHX;
14a5cf38
JH
4952 PerlIO_seek(f, (Off_t) 0, SEEK_SET);
4953 PerlIO_clearerr(f);
6f9d8c32
NIS
4954}
4955
4956#undef PerlIO_vprintf
4957int
4958PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
4959{
14a5cf38 4960 dTHX;
53ce71d3 4961 SV * sv;
b83604b4 4962 const char *s;
14a5cf38
JH
4963 STRLEN len;
4964 SSize_t wrote;
2cc61e15 4965#ifdef NEED_VA_COPY
14a5cf38
JH
4966 va_list apc;
4967 Perl_va_copy(ap, apc);
53ce71d3 4968 sv = vnewSVpvf(fmt, &apc);
2cc61e15 4969#else
53ce71d3 4970 sv = vnewSVpvf(fmt, &ap);
2cc61e15 4971#endif
b83604b4 4972 s = SvPV_const(sv, len);
14a5cf38
JH
4973 wrote = PerlIO_write(f, s, len);
4974 SvREFCNT_dec(sv);
4975 return wrote;
760ac839
LW
4976}
4977
4978#undef PerlIO_printf
6f9d8c32 4979int
14a5cf38 4980PerlIO_printf(PerlIO *f, const char *fmt, ...)
760ac839 4981{
14a5cf38
JH
4982 va_list ap;
4983 int result;
4984 va_start(ap, fmt);
4985 result = PerlIO_vprintf(f, fmt, ap);
4986 va_end(ap);
4987 return result;
760ac839
LW
4988}
4989
4990#undef PerlIO_stdoutf
6f9d8c32 4991int
14a5cf38 4992PerlIO_stdoutf(const char *fmt, ...)
760ac839 4993{
e87a358a 4994 dTHX;
14a5cf38
JH
4995 va_list ap;
4996 int result;
4997 va_start(ap, fmt);
4998 result = PerlIO_vprintf(PerlIO_stdout(), fmt, ap);
4999 va_end(ap);
5000 return result;
760ac839
LW
5001}
5002
5003#undef PerlIO_tmpfile
5004PerlIO *
c78749f2 5005PerlIO_tmpfile(void)
760ac839 5006{
2941a2e1
JH
5007 dTHX;
5008 PerlIO *f = NULL;
2941a2e1 5009#ifdef WIN32
de009b76 5010 const int fd = win32_tmpfd();
2941a2e1
JH
5011 if (fd >= 0)
5012 f = PerlIO_fdopen(fd, "w+b");
5013#else /* WIN32 */
460c8493 5014# if defined(HAS_MKSTEMP) && ! defined(VMS) && ! defined(OS2)
0b99e986
RGS
5015 int fd = -1;
5016 char tempname[] = "/tmp/PerlIO_XXXXXX";
5017 const char * const tmpdir = PL_tainting ? NULL : PerlEnv_getenv("TMPDIR");
525f6fe9 5018 SV * sv = NULL;
2941a2e1
JH
5019 /*
5020 * I have no idea how portable mkstemp() is ... NI-S
5021 */
7299ca58 5022 if (tmpdir && *tmpdir) {
0b99e986 5023 /* if TMPDIR is set and not empty, we try that first */
7299ca58 5024 sv = newSVpv(tmpdir, 0);
0b99e986
RGS
5025 sv_catpv(sv, tempname + 4);
5026 fd = mkstemp(SvPVX(sv));
5027 }
5028 if (fd < 0) {
7299ca58 5029 sv = NULL;
0b99e986
RGS
5030 /* else we try /tmp */
5031 fd = mkstemp(tempname);
5032 }
2941a2e1
JH
5033 if (fd >= 0) {
5034 f = PerlIO_fdopen(fd, "w+");
5035 if (f)
5036 PerlIOBase(f)->flags |= PERLIO_F_TEMP;
0b99e986 5037 PerlLIO_unlink(sv ? SvPVX_const(sv) : tempname);
2941a2e1 5038 }
ef8d46e8 5039 SvREFCNT_dec(sv);
2941a2e1 5040# else /* !HAS_MKSTEMP, fallback to stdio tmpfile(). */
c4420975 5041 FILE * const stdio = PerlSIO_tmpfile();
2941a2e1 5042
085e731f
CB
5043 if (stdio)
5044 f = PerlIO_fdopen(fileno(stdio), "w+");
5045
2941a2e1
JH
5046# endif /* else HAS_MKSTEMP */
5047#endif /* else WIN32 */
5048 return f;
760ac839
LW
5049}
5050
6f9d8c32
NIS
5051#undef HAS_FSETPOS
5052#undef HAS_FGETPOS
5053
22569500
NIS
5054#endif /* USE_SFIO */
5055#endif /* PERLIO_IS_STDIO */
760ac839 5056
9e353e3b 5057/*======================================================================================*/
14a5cf38 5058/*
71200d45
NIS
5059 * Now some functions in terms of above which may be needed even if we are
5060 * not in true PerlIO mode
9e353e3b 5061 */
188f0c84
YO
5062const char *
5063Perl_PerlIO_context_layers(pTHX_ const char *mode)
5064{
5065 dVAR;
8b850bd5
NC
5066 const char *direction = NULL;
5067 SV *layers;
188f0c84
YO
5068 /*
5069 * Need to supply default layer info from open.pm
5070 */
8b850bd5
NC
5071
5072 if (!PL_curcop)
5073 return NULL;
5074
5075 if (mode && mode[0] != 'r') {
5076 if (PL_curcop->cop_hints & HINT_LEXICAL_IO_OUT)
5077 direction = "open>";
5078 } else {
5079 if (PL_curcop->cop_hints & HINT_LEXICAL_IO_IN)
5080 direction = "open<";
188f0c84 5081 }
8b850bd5
NC
5082 if (!direction)
5083 return NULL;
5084
20439bc7 5085 layers = cop_hints_fetch_pvn(PL_curcop, direction, 5, 0, 0);
8b850bd5
NC
5086
5087 assert(layers);
5088 return SvOK(layers) ? SvPV_nolen_const(layers) : NULL;
188f0c84
YO
5089}
5090
9e353e3b 5091
760ac839
LW
5092#ifndef HAS_FSETPOS
5093#undef PerlIO_setpos
5094int
766a733e 5095PerlIO_setpos(PerlIO *f, SV *pos)
760ac839 5096{
14a5cf38
JH
5097 dTHX;
5098 if (SvOK(pos)) {
5099 STRLEN len;
c4420975 5100 const Off_t * const posn = (Off_t *) SvPV(pos, len);
14a5cf38
JH
5101 if (f && len == sizeof(Off_t))
5102 return PerlIO_seek(f, *posn, SEEK_SET);
5103 }
93189314 5104 SETERRNO(EINVAL, SS_IVCHAN);
14a5cf38 5105 return -1;
760ac839 5106}
c411622e 5107#else
c411622e 5108#undef PerlIO_setpos
5109int
766a733e 5110PerlIO_setpos(PerlIO *f, SV *pos)
c411622e 5111{
14a5cf38
JH
5112 dTHX;
5113 if (SvOK(pos)) {
5114 STRLEN len;
c4420975 5115 Fpos_t * const fpos = (Fpos_t *) SvPV(pos, len);
14a5cf38 5116 if (f && len == sizeof(Fpos_t)) {
2d4389e4 5117#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
14a5cf38 5118 return fsetpos64(f, fpos);
d9b3e12d 5119#else
14a5cf38 5120 return fsetpos(f, fpos);
d9b3e12d 5121#endif
14a5cf38 5122 }
766a733e 5123 }
93189314 5124 SETERRNO(EINVAL, SS_IVCHAN);
14a5cf38 5125 return -1;
c411622e 5126}
5127#endif
760ac839
LW
5128
5129#ifndef HAS_FGETPOS
5130#undef PerlIO_getpos
5131int
766a733e 5132PerlIO_getpos(PerlIO *f, SV *pos)
760ac839 5133{
14a5cf38
JH
5134 dTHX;
5135 Off_t posn = PerlIO_tell(f);
5136 sv_setpvn(pos, (char *) &posn, sizeof(posn));
5137 return (posn == (Off_t) - 1) ? -1 : 0;
760ac839 5138}
c411622e 5139#else
c411622e 5140#undef PerlIO_getpos
5141int
766a733e 5142PerlIO_getpos(PerlIO *f, SV *pos)
c411622e 5143{
14a5cf38
JH
5144 dTHX;
5145 Fpos_t fpos;
5146 int code;
2d4389e4 5147#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
14a5cf38 5148 code = fgetpos64(f, &fpos);
d9b3e12d 5149#else
14a5cf38 5150 code = fgetpos(f, &fpos);
d9b3e12d 5151#endif
14a5cf38
JH
5152 sv_setpvn(pos, (char *) &fpos, sizeof(fpos));
5153 return code;
c411622e 5154}
5155#endif
760ac839
LW
5156
5157#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
5158
5159int
c78749f2 5160vprintf(char *pat, char *args)
662a7e3f
CS
5161{
5162 _doprnt(pat, args, stdout);
22569500 5163 return 0; /* wrong, but perl doesn't use the return
14a5cf38 5164 * value */
662a7e3f
CS
5165}
5166
5167int
c78749f2 5168vfprintf(FILE *fd, char *pat, char *args)
760ac839
LW
5169{
5170 _doprnt(pat, args, fd);
22569500 5171 return 0; /* wrong, but perl doesn't use the return
14a5cf38 5172 * value */
760ac839
LW
5173}
5174
5175#endif
5176
5177#ifndef PerlIO_vsprintf
6f9d8c32 5178int
8ac85365 5179PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
760ac839 5180{
8ff9a42b 5181 dTHX;
d9fad198 5182 const int val = my_vsnprintf(s, n > 0 ? n : 0, fmt, ap);
14333449
AL
5183 PERL_UNUSED_CONTEXT;
5184
1208b3dd
JH
5185#ifndef PERL_MY_VSNPRINTF_GUARDED
5186 if (val < 0 || (n > 0 ? val >= n : 0)) {
37405f90 5187 Perl_croak(aTHX_ "panic: my_vsnprintf overflow in PerlIO_vsprintf\n");
760ac839 5188 }
1208b3dd 5189#endif
14a5cf38 5190 return val;
760ac839
LW
5191}
5192#endif
5193
5194#ifndef PerlIO_sprintf
6f9d8c32 5195int
14a5cf38 5196PerlIO_sprintf(char *s, int n, const char *fmt, ...)
760ac839 5197{
14a5cf38
JH
5198 va_list ap;
5199 int result;
5200 va_start(ap, fmt);
5201 result = PerlIO_vsprintf(s, n, fmt, ap);
5202 va_end(ap);
5203 return result;
760ac839
LW
5204}
5205#endif
9cfa90c0
NC
5206
5207/*
5208 * Local variables:
5209 * c-indentation-style: bsd
5210 * c-basic-offset: 4
14d04a33 5211 * indent-tabs-mode: nil
9cfa90c0
NC
5212 * End:
5213 *
14d04a33 5214 * ex: set ts=8 sts=4 sw=4 et:
37442d52 5215 */