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