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