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