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