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