Apply the spirit of patch from Nicholas Clark:
[p5sagit/p5-mst-13.2.git] / perlio.c
CommitLineData
760ac839 1/* perlio.c
2 *
26fb694e 3 * Copyright (c) 1996-2001, Nick Ing-Simmons
760ac839 4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
10#define VOIDUSED 1
12ae5dfc 11#ifdef PERL_MICRO
12# include "uconfig.h"
13#else
14# include "config.h"
15#endif
760ac839 16
6f9d8c32 17#define PERLIO_NOT_STDIO 0
760ac839 18#if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
6f9d8c32 19/* #define PerlIO FILE */
760ac839 20#endif
21/*
6f9d8c32 22 * This file provides those parts of PerlIO abstraction
88b61e10 23 * which are not #defined in perlio.h.
6f9d8c32 24 * Which these are depends on various Configure #ifdef's
760ac839 25 */
26
27#include "EXTERN.h"
864dbfa3 28#define PERL_IN_PERLIO_C
760ac839 29#include "perl.h"
30
5f1a76d0 31#undef PerlMemShared_calloc
32#define PerlMemShared_calloc(x,y) calloc(x,y)
33#undef PerlMemShared_free
34#define PerlMemShared_free(x) free(x)
35
60382766 36int
f5b9d040 37perlsio_binmode(FILE *fp, int iotype, int mode)
60382766 38{
39/* This used to be contents of do_binmode in doio.c */
40#ifdef DOSISH
41# if defined(atarist) || defined(__MINT__)
f5b9d040 42 if (!fflush(fp)) {
60382766 43 if (mode & O_BINARY)
44 ((FILE*)fp)->_flag |= _IOBIN;
45 else
46 ((FILE*)fp)->_flag &= ~ _IOBIN;
47 return 1;
48 }
49 return 0;
50# else
eb73beca 51 dTHX;
f5b9d040 52 if (PerlLIO_setmode(fileno(fp), mode) != -1) {
60382766 53# if defined(WIN32) && defined(__BORLANDC__)
54 /* The translation mode of the stream is maintained independent
55 * of the translation mode of the fd in the Borland RTL (heavy
56 * digging through their runtime sources reveal). User has to
57 * set the mode explicitly for the stream (though they don't
58 * document this anywhere). GSAR 97-5-24
59 */
f5b9d040 60 fseek(fp,0L,0);
60382766 61 if (mode & O_BINARY)
f5b9d040 62 fp->flags |= _F_BIN;
60382766 63 else
f5b9d040 64 fp->flags &= ~ _F_BIN;
60382766 65# endif
66 return 1;
67 }
68 else
69 return 0;
70# endif
71#else
72# if defined(USEMYBINMODE)
73 if (my_binmode(fp, iotype, mode) != FALSE)
74 return 1;
75 else
76 return 0;
77# else
78 return 1;
79# endif
80#endif
81}
82
eb73beca 83#ifndef PERLIO_LAYERS
84int
85PerlIO_apply_layers(pTHX_ PerlIO *f, const char *mode, const char *names)
86{
87 if (!names || !*names || strEQ(names,":crlf") || strEQ(names,":raw"))
88 {
89 return 0;
90 }
91 Perl_croak(aTHX_ "Cannot apply \"%s\" in non-PerlIO perl",names);
92 /* NOTREACHED */
93 return -1;
94}
95
f5b9d040 96int
97PerlIO_binmode(pTHX_ PerlIO *fp, int iotype, int mode, const char *names)
98{
99 return perlsio_binmode(fp,iotype,mode);
100}
60382766 101
ac27b0f5 102#endif
103
32e30700 104
6f9d8c32 105#ifdef PERLIO_IS_STDIO
760ac839 106
107void
8ac85365 108PerlIO_init(void)
760ac839 109{
6f9d8c32 110 /* Does nothing (yet) except force this file to be included
760ac839 111 in perl binary. That allows this file to force inclusion
6f9d8c32 112 of other functions that may be required by loadable
113 extensions e.g. for FileHandle::tmpfile
760ac839 114 */
115}
116
33dcbb9a 117#undef PerlIO_tmpfile
118PerlIO *
8ac85365 119PerlIO_tmpfile(void)
33dcbb9a 120{
121 return tmpfile();
122}
123
760ac839 124#else /* PERLIO_IS_STDIO */
125
126#ifdef USE_SFIO
127
128#undef HAS_FSETPOS
129#undef HAS_FGETPOS
130
6f9d8c32 131/* This section is just to make sure these functions
760ac839 132 get pulled in from libsfio.a
133*/
134
135#undef PerlIO_tmpfile
136PerlIO *
c78749f2 137PerlIO_tmpfile(void)
760ac839 138{
139 return sftmp(0);
140}
141
142void
c78749f2 143PerlIO_init(void)
760ac839 144{
6f9d8c32 145 /* Force this file to be included in perl binary. Which allows
146 * this file to force inclusion of other functions that may be
147 * required by loadable extensions e.g. for FileHandle::tmpfile
760ac839 148 */
149
150 /* Hack
151 * sfio does its own 'autoflush' on stdout in common cases.
6f9d8c32 152 * Flush results in a lot of lseek()s to regular files and
760ac839 153 * lot of small writes to pipes.
154 */
155 sfset(sfstdout,SF_SHARE,0);
156}
157
17c3b450 158#else /* USE_SFIO */
6f9d8c32 159/*======================================================================================*/
6f9d8c32 160/* Implement all the PerlIO interface ourselves.
9e353e3b 161 */
760ac839 162
76ced9ad 163#include "perliol.h"
164
b1ef6e3b 165/* We _MUST_ have <unistd.h> if we are using lseek() and may have large files */
02f66e2f 166#ifdef I_UNISTD
167#include <unistd.h>
168#endif
06da4f11 169#ifdef HAS_MMAP
170#include <sys/mman.h>
171#endif
172
f3862f8b 173#include "XSUB.h"
02f66e2f 174
88b61e10 175void PerlIO_debug(const char *fmt,...) __attribute__((format(__printf__,1,2)));
6f9d8c32 176
6f9d8c32 177void
88b61e10 178PerlIO_debug(const char *fmt,...)
6f9d8c32 179{
adb71456 180 dTHX;
6f9d8c32 181 static int dbg = 0;
88b61e10 182 va_list ap;
183 va_start(ap,fmt);
6f9d8c32 184 if (!dbg)
185 {
00b02797 186 char *s = PerlEnv_getenv("PERLIO_DEBUG");
6f9d8c32 187 if (s && *s)
00b02797 188 dbg = PerlLIO_open3(s,O_WRONLY|O_CREAT|O_APPEND,0666);
6f9d8c32 189 else
190 dbg = -1;
191 }
192 if (dbg > 0)
193 {
194 dTHX;
6f9d8c32 195 SV *sv = newSVpvn("",0);
196 char *s;
197 STRLEN len;
05d1247b 198 s = CopFILE(PL_curcop);
199 if (!s)
200 s = "(none)";
201 Perl_sv_catpvf(aTHX_ sv, "%s:%"IVdf" ", s, (IV)CopLINE(PL_curcop));
c7fc522f 202 Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap);
203
6f9d8c32 204 s = SvPV(sv,len);
00b02797 205 PerlLIO_write(dbg,s,len);
6f9d8c32 206 SvREFCNT_dec(sv);
207 }
88b61e10 208 va_end(ap);
6f9d8c32 209}
210
9e353e3b 211/*--------------------------------------------------------------------------------------*/
212
9e353e3b 213/* Inner level routines */
214
b1ef6e3b 215/* Table of pointers to the PerlIO structs (malloc'ed) */
05d1247b 216PerlIO *_perlio = NULL;
217#define PERLIO_TABLE_SIZE 64
6f9d8c32 218
760ac839 219PerlIO *
5f1a76d0 220PerlIO_allocate(pTHX)
6f9d8c32 221{
f3862f8b 222 /* Find a free slot in the table, allocating new table as necessary */
5f1a76d0 223 PerlIO **last;
6f9d8c32 224 PerlIO *f;
5f1a76d0 225 last = &_perlio;
05d1247b 226 while ((f = *last))
6f9d8c32 227 {
05d1247b 228 int i;
229 last = (PerlIO **)(f);
230 for (i=1; i < PERLIO_TABLE_SIZE; i++)
6f9d8c32 231 {
05d1247b 232 if (!*++f)
6f9d8c32 233 {
6f9d8c32 234 return f;
235 }
6f9d8c32 236 }
6f9d8c32 237 }
5f1a76d0 238 f = PerlMemShared_calloc(PERLIO_TABLE_SIZE,sizeof(PerlIO));
05d1247b 239 if (!f)
5f1a76d0 240 {
241 return NULL;
766a733e 242 }
05d1247b 243 *last = f;
244 return f+1;
245}
246
247void
5f1a76d0 248PerlIO_cleantable(pTHX_ PerlIO **tablep)
05d1247b 249{
250 PerlIO *table = *tablep;
251 if (table)
252 {
253 int i;
5f1a76d0 254 PerlIO_cleantable(aTHX_ (PerlIO **) &(table[0]));
05d1247b 255 for (i=PERLIO_TABLE_SIZE-1; i > 0; i--)
256 {
257 PerlIO *f = table+i;
60382766 258 if (*f)
3789aae2 259 {
260 PerlIO_close(f);
261 }
05d1247b 262 }
5f1a76d0 263 PerlMemShared_free(table);
05d1247b 264 *tablep = NULL;
265 }
266}
267
4a4a6116 268HV *PerlIO_layer_hv;
269AV *PerlIO_layer_av;
270
05d1247b 271void
5f1a76d0 272PerlIO_cleanup()
05d1247b 273{
5f1a76d0 274 dTHX;
275 PerlIO_cleantable(aTHX_ &_perlio);
6f9d8c32 276}
277
9e353e3b 278void
279PerlIO_pop(PerlIO *f)
760ac839 280{
5f1a76d0 281 dTHX;
9e353e3b 282 PerlIOl *l = *f;
283 if (l)
6f9d8c32 284 {
86295796 285 PerlIO_debug("PerlIO_pop f=%p %s\n",f,l->tab->name);
26fb694e 286 if (l->tab->Popped)
287 (*l->tab->Popped)(f);
9e353e3b 288 *f = l->next;
5f1a76d0 289 PerlMemShared_free(l);
6f9d8c32 290 }
6f9d8c32 291}
292
9e353e3b 293/*--------------------------------------------------------------------------------------*/
b931b1d9 294/* XS Interface for perl code */
9e353e3b 295
b931b1d9 296XS(XS_perlio_import)
f3862f8b 297{
298 dXSARGS;
299 GV *gv = CvGV(cv);
300 char *s = GvNAME(gv);
301 STRLEN l = GvNAMELEN(gv);
302 PerlIO_debug("%.*s\n",(int) l,s);
303 XSRETURN_EMPTY;
304}
305
b931b1d9 306XS(XS_perlio_unimport)
f3862f8b 307{
308 dXSARGS;
309 GV *gv = CvGV(cv);
310 char *s = GvNAME(gv);
311 STRLEN l = GvNAMELEN(gv);
312 PerlIO_debug("%.*s\n",(int) l,s);
313 XSRETURN_EMPTY;
314}
315
f3862f8b 316SV *
ac27b0f5 317PerlIO_find_layer(const char *name, STRLEN len)
f3862f8b 318{
319 dTHX;
320 SV **svp;
321 SV *sv;
766a733e 322 if ((SSize_t) len <= 0)
f3862f8b 323 len = strlen(name);
324 svp = hv_fetch(PerlIO_layer_hv,name,len,0);
325 if (svp && (sv = *svp) && SvROK(sv))
326 return *svp;
327 return NULL;
328}
329
b13b2135 330
331static int
332perlio_mg_set(pTHX_ SV *sv, MAGIC *mg)
333{
334 if (SvROK(sv))
335 {
b931b1d9 336 IO *io = GvIOn((GV *)SvRV(sv));
b13b2135 337 PerlIO *ifp = IoIFP(io);
338 PerlIO *ofp = IoOFP(io);
339 AV *av = (AV *) mg->mg_obj;
4659c93f 340 Perl_warn(aTHX_ "set %"SVf" %p %p %p",sv,io,ifp,ofp);
b13b2135 341 }
342 return 0;
343}
344
345static int
346perlio_mg_get(pTHX_ SV *sv, MAGIC *mg)
347{
348 if (SvROK(sv))
349 {
b931b1d9 350 IO *io = GvIOn((GV *)SvRV(sv));
b13b2135 351 PerlIO *ifp = IoIFP(io);
352 PerlIO *ofp = IoOFP(io);
353 AV *av = (AV *) mg->mg_obj;
4659c93f 354 Perl_warn(aTHX_ "get %"SVf" %p %p %p",sv,io,ifp,ofp);
b13b2135 355 }
356 return 0;
357}
358
359static int
360perlio_mg_clear(pTHX_ SV *sv, MAGIC *mg)
361{
4659c93f 362 Perl_warn(aTHX_ "clear %"SVf,sv);
b13b2135 363 return 0;
364}
365
366static int
367perlio_mg_free(pTHX_ SV *sv, MAGIC *mg)
368{
4659c93f 369 Perl_warn(aTHX_ "free %"SVf,sv);
b13b2135 370 return 0;
371}
372
373MGVTBL perlio_vtab = {
374 perlio_mg_get,
375 perlio_mg_set,
376 NULL, /* len */
377 NULL,
378 perlio_mg_free
379};
380
381XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
382{
383 dXSARGS;
384 SV *sv = SvRV(ST(1));
385 AV *av = newAV();
386 MAGIC *mg;
387 int count = 0;
388 int i;
389 sv_magic(sv, (SV *)av, '~', NULL, 0);
390 SvRMAGICAL_off(sv);
391 mg = mg_find(sv,'~');
392 mg->mg_virtual = &perlio_vtab;
393 mg_magical(sv);
4659c93f 394 Perl_warn(aTHX_ "attrib %"SVf,sv);
b13b2135 395 for (i=2; i < items; i++)
396 {
397 STRLEN len;
ac27b0f5 398 const char *name = SvPV(ST(i),len);
b13b2135 399 SV *layer = PerlIO_find_layer(name,len);
400 if (layer)
401 {
402 av_push(av,SvREFCNT_inc(layer));
403 }
404 else
405 {
406 ST(count) = ST(i);
407 count++;
408 }
409 }
410 SvREFCNT_dec(av);
411 XSRETURN(count);
412}
413
f3862f8b 414void
415PerlIO_define_layer(PerlIO_funcs *tab)
416{
417 dTHX;
b931b1d9 418 HV *stash = gv_stashpv("perlio::Layer", TRUE);
e7778b43 419 SV *sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))),stash);
26fb694e 420 if (!PerlIO_layer_hv)
421 {
422 PerlIO_layer_hv = get_hv("open::layers",GV_ADD|GV_ADDMULTI);
423 }
f3862f8b 424 hv_store(PerlIO_layer_hv,tab->name,strlen(tab->name),sv,0);
dfebf958 425 PerlIO_debug("define %s %p\n",tab->name,tab);
f3862f8b 426}
427
dfebf958 428void
429PerlIO_default_buffer(pTHX)
430{
431 PerlIO_funcs *tab = &PerlIO_perlio;
432 if (O_BINARY != O_TEXT)
433 {
434 tab = &PerlIO_crlf;
435 }
436 else
437 {
438 if (PerlIO_stdio.Set_ptrcnt)
439 {
440 tab = &PerlIO_stdio;
441 }
442 }
443 PerlIO_debug("Pushing %s\n",tab->name);
444 av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(tab->name,0)));
dfebf958 445}
446
447
f3862f8b 448PerlIO_funcs *
449PerlIO_default_layer(I32 n)
450{
451 dTHX;
452 SV **svp;
453 SV *layer;
454 PerlIO_funcs *tab = &PerlIO_stdio;
455 int len;
26fb694e 456 if (!PerlIO_layer_av)
f3862f8b 457 {
ac27b0f5 458 const char *s = PerlEnv_getenv("PERLIO");
26fb694e 459 PerlIO_layer_av = get_av("open::layers",GV_ADD|GV_ADDMULTI);
b931b1d9 460 newXS("perlio::import",XS_perlio_import,__FILE__);
461 newXS("perlio::unimport",XS_perlio_unimport,__FILE__);
462#if 0
b13b2135 463 newXS("io::MODIFY_SCALAR_ATTRIBUTES",XS_io_MODIFY_SCALAR_ATTRIBUTES,__FILE__);
b931b1d9 464#endif
dfebf958 465 PerlIO_define_layer(&PerlIO_raw);
f3862f8b 466 PerlIO_define_layer(&PerlIO_unix);
f3862f8b 467 PerlIO_define_layer(&PerlIO_perlio);
468 PerlIO_define_layer(&PerlIO_stdio);
66ecd56b 469 PerlIO_define_layer(&PerlIO_crlf);
06da4f11 470#ifdef HAS_MMAP
471 PerlIO_define_layer(&PerlIO_mmap);
472#endif
dfebf958 473 PerlIO_define_layer(&PerlIO_utf8);
26fb694e 474 PerlIO_define_layer(&PerlIO_byte);
f3862f8b 475 av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(PerlIO_unix.name,0)));
476 if (s)
477 {
dfebf958 478 IV buffered = 0;
f3862f8b 479 while (*s)
480 {
00b02797 481 while (*s && isSPACE((unsigned char)*s))
f3862f8b 482 s++;
483 if (*s)
484 {
ac27b0f5 485 const char *e = s;
f3862f8b 486 SV *layer;
00b02797 487 while (*e && !isSPACE((unsigned char)*e))
f3862f8b 488 e++;
ac27b0f5 489 if (*s == ':')
490 s++;
f3862f8b 491 layer = PerlIO_find_layer(s,e-s);
492 if (layer)
493 {
dfebf958 494 PerlIO_funcs *tab = INT2PTR(PerlIO_funcs *, SvIV(SvRV(layer)));
495 if ((tab->kind & PERLIO_K_DUMMY) && (tab->kind & PERLIO_K_BUFFERED))
496 {
497 if (!buffered)
498 PerlIO_default_buffer(aTHX);
499 }
f3862f8b 500 PerlIO_debug("Pushing %.*s\n",(e-s),s);
501 av_push(PerlIO_layer_av,SvREFCNT_inc(layer));
dfebf958 502 buffered |= (tab->kind & PERLIO_K_BUFFERED);
f3862f8b 503 }
504 else
ef0f9817 505 Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",(e-s),s);
f3862f8b 506 s = e;
507 }
508 }
509 }
510 }
511 len = av_len(PerlIO_layer_av);
512 if (len < 1)
513 {
dfebf958 514 PerlIO_default_buffer(aTHX);
f3862f8b 515 len = av_len(PerlIO_layer_av);
516 }
517 if (n < 0)
518 n += len+1;
519 svp = av_fetch(PerlIO_layer_av,n,0);
520 if (svp && (layer = *svp) && SvROK(layer) && SvIOK((layer = SvRV(layer))))
521 {
e7778b43 522 tab = INT2PTR(PerlIO_funcs *, SvIV(layer));
f3862f8b 523 }
524 /* PerlIO_debug("Layer %d is %s\n",n,tab->name); */
525 return tab;
526}
527
60382766 528#define PerlIO_default_top() PerlIO_default_layer(-1)
529#define PerlIO_default_btm() PerlIO_default_layer(0)
530
531void
532PerlIO_stdstreams()
533{
534 if (!_perlio)
535 {
5f1a76d0 536 dTHX;
537 PerlIO_allocate(aTHX);
f5b9d040 538 PerlIO_fdopen(0,"Ir" PERLIO_STDTEXT);
539 PerlIO_fdopen(1,"Iw" PERLIO_STDTEXT);
540 PerlIO_fdopen(2,"Iw" PERLIO_STDTEXT);
60382766 541 }
542}
543
544PerlIO *
33af2bc7 545PerlIO_push(PerlIO *f,PerlIO_funcs *tab,const char *mode,const char *arg,STRLEN len)
60382766 546{
5f1a76d0 547 dTHX;
60382766 548 PerlIOl *l = NULL;
5f1a76d0 549 l = PerlMemShared_calloc(tab->size,sizeof(char));
60382766 550 if (l)
551 {
552 Zero(l,tab->size,char);
553 l->next = *f;
554 l->tab = tab;
555 *f = l;
64977eb6 556 PerlIO_debug("PerlIO_push f=%p %s %s '%.*s'\n",
557 f,tab->name,(mode) ? mode : "(Null)",(int) len,arg);
33af2bc7 558 if ((*l->tab->Pushed)(f,mode,arg,len) != 0)
60382766 559 {
560 PerlIO_pop(f);
561 return NULL;
562 }
563 }
564 return f;
565}
566
dfebf958 567IV
4b803d04 568PerlIOPop_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
569{
570 PerlIO_pop(f);
571 if (*f)
572 {
573 PerlIO_flush(f);
574 PerlIO_pop(f);
575 return 0;
576 }
577 return -1;
578}
579
580IV
dfebf958 581PerlIORaw_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
582{
4b803d04 583 /* Remove the dummy layer */
584 PerlIO_pop(f);
dfebf958 585 /* Pop back to bottom layer */
4b803d04 586 if (f && *f)
dfebf958 587 {
4b803d04 588 int code = 0;
589 PerlIO_flush(f);
590 while (!(PerlIOBase(f)->tab->kind & PERLIO_K_RAW))
dfebf958 591 {
4b803d04 592 if (*PerlIONext(f))
593 {
594 PerlIO_pop(f);
595 }
596 else
597 {
598 /* Nothing bellow - push unix on top then remove it */
599 if (PerlIO_push(f,PerlIO_default_btm(),mode,arg,len))
600 {
601 PerlIO_pop(PerlIONext(f));
602 }
603 break;
604 }
dfebf958 605 }
26fb694e 606 PerlIO_debug(":raw f=%p :%s\n",f,PerlIOBase(f)->tab->name);
dfebf958 607 return 0;
608 }
609 return -1;
610}
611
ac27b0f5 612int
613PerlIO_apply_layers(pTHX_ PerlIO *f, const char *mode, const char *names)
614{
615 if (names)
616 {
617 const char *s = names;
618 while (*s)
619 {
26fb694e 620 while (isSPACE(*s) || *s == ':')
ac27b0f5 621 s++;
622 if (*s)
623 {
64977eb6 624 STRLEN llen = 0;
ac27b0f5 625 const char *e = s;
33af2bc7 626 const char *as = Nullch;
64977eb6 627 STRLEN alen = 0;
628 if (!isIDFIRST(*s))
33af2bc7 629 {
64977eb6 630 /* Message is consistent with how attribute lists are passed.
631 Even though this means "foo : : bar" is seen as an invalid separator
632 character. */
633 char q = ((*s == '\'') ? '"' : '\'');
634 Perl_warn(aTHX_ "perlio: invalid separator character %c%c%c in layer specification list", q, *s, q);
635 return -1;
636 }
637 do
638 {
639 e++;
640 } while (isALNUM(*e));
641 llen = e-s;
642 if (*e == '(')
643 {
644 int nesting = 1;
645 as = ++e;
646 while (nesting)
33af2bc7 647 {
64977eb6 648 switch (*e++)
649 {
650 case ')':
651 if (--nesting == 0)
652 alen = (e-1)-as;
653 break;
654 case '(':
655 ++nesting;
656 break;
657 case '\\':
658 /* It's a nul terminated string, not allowed to \ the terminating null.
659 Anything other character is passed over. */
660 if (*e++)
661 {
662 break;
663 }
664 /* Drop through */
665 case '\0':
666 e--;
667 Perl_warn(aTHX_ "perlio: argument list not closed for layer \"%.*s\"",(int)(e - s),s);
668 return -1;
669 default:
670 /* boring. */
671 break;
672 }
33af2bc7 673 }
33af2bc7 674 }
ac27b0f5 675 if (e > s)
676 {
64977eb6 677 SV *layer = PerlIO_find_layer(s,llen);
678 if (layer)
60382766 679 {
64977eb6 680 PerlIO_funcs *tab = INT2PTR(PerlIO_funcs *, SvIV(SvRV(layer)));
681 if (tab)
60382766 682 {
64977eb6 683 if (!PerlIO_push(f,tab,mode,as,alen))
684 return -1;
60382766 685 }
60382766 686 }
64977eb6 687 else
688 Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",(int)llen,s);
ac27b0f5 689 }
690 s = e;
691 }
692 }
693 }
694 return 0;
695}
696
f3862f8b 697
9e353e3b 698
60382766 699/*--------------------------------------------------------------------------------------*/
700/* Given the abstraction above the public API functions */
701
702int
f5b9d040 703PerlIO_binmode(pTHX_ PerlIO *f, int iotype, int mode, const char *names)
76ced9ad 704{
86295796 705 PerlIO_debug("PerlIO_binmode f=%p %s %c %x %s\n",
a4d3c1d3 706 f,PerlIOBase(f)->tab->name,iotype,mode, (names) ? names : "(Null)");
33af2bc7 707 if (!names && (O_TEXT != O_BINARY && (mode & O_BINARY)))
76ced9ad 708 {
f5b9d040 709 PerlIO *top = f;
60382766 710 PerlIOl *l;
711 while (l = *top)
76ced9ad 712 {
60382766 713 if (PerlIOBase(top)->tab == &PerlIO_crlf)
714 {
715 PerlIO_flush(top);
a4d3c1d3 716 PerlIOBase(top)->flags &= ~PERLIO_F_CRLF;
60382766 717 break;
718 }
719 top = PerlIONext(top);
76ced9ad 720 }
721 }
f5b9d040 722 return PerlIO_apply_layers(aTHX_ f, NULL, names) == 0 ? TRUE : FALSE;
723}
724
725#undef PerlIO__close
726int
727PerlIO__close(PerlIO *f)
728{
729 return (*PerlIOBase(f)->tab->Close)(f);
76ced9ad 730}
731
5f1a76d0 732#undef PerlIO_fdupopen
733PerlIO *
734PerlIO_fdupopen(pTHX_ PerlIO *f)
735{
736 char buf[8];
737 int fd = PerlLIO_dup(PerlIO_fileno(f));
738 PerlIO *new = PerlIO_fdopen(fd,PerlIO_modestr(f,buf));
739 if (new)
740 {
741 Off_t posn = PerlIO_tell(f);
742 PerlIO_seek(new,posn,SEEK_SET);
743 }
766a733e 744 return new;
5f1a76d0 745}
f5b9d040 746
b931b1d9 747#undef PerlIO_close
748int
749PerlIO_close(PerlIO *f)
750{
751 int code = (*PerlIOBase(f)->tab->Close)(f);
752 while (*f)
753 {
754 PerlIO_pop(f);
755 }
756 return code;
757}
758
759#undef PerlIO_fileno
760int
761PerlIO_fileno(PerlIO *f)
762{
763 return (*PerlIOBase(f)->tab->Fileno)(f);
764}
765
766
767
9e353e3b 768#undef PerlIO_fdopen
769PerlIO *
770PerlIO_fdopen(int fd, const char *mode)
771{
772 PerlIO_funcs *tab = PerlIO_default_top();
f3862f8b 773 if (!_perlio)
774 PerlIO_stdstreams();
06da4f11 775 return (*tab->Fdopen)(tab,fd,mode);
9e353e3b 776}
777
6f9d8c32 778#undef PerlIO_open
779PerlIO *
780PerlIO_open(const char *path, const char *mode)
781{
9e353e3b 782 PerlIO_funcs *tab = PerlIO_default_top();
f3862f8b 783 if (!_perlio)
784 PerlIO_stdstreams();
06da4f11 785 return (*tab->Open)(tab,path,mode);
6f9d8c32 786}
787
9e353e3b 788#undef PerlIO_reopen
789PerlIO *
790PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
6f9d8c32 791{
9e353e3b 792 if (f)
6f9d8c32 793 {
9e353e3b 794 PerlIO_flush(f);
795 if ((*PerlIOBase(f)->tab->Reopen)(path,mode,f) == 0)
796 {
33af2bc7 797 if ((*PerlIOBase(f)->tab->Pushed)(f,mode,Nullch,0) == 0)
06da4f11 798 return f;
9e353e3b 799 }
800 return NULL;
6f9d8c32 801 }
9e353e3b 802 else
803 return PerlIO_open(path,mode);
760ac839 804}
805
9e353e3b 806#undef PerlIO_read
807SSize_t
808PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 809{
9e353e3b 810 return (*PerlIOBase(f)->tab->Read)(f,vbuf,count);
760ac839 811}
812
313ca112 813#undef PerlIO_unread
814SSize_t
815PerlIO_unread(PerlIO *f, const void *vbuf, Size_t count)
760ac839 816{
313ca112 817 return (*PerlIOBase(f)->tab->Unread)(f,vbuf,count);
760ac839 818}
819
9e353e3b 820#undef PerlIO_write
821SSize_t
822PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
760ac839 823{
9e353e3b 824 return (*PerlIOBase(f)->tab->Write)(f,vbuf,count);
760ac839 825}
826
9e353e3b 827#undef PerlIO_seek
6f9d8c32 828int
9e353e3b 829PerlIO_seek(PerlIO *f, Off_t offset, int whence)
760ac839 830{
9e353e3b 831 return (*PerlIOBase(f)->tab->Seek)(f,offset,whence);
760ac839 832}
833
9e353e3b 834#undef PerlIO_tell
835Off_t
836PerlIO_tell(PerlIO *f)
760ac839 837{
9e353e3b 838 return (*PerlIOBase(f)->tab->Tell)(f);
760ac839 839}
840
9e353e3b 841#undef PerlIO_flush
6f9d8c32 842int
9e353e3b 843PerlIO_flush(PerlIO *f)
760ac839 844{
6f9d8c32 845 if (f)
846 {
26fb694e 847 PerlIO_funcs *tab = PerlIOBase(f)->tab;
848 if (tab && tab->Flush)
849 {
850 return (*tab->Flush)(f);
851 }
852 else
853 {
854 PerlIO_debug("Cannot flush f=%p :%s\n",f,tab->name);
855 errno = EINVAL;
856 return -1;
857 }
6f9d8c32 858 }
9e353e3b 859 else
6f9d8c32 860 {
05d1247b 861 PerlIO **table = &_perlio;
9e353e3b 862 int code = 0;
05d1247b 863 while ((f = *table))
6f9d8c32 864 {
05d1247b 865 int i;
866 table = (PerlIO **)(f++);
867 for (i=1; i < PERLIO_TABLE_SIZE; i++)
9e353e3b 868 {
869 if (*f && PerlIO_flush(f) != 0)
870 code = -1;
05d1247b 871 f++;
9e353e3b 872 }
6f9d8c32 873 }
9e353e3b 874 return code;
6f9d8c32 875 }
760ac839 876}
877
06da4f11 878#undef PerlIO_fill
879int
880PerlIO_fill(PerlIO *f)
881{
882 return (*PerlIOBase(f)->tab->Fill)(f);
883}
884
f3862f8b 885#undef PerlIO_isutf8
886int
887PerlIO_isutf8(PerlIO *f)
888{
889 return (PerlIOBase(f)->flags & PERLIO_F_UTF8) != 0;
890}
891
9e353e3b 892#undef PerlIO_eof
6f9d8c32 893int
9e353e3b 894PerlIO_eof(PerlIO *f)
760ac839 895{
9e353e3b 896 return (*PerlIOBase(f)->tab->Eof)(f);
897}
898
899#undef PerlIO_error
900int
901PerlIO_error(PerlIO *f)
902{
903 return (*PerlIOBase(f)->tab->Error)(f);
904}
905
906#undef PerlIO_clearerr
907void
908PerlIO_clearerr(PerlIO *f)
909{
f5b9d040 910 if (f && *f)
911 (*PerlIOBase(f)->tab->Clearerr)(f);
9e353e3b 912}
913
914#undef PerlIO_setlinebuf
915void
916PerlIO_setlinebuf(PerlIO *f)
917{
918 (*PerlIOBase(f)->tab->Setlinebuf)(f);
919}
920
921#undef PerlIO_has_base
922int
923PerlIO_has_base(PerlIO *f)
924{
925 if (f && *f)
6f9d8c32 926 {
9e353e3b 927 return (PerlIOBase(f)->tab->Get_base != NULL);
6f9d8c32 928 }
9e353e3b 929 return 0;
760ac839 930}
931
9e353e3b 932#undef PerlIO_fast_gets
933int
934PerlIO_fast_gets(PerlIO *f)
760ac839 935{
5e2ab84b 936 if (f && *f && (PerlIOBase(f)->flags & PERLIO_F_FASTGETS))
6f9d8c32 937 {
5e2ab84b 938 PerlIO_funcs *tab = PerlIOBase(f)->tab;
939 return (tab->Set_ptrcnt != NULL);
6f9d8c32 940 }
9e353e3b 941 return 0;
942}
943
944#undef PerlIO_has_cntptr
945int
946PerlIO_has_cntptr(PerlIO *f)
947{
948 if (f && *f)
949 {
950 PerlIO_funcs *tab = PerlIOBase(f)->tab;
951 return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
952 }
953 return 0;
954}
955
956#undef PerlIO_canset_cnt
957int
958PerlIO_canset_cnt(PerlIO *f)
959{
960 if (f && *f)
961 {
c7fc522f 962 PerlIOl *l = PerlIOBase(f);
963 return (l->tab->Set_ptrcnt != NULL);
9e353e3b 964 }
c7fc522f 965 return 0;
760ac839 966}
967
968#undef PerlIO_get_base
888911fc 969STDCHAR *
a20bf0c3 970PerlIO_get_base(PerlIO *f)
760ac839 971{
9e353e3b 972 return (*PerlIOBase(f)->tab->Get_base)(f);
973}
974
975#undef PerlIO_get_bufsiz
976int
977PerlIO_get_bufsiz(PerlIO *f)
978{
979 return (*PerlIOBase(f)->tab->Get_bufsiz)(f);
980}
981
982#undef PerlIO_get_ptr
983STDCHAR *
984PerlIO_get_ptr(PerlIO *f)
985{
5e2ab84b 986 PerlIO_funcs *tab = PerlIOBase(f)->tab;
987 if (tab->Get_ptr == NULL)
988 return NULL;
989 return (*tab->Get_ptr)(f);
9e353e3b 990}
991
992#undef PerlIO_get_cnt
05d1247b 993int
9e353e3b 994PerlIO_get_cnt(PerlIO *f)
995{
5e2ab84b 996 PerlIO_funcs *tab = PerlIOBase(f)->tab;
997 if (tab->Get_cnt == NULL)
998 return 0;
999 return (*tab->Get_cnt)(f);
9e353e3b 1000}
1001
1002#undef PerlIO_set_cnt
1003void
05d1247b 1004PerlIO_set_cnt(PerlIO *f,int cnt)
9e353e3b 1005{
f3862f8b 1006 (*PerlIOBase(f)->tab->Set_ptrcnt)(f,NULL,cnt);
9e353e3b 1007}
1008
1009#undef PerlIO_set_ptrcnt
1010void
05d1247b 1011PerlIO_set_ptrcnt(PerlIO *f, STDCHAR *ptr, int cnt)
9e353e3b 1012{
5e2ab84b 1013 PerlIO_funcs *tab = PerlIOBase(f)->tab;
1014 if (tab->Set_ptrcnt == NULL)
1015 {
1016 dTHX;
1017 Perl_croak(aTHX_ "PerlIO buffer snooping abuse");
1018 }
f3862f8b 1019 (*PerlIOBase(f)->tab->Set_ptrcnt)(f,ptr,cnt);
9e353e3b 1020}
1021
1022/*--------------------------------------------------------------------------------------*/
dfebf958 1023/* utf8 and raw dummy layers */
1024
26fb694e 1025IV
1026PerlIOUtf8_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
1027{
1028 if (PerlIONext(f))
1029 {
1030 PerlIO_funcs *tab = PerlIOBase(f)->tab;
1031 PerlIO_pop(f);
1032 if (tab->kind & PERLIO_K_UTF8)
1033 PerlIOBase(f)->flags |= PERLIO_F_UTF8;
1034 else
1035 PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
1036 return 0;
1037 }
1038 return -1;
1039}
1040
dfebf958 1041PerlIO *
1042PerlIOUtf8_fdopen(PerlIO_funcs *self, int fd,const char *mode)
1043{
1044 PerlIO_funcs *tab = PerlIO_default_layer(-2);
1045 PerlIO *f = (*tab->Fdopen)(tab,fd,mode);
1046 if (f)
1047 {
26fb694e 1048 PerlIOl *l = PerlIOBase(f);
1049 if (tab->kind & PERLIO_K_UTF8)
1050 l->flags |= PERLIO_F_UTF8;
1051 else
1052 l->flags &= ~PERLIO_F_UTF8;
1053 }
dfebf958 1054 return f;
1055}
1056
1057PerlIO *
1058PerlIOUtf8_open(PerlIO_funcs *self, const char *path,const char *mode)
1059{
1060 PerlIO_funcs *tab = PerlIO_default_layer(-2);
1061 PerlIO *f = (*tab->Open)(tab,path,mode);
1062 if (f)
1063 {
26fb694e 1064 PerlIOl *l = PerlIOBase(f);
1065 if (tab->kind & PERLIO_K_UTF8)
1066 l->flags |= PERLIO_F_UTF8;
1067 else
1068 l->flags &= ~PERLIO_F_UTF8;
dfebf958 1069 }
1070 return f;
1071}
1072
1073PerlIO_funcs PerlIO_utf8 = {
1074 "utf8",
1075 sizeof(PerlIOl),
26fb694e 1076 PERLIO_K_DUMMY|PERLIO_F_UTF8,
1077 NULL,
1078 PerlIOUtf8_fdopen,
1079 PerlIOUtf8_open,
1080 NULL,
1081 PerlIOUtf8_pushed,
1082 NULL,
1083 NULL,
1084 NULL,
1085 NULL,
1086 NULL,
1087 NULL,
1088 NULL,
1089 NULL, /* flush */
1090 NULL, /* fill */
1091 NULL,
1092 NULL,
1093 NULL,
1094 NULL,
1095 NULL, /* get_base */
1096 NULL, /* get_bufsiz */
1097 NULL, /* get_ptr */
1098 NULL, /* get_cnt */
1099 NULL, /* set_ptrcnt */
1100};
1101
1102PerlIO_funcs PerlIO_byte = {
1103 "bytes",
1104 sizeof(PerlIOl),
1105 PERLIO_K_DUMMY,
dfebf958 1106 NULL,
1107 PerlIOUtf8_fdopen,
1108 PerlIOUtf8_open,
1109 NULL,
1110 PerlIOUtf8_pushed,
1111 NULL,
1112 NULL,
1113 NULL,
1114 NULL,
1115 NULL,
1116 NULL,
1117 NULL,
1118 NULL, /* flush */
1119 NULL, /* fill */
1120 NULL,
1121 NULL,
1122 NULL,
1123 NULL,
1124 NULL, /* get_base */
1125 NULL, /* get_bufsiz */
1126 NULL, /* get_ptr */
1127 NULL, /* get_cnt */
1128 NULL, /* set_ptrcnt */
1129};
1130
1131PerlIO *
1132PerlIORaw_fdopen(PerlIO_funcs *self, int fd,const char *mode)
1133{
4b803d04 1134 PerlIO_funcs *tab = PerlIO_default_btm();
dfebf958 1135 return (*tab->Fdopen)(tab,fd,mode);
1136}
1137
1138PerlIO *
1139PerlIORaw_open(PerlIO_funcs *self, const char *path,const char *mode)
1140{
4b803d04 1141 PerlIO_funcs *tab = PerlIO_default_btm();
dfebf958 1142 return (*tab->Open)(tab,path,mode);
1143}
1144
1145PerlIO_funcs PerlIO_raw = {
1146 "raw",
1147 sizeof(PerlIOl),
4b803d04 1148 PERLIO_K_DUMMY,
dfebf958 1149 NULL,
1150 PerlIORaw_fdopen,
1151 PerlIORaw_open,
1152 NULL,
1153 PerlIORaw_pushed,
26fb694e 1154 PerlIOBase_popped,
dfebf958 1155 NULL,
1156 NULL,
1157 NULL,
1158 NULL,
1159 NULL,
1160 NULL,
1161 NULL, /* flush */
1162 NULL, /* fill */
1163 NULL,
1164 NULL,
1165 NULL,
1166 NULL,
1167 NULL, /* get_base */
1168 NULL, /* get_bufsiz */
1169 NULL, /* get_ptr */
1170 NULL, /* get_cnt */
1171 NULL, /* set_ptrcnt */
1172};
1173/*--------------------------------------------------------------------------------------*/
1174/*--------------------------------------------------------------------------------------*/
9e353e3b 1175/* "Methods" of the "base class" */
1176
1177IV
1178PerlIOBase_fileno(PerlIO *f)
1179{
1180 return PerlIO_fileno(PerlIONext(f));
1181}
1182
f5b9d040 1183char *
1184PerlIO_modestr(PerlIO *f,char *buf)
1185{
1186 char *s = buf;
1187 IV flags = PerlIOBase(f)->flags;
5f1a76d0 1188 if (flags & PERLIO_F_APPEND)
1189 {
1190 *s++ = 'a';
1191 if (flags & PERLIO_F_CANREAD)
1192 {
1193 *s++ = '+';
1194 }
766a733e 1195 }
5f1a76d0 1196 else if (flags & PERLIO_F_CANREAD)
1197 {
1198 *s++ = 'r';
1199 if (flags & PERLIO_F_CANWRITE)
1200 *s++ = '+';
1201 }
1202 else if (flags & PERLIO_F_CANWRITE)
1203 {
1204 *s++ = 'w';
1205 if (flags & PERLIO_F_CANREAD)
1206 {
1207 *s++ = '+';
1208 }
1209 }
1210#if O_TEXT != O_BINARY
1211 if (!(flags & PERLIO_F_CRLF))
a4d3c1d3 1212 *s++ = 'b';
5f1a76d0 1213#endif
f5b9d040 1214 *s = '\0';
1215 return buf;
1216}
1217
76ced9ad 1218IV
33af2bc7 1219PerlIOBase_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
9e353e3b 1220{
76ced9ad 1221 PerlIOl *l = PerlIOBase(f);
f5b9d040 1222 const char *omode = mode;
1223 char temp[8];
5e2ab84b 1224 PerlIO_funcs *tab = PerlIOBase(f)->tab;
76ced9ad 1225 l->flags &= ~(PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
f5b9d040 1226 PERLIO_F_TRUNCATE|PERLIO_F_APPEND);
5e2ab84b 1227 if (tab->Set_ptrcnt != NULL)
1228 l->flags |= PERLIO_F_FASTGETS;
76ced9ad 1229 if (mode)
6f9d8c32 1230 {
76ced9ad 1231 switch (*mode++)
06da4f11 1232 {
76ced9ad 1233 case 'r':
f5b9d040 1234 l->flags |= PERLIO_F_CANREAD;
76ced9ad 1235 break;
1236 case 'a':
f5b9d040 1237 l->flags |= PERLIO_F_APPEND|PERLIO_F_CANWRITE;
76ced9ad 1238 break;
1239 case 'w':
f5b9d040 1240 l->flags |= PERLIO_F_TRUNCATE|PERLIO_F_CANWRITE;
76ced9ad 1241 break;
1242 default:
1243 errno = EINVAL;
1244 return -1;
1245 }
1246 while (*mode)
1247 {
1248 switch (*mode++)
1249 {
1250 case '+':
1251 l->flags |= PERLIO_F_CANREAD|PERLIO_F_CANWRITE;
1252 break;
1253 case 'b':
f5b9d040 1254 l->flags &= ~PERLIO_F_CRLF;
1255 break;
1256 case 't':
1257 l->flags |= PERLIO_F_CRLF;
76ced9ad 1258 break;
1259 default:
1260 errno = EINVAL;
1261 return -1;
1262 }
06da4f11 1263 }
6f9d8c32 1264 }
76ced9ad 1265 else
1266 {
1267 if (l->next)
1268 {
1269 l->flags |= l->next->flags &
f5b9d040 1270 (PERLIO_F_CANREAD|PERLIO_F_CANWRITE|PERLIO_F_TRUNCATE|PERLIO_F_APPEND);
76ced9ad 1271 }
1272 }
5e2ab84b 1273#if 0
4659c93f 1274 PerlIO_debug("PerlIOBase_pushed f=%p %s %s fl=%08"UVxf" (%s)\n",
f5b9d040 1275 f,PerlIOBase(f)->tab->name,(omode) ? omode : "(Null)",
a4d3c1d3 1276 l->flags,PerlIO_modestr(f,temp));
5e2ab84b 1277#endif
76ced9ad 1278 return 0;
1279}
1280
1281IV
1282PerlIOBase_popped(PerlIO *f)
1283{
1284 return 0;
760ac839 1285}
1286
9e353e3b 1287SSize_t
1288PerlIOBase_unread(PerlIO *f, const void *vbuf, Size_t count)
1289{
1290 Off_t old = PerlIO_tell(f);
72e44f29 1291 SSize_t done;
33af2bc7 1292 PerlIO_push(f,&PerlIO_pending,"r",Nullch,0);
72e44f29 1293 done = PerlIOBuf_unread(f,vbuf,count);
1294 PerlIOSelf(f,PerlIOBuf)->posn = old - done;
1295 return done;
9e353e3b 1296}
1297
1298IV
06da4f11 1299PerlIOBase_noop_ok(PerlIO *f)
9e353e3b 1300{
1301 return 0;
1302}
1303
1304IV
06da4f11 1305PerlIOBase_noop_fail(PerlIO *f)
1306{
1307 return -1;
1308}
1309
1310IV
9e353e3b 1311PerlIOBase_close(PerlIO *f)
1312{
1313 IV code = 0;
f5b9d040 1314 PerlIO *n = PerlIONext(f);
9e353e3b 1315 if (PerlIO_flush(f) != 0)
1316 code = -1;
f5b9d040 1317 if (n && (*PerlIOBase(n)->tab->Close)(n) != 0)
9e353e3b 1318 code = -1;
1319 PerlIOBase(f)->flags &= ~(PERLIO_F_CANREAD|PERLIO_F_CANWRITE|PERLIO_F_OPEN);
1320 return code;
1321}
1322
1323IV
1324PerlIOBase_eof(PerlIO *f)
1325{
1326 if (f && *f)
1327 {
1328 return (PerlIOBase(f)->flags & PERLIO_F_EOF) != 0;
1329 }
1330 return 1;
1331}
1332
1333IV
1334PerlIOBase_error(PerlIO *f)
1335{
1336 if (f && *f)
1337 {
1338 return (PerlIOBase(f)->flags & PERLIO_F_ERROR) != 0;
1339 }
1340 return 1;
1341}
1342
1343void
1344PerlIOBase_clearerr(PerlIO *f)
1345{
1346 if (f && *f)
1347 {
f5b9d040 1348 PerlIO *n = PerlIONext(f);
1349 PerlIOBase(f)->flags &= ~(PERLIO_F_ERROR|PERLIO_F_EOF);
1350 if (n)
1351 PerlIO_clearerr(n);
9e353e3b 1352 }
1353}
1354
1355void
1356PerlIOBase_setlinebuf(PerlIO *f)
1357{
1358
1359}
1360
9e353e3b 1361/*--------------------------------------------------------------------------------------*/
1362/* Bottom-most level for UNIX-like case */
1363
1364typedef struct
1365{
1366 struct _PerlIO base; /* The generic part */
1367 int fd; /* UNIX like file descriptor */
1368 int oflags; /* open/fcntl flags */
1369} PerlIOUnix;
1370
6f9d8c32 1371int
9e353e3b 1372PerlIOUnix_oflags(const char *mode)
760ac839 1373{
9e353e3b 1374 int oflags = -1;
1375 switch(*mode)
1376 {
1377 case 'r':
1378 oflags = O_RDONLY;
1379 if (*++mode == '+')
1380 {
1381 oflags = O_RDWR;
1382 mode++;
1383 }
1384 break;
1385
1386 case 'w':
1387 oflags = O_CREAT|O_TRUNC;
1388 if (*++mode == '+')
1389 {
1390 oflags |= O_RDWR;
1391 mode++;
1392 }
1393 else
1394 oflags |= O_WRONLY;
1395 break;
1396
1397 case 'a':
1398 oflags = O_CREAT|O_APPEND;
1399 if (*++mode == '+')
1400 {
1401 oflags |= O_RDWR;
1402 mode++;
1403 }
1404 else
1405 oflags |= O_WRONLY;
1406 break;
1407 }
83b075c3 1408 if (*mode == 'b')
1409 {
f5b9d040 1410 oflags |= O_BINARY;
1411 oflags &= ~O_TEXT;
1412 mode++;
1413 }
1414 else if (*mode == 't')
1415 {
1416 oflags |= O_TEXT;
1417 oflags &= ~O_BINARY;
60382766 1418 mode++;
1419 }
99efab12 1420 /* Always open in binary mode */
1421 oflags |= O_BINARY;
9e353e3b 1422 if (*mode || oflags == -1)
6f9d8c32 1423 {
9e353e3b 1424 errno = EINVAL;
1425 oflags = -1;
6f9d8c32 1426 }
9e353e3b 1427 return oflags;
1428}
1429
1430IV
1431PerlIOUnix_fileno(PerlIO *f)
1432{
1433 return PerlIOSelf(f,PerlIOUnix)->fd;
1434}
1435
4b803d04 1436IV
1437PerlIOUnix_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
1438{
1439 IV code = PerlIOBase_pushed(f,mode,arg,len);
1440 if (*PerlIONext(f))
1441 {
1442 PerlIOUnix *s = PerlIOSelf(f,PerlIOUnix);
1443 s->fd = PerlIO_fileno(PerlIONext(f));
1444 s->oflags = PerlIOUnix_oflags(mode);
1445 }
1446 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
1447 return code;
1448}
1449
9e353e3b 1450PerlIO *
06da4f11 1451PerlIOUnix_fdopen(PerlIO_funcs *self, int fd,const char *mode)
9e353e3b 1452{
5f1a76d0 1453 dTHX;
9e353e3b 1454 PerlIO *f = NULL;
c7fc522f 1455 if (*mode == 'I')
1456 mode++;
9e353e3b 1457 if (fd >= 0)
1458 {
1459 int oflags = PerlIOUnix_oflags(mode);
1460 if (oflags != -1)
1461 {
33af2bc7 1462 PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode,Nullch,0),PerlIOUnix);
9e353e3b 1463 s->fd = fd;
1464 s->oflags = oflags;
9e353e3b 1465 }
1466 }
1467 return f;
1468}
1469
1470PerlIO *
06da4f11 1471PerlIOUnix_open(PerlIO_funcs *self, const char *path,const char *mode)
9e353e3b 1472{
adb71456 1473 dTHX;
9e353e3b 1474 PerlIO *f = NULL;
1475 int oflags = PerlIOUnix_oflags(mode);
1476 if (oflags != -1)
1477 {
00b02797 1478 int fd = PerlLIO_open3(path,oflags,0666);
9e353e3b 1479 if (fd >= 0)
1480 {
33af2bc7 1481 PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode,Nullch,0),PerlIOUnix);
9e353e3b 1482 s->fd = fd;
1483 s->oflags = oflags;
1484 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
1485 }
1486 }
1487 return f;
760ac839 1488}
1489
760ac839 1490int
9e353e3b 1491PerlIOUnix_reopen(const char *path, const char *mode, PerlIO *f)
760ac839 1492{
9e353e3b 1493 PerlIOUnix *s = PerlIOSelf(f,PerlIOUnix);
1494 int oflags = PerlIOUnix_oflags(mode);
1495 if (PerlIOBase(f)->flags & PERLIO_F_OPEN)
1496 (*PerlIOBase(f)->tab->Close)(f);
1497 if (oflags != -1)
1498 {
adb71456 1499 dTHX;
00b02797 1500 int fd = PerlLIO_open3(path,oflags,0666);
9e353e3b 1501 if (fd >= 0)
1502 {
1503 s->fd = fd;
1504 s->oflags = oflags;
1505 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
1506 return 0;
1507 }
1508 }
1509 return -1;
1510}
1511
1512SSize_t
1513PerlIOUnix_read(PerlIO *f, void *vbuf, Size_t count)
1514{
adb71456 1515 dTHX;
9e353e3b 1516 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
8f24bd79 1517 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
1518 return 0;
9e353e3b 1519 while (1)
1520 {
00b02797 1521 SSize_t len = PerlLIO_read(fd,vbuf,count);
9e353e3b 1522 if (len >= 0 || errno != EINTR)
06da4f11 1523 {
1524 if (len < 0)
1525 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1526 else if (len == 0 && count != 0)
1527 PerlIOBase(f)->flags |= PERLIO_F_EOF;
1528 return len;
1529 }
0a8e0eff 1530 PERL_ASYNC_CHECK();
9e353e3b 1531 }
1532}
1533
1534SSize_t
1535PerlIOUnix_write(PerlIO *f, const void *vbuf, Size_t count)
1536{
adb71456 1537 dTHX;
9e353e3b 1538 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
1539 while (1)
1540 {
00b02797 1541 SSize_t len = PerlLIO_write(fd,vbuf,count);
9e353e3b 1542 if (len >= 0 || errno != EINTR)
06da4f11 1543 {
1544 if (len < 0)
1545 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1546 return len;
1547 }
0a8e0eff 1548 PERL_ASYNC_CHECK();
9e353e3b 1549 }
1550}
1551
1552IV
1553PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence)
1554{
adb71456 1555 dTHX;
00b02797 1556 Off_t new = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence);
06da4f11 1557 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
9e353e3b 1558 return (new == (Off_t) -1) ? -1 : 0;
1559}
1560
1561Off_t
1562PerlIOUnix_tell(PerlIO *f)
1563{
adb71456 1564 dTHX;
766a733e 1565 Off_t posn = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
00b02797 1566 return PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
9e353e3b 1567}
1568
1569IV
1570PerlIOUnix_close(PerlIO *f)
1571{
adb71456 1572 dTHX;
9e353e3b 1573 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
1574 int code = 0;
00b02797 1575 while (PerlLIO_close(fd) != 0)
9e353e3b 1576 {
1577 if (errno != EINTR)
1578 {
1579 code = -1;
1580 break;
1581 }
0a8e0eff 1582 PERL_ASYNC_CHECK();
9e353e3b 1583 }
1584 if (code == 0)
1585 {
1586 PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
1587 }
1588 return code;
1589}
1590
1591PerlIO_funcs PerlIO_unix = {
1592 "unix",
1593 sizeof(PerlIOUnix),
f5b9d040 1594 PERLIO_K_RAW,
9e353e3b 1595 PerlIOUnix_fileno,
1596 PerlIOUnix_fdopen,
1597 PerlIOUnix_open,
1598 PerlIOUnix_reopen,
4b803d04 1599 PerlIOUnix_pushed,
06da4f11 1600 PerlIOBase_noop_ok,
9e353e3b 1601 PerlIOUnix_read,
1602 PerlIOBase_unread,
1603 PerlIOUnix_write,
1604 PerlIOUnix_seek,
1605 PerlIOUnix_tell,
1606 PerlIOUnix_close,
76ced9ad 1607 PerlIOBase_noop_ok, /* flush */
1608 PerlIOBase_noop_fail, /* fill */
9e353e3b 1609 PerlIOBase_eof,
1610 PerlIOBase_error,
1611 PerlIOBase_clearerr,
1612 PerlIOBase_setlinebuf,
1613 NULL, /* get_base */
1614 NULL, /* get_bufsiz */
1615 NULL, /* get_ptr */
1616 NULL, /* get_cnt */
1617 NULL, /* set_ptrcnt */
1618};
1619
1620/*--------------------------------------------------------------------------------------*/
1621/* stdio as a layer */
1622
1623typedef struct
1624{
1625 struct _PerlIO base;
1626 FILE * stdio; /* The stream */
1627} PerlIOStdio;
1628
1629IV
1630PerlIOStdio_fileno(PerlIO *f)
1631{
adb71456 1632 dTHX;
eaf8b698 1633 return PerlSIO_fileno(PerlIOSelf(f,PerlIOStdio)->stdio);
9e353e3b 1634}
1635
766a733e 1636char *
f5b9d040 1637PerlIOStdio_mode(const char *mode,char *tmode)
1638{
766a733e 1639 char *ret = tmode;
1640 while (*mode)
1641 {
1642 *tmode++ = *mode++;
1643 }
f5b9d040 1644 if (O_BINARY != O_TEXT)
1645 {
f5b9d040 1646 *tmode++ = 'b';
f5b9d040 1647 }
766a733e 1648 *tmode = '\0';
f5b9d040 1649 return ret;
1650}
9e353e3b 1651
1652PerlIO *
06da4f11 1653PerlIOStdio_fdopen(PerlIO_funcs *self, int fd,const char *mode)
9e353e3b 1654{
adb71456 1655 dTHX;
9e353e3b 1656 PerlIO *f = NULL;
c7fc522f 1657 int init = 0;
f5b9d040 1658 char tmode[8];
c7fc522f 1659 if (*mode == 'I')
1660 {
1661 init = 1;
1662 mode++;
1663 }
9e353e3b 1664 if (fd >= 0)
1665 {
c7fc522f 1666 FILE *stdio = NULL;
1667 if (init)
1668 {
1669 switch(fd)
1670 {
1671 case 0:
eaf8b698 1672 stdio = PerlSIO_stdin;
c7fc522f 1673 break;
1674 case 1:
eaf8b698 1675 stdio = PerlSIO_stdout;
c7fc522f 1676 break;
1677 case 2:
eaf8b698 1678 stdio = PerlSIO_stderr;
c7fc522f 1679 break;
1680 }
1681 }
1682 else
f5b9d040 1683 {
eaf8b698 1684 stdio = PerlSIO_fdopen(fd,mode = PerlIOStdio_mode(mode,tmode));
f5b9d040 1685 }
9e353e3b 1686 if (stdio)
1687 {
33af2bc7 1688 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode,Nullch,0),PerlIOStdio);
9e353e3b 1689 s->stdio = stdio;
1690 }
1691 }
1692 return f;
1693}
1694
4b803d04 1695/* This isn't used yet ... */
1696IV
1697PerlIOStdio_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
1698{
1699 if (*PerlIONext(f))
1700 {
1701 PerlIOStdio *s = PerlIOSelf(f,PerlIOStdio);
1702 char tmode[8];
1703 FILE *stdio = PerlSIO_fdopen(PerlIO_fileno(PerlIONext(f)),mode = PerlIOStdio_mode(mode,tmode));
1704 if (stdio)
1705 s->stdio = stdio;
1706 else
1707 return -1;
1708 }
1709 return PerlIOBase_pushed(f,mode,arg,len);
1710}
1711
9e353e3b 1712#undef PerlIO_importFILE
1713PerlIO *
1714PerlIO_importFILE(FILE *stdio, int fl)
1715{
5f1a76d0 1716 dTHX;
9e353e3b 1717 PerlIO *f = NULL;
1718 if (stdio)
1719 {
33af2bc7 1720 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),&PerlIO_stdio,"r+",Nullch,0),PerlIOStdio);
9e353e3b 1721 s->stdio = stdio;
1722 }
1723 return f;
1724}
1725
1726PerlIO *
06da4f11 1727PerlIOStdio_open(PerlIO_funcs *self, const char *path,const char *mode)
9e353e3b 1728{
adb71456 1729 dTHX;
9e353e3b 1730 PerlIO *f = NULL;
eaf8b698 1731 FILE *stdio = PerlSIO_fopen(path,mode);
9e353e3b 1732 if (stdio)
1733 {
f5b9d040 1734 char tmode[8];
5f1a76d0 1735 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX), self,
33af2bc7 1736 (mode = PerlIOStdio_mode(mode,tmode)),Nullch,0),
f5b9d040 1737 PerlIOStdio);
9e353e3b 1738 s->stdio = stdio;
1739 }
1740 return f;
760ac839 1741}
1742
6f9d8c32 1743int
9e353e3b 1744PerlIOStdio_reopen(const char *path, const char *mode, PerlIO *f)
1745{
adb71456 1746 dTHX;
9e353e3b 1747 PerlIOStdio *s = PerlIOSelf(f,PerlIOStdio);
f5b9d040 1748 char tmode[8];
eaf8b698 1749 FILE *stdio = PerlSIO_freopen(path,(mode = PerlIOStdio_mode(mode,tmode)),s->stdio);
9e353e3b 1750 if (!s->stdio)
1751 return -1;
1752 s->stdio = stdio;
1753 return 0;
1754}
1755
1756SSize_t
1757PerlIOStdio_read(PerlIO *f, void *vbuf, Size_t count)
1758{
adb71456 1759 dTHX;
9e353e3b 1760 FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
c7fc522f 1761 SSize_t got = 0;
9e353e3b 1762 if (count == 1)
1763 {
1764 STDCHAR *buf = (STDCHAR *) vbuf;
1765 /* Perl is expecting PerlIO_getc() to fill the buffer
1766 * Linux's stdio does not do that for fread()
1767 */
eaf8b698 1768 int ch = PerlSIO_fgetc(s);
9e353e3b 1769 if (ch != EOF)
1770 {
1771 *buf = ch;
c7fc522f 1772 got = 1;
9e353e3b 1773 }
9e353e3b 1774 }
c7fc522f 1775 else
eaf8b698 1776 got = PerlSIO_fread(vbuf,1,count,s);
c7fc522f 1777 return got;
9e353e3b 1778}
1779
1780SSize_t
1781PerlIOStdio_unread(PerlIO *f, const void *vbuf, Size_t count)
1782{
adb71456 1783 dTHX;
9e353e3b 1784 FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
1785 STDCHAR *buf = ((STDCHAR *)vbuf)+count-1;
1786 SSize_t unread = 0;
1787 while (count > 0)
1788 {
1789 int ch = *buf-- & 0xff;
eaf8b698 1790 if (PerlSIO_ungetc(ch,s) != ch)
9e353e3b 1791 break;
1792 unread++;
1793 count--;
1794 }
1795 return unread;
1796}
1797
1798SSize_t
1799PerlIOStdio_write(PerlIO *f, const void *vbuf, Size_t count)
1800{
adb71456 1801 dTHX;
eaf8b698 1802 return PerlSIO_fwrite(vbuf,1,count,PerlIOSelf(f,PerlIOStdio)->stdio);
9e353e3b 1803}
1804
1805IV
1806PerlIOStdio_seek(PerlIO *f, Off_t offset, int whence)
1807{
adb71456 1808 dTHX;
c7fc522f 1809 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
eaf8b698 1810 return PerlSIO_fseek(stdio,offset,whence);
9e353e3b 1811}
1812
1813Off_t
1814PerlIOStdio_tell(PerlIO *f)
1815{
adb71456 1816 dTHX;
c7fc522f 1817 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
eaf8b698 1818 return PerlSIO_ftell(stdio);
9e353e3b 1819}
1820
1821IV
1822PerlIOStdio_close(PerlIO *f)
1823{
adb71456 1824 dTHX;
8e4bc33b 1825#ifdef HAS_SOCKET
cf829ab0 1826 int optval, optlen = sizeof(int);
8e4bc33b 1827#endif
3789aae2 1828 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
cf829ab0 1829 return(
8e4bc33b 1830#ifdef HAS_SOCKET
a4d3c1d3 1831 (getsockopt(PerlIO_fileno(f), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0) ?
eaf8b698 1832 PerlSIO_fclose(stdio) :
8e4bc33b 1833 close(PerlIO_fileno(f))
1834#else
1835 PerlSIO_fclose(stdio)
1836#endif
1837 );
1838
9e353e3b 1839}
1840
1841IV
1842PerlIOStdio_flush(PerlIO *f)
1843{
adb71456 1844 dTHX;
9e353e3b 1845 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
88b61e10 1846 if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE)
1847 {
eaf8b698 1848 return PerlSIO_fflush(stdio);
88b61e10 1849 }
1850 else
1851 {
1852#if 0
1853 /* FIXME: This discards ungetc() and pre-read stuff which is
1854 not right if this is just a "sync" from a layer above
1855 Suspect right design is to do _this_ but not have layer above
1856 flush this layer read-to-read
1857 */
1858 /* Not writeable - sync by attempting a seek */
1859 int err = errno;
eaf8b698 1860 if (PerlSIO_fseek(stdio,(Off_t) 0, SEEK_CUR) != 0)
88b61e10 1861 errno = err;
1862#endif
1863 }
1864 return 0;
9e353e3b 1865}
1866
1867IV
06da4f11 1868PerlIOStdio_fill(PerlIO *f)
1869{
adb71456 1870 dTHX;
06da4f11 1871 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1872 int c;
3789aae2 1873 /* fflush()ing read-only streams can cause trouble on some stdio-s */
1874 if ((PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
1875 {
eaf8b698 1876 if (PerlSIO_fflush(stdio) != 0)
3789aae2 1877 return EOF;
1878 }
eaf8b698 1879 c = PerlSIO_fgetc(stdio);
1880 if (c == EOF || PerlSIO_ungetc(c,stdio) != c)
06da4f11 1881 return EOF;
1882 return 0;
1883}
1884
1885IV
9e353e3b 1886PerlIOStdio_eof(PerlIO *f)
1887{
adb71456 1888 dTHX;
eaf8b698 1889 return PerlSIO_feof(PerlIOSelf(f,PerlIOStdio)->stdio);
9e353e3b 1890}
1891
1892IV
1893PerlIOStdio_error(PerlIO *f)
1894{
adb71456 1895 dTHX;
eaf8b698 1896 return PerlSIO_ferror(PerlIOSelf(f,PerlIOStdio)->stdio);
9e353e3b 1897}
1898
1899void
1900PerlIOStdio_clearerr(PerlIO *f)
1901{
adb71456 1902 dTHX;
eaf8b698 1903 PerlSIO_clearerr(PerlIOSelf(f,PerlIOStdio)->stdio);
9e353e3b 1904}
1905
1906void
1907PerlIOStdio_setlinebuf(PerlIO *f)
1908{
adb71456 1909 dTHX;
9e353e3b 1910#ifdef HAS_SETLINEBUF
eaf8b698 1911 PerlSIO_setlinebuf(PerlIOSelf(f,PerlIOStdio)->stdio);
9e353e3b 1912#else
eaf8b698 1913 PerlSIO_setvbuf(PerlIOSelf(f,PerlIOStdio)->stdio, Nullch, _IOLBF, 0);
9e353e3b 1914#endif
1915}
1916
1917#ifdef FILE_base
1918STDCHAR *
1919PerlIOStdio_get_base(PerlIO *f)
1920{
adb71456 1921 dTHX;
9e353e3b 1922 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
eaf8b698 1923 return PerlSIO_get_base(stdio);
9e353e3b 1924}
1925
1926Size_t
1927PerlIOStdio_get_bufsiz(PerlIO *f)
1928{
adb71456 1929 dTHX;
9e353e3b 1930 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
eaf8b698 1931 return PerlSIO_get_bufsiz(stdio);
9e353e3b 1932}
1933#endif
1934
1935#ifdef USE_STDIO_PTR
1936STDCHAR *
1937PerlIOStdio_get_ptr(PerlIO *f)
1938{
adb71456 1939 dTHX;
9e353e3b 1940 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
eaf8b698 1941 return PerlSIO_get_ptr(stdio);
9e353e3b 1942}
1943
1944SSize_t
1945PerlIOStdio_get_cnt(PerlIO *f)
1946{
adb71456 1947 dTHX;
9e353e3b 1948 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
eaf8b698 1949 return PerlSIO_get_cnt(stdio);
9e353e3b 1950}
1951
1952void
1953PerlIOStdio_set_ptrcnt(PerlIO *f,STDCHAR *ptr,SSize_t cnt)
1954{
adb71456 1955 dTHX;
9e353e3b 1956 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1957 if (ptr != NULL)
1958 {
1959#ifdef STDIO_PTR_LVALUE
eaf8b698 1960 PerlSIO_set_ptr(stdio,ptr);
9e353e3b 1961#ifdef STDIO_PTR_LVAL_SETS_CNT
eaf8b698 1962 if (PerlSIO_get_cnt(stdio) != (cnt))
9e353e3b 1963 {
1964 dTHX;
eaf8b698 1965 assert(PerlSIO_get_cnt(stdio) == (cnt));
9e353e3b 1966 }
1967#endif
1968#if (!defined(STDIO_PTR_LVAL_NOCHANGE_CNT))
1969 /* Setting ptr _does_ change cnt - we are done */
1970 return;
1971#endif
1972#else /* STDIO_PTR_LVALUE */
eaf8b698 1973 PerlProc_abort();
9e353e3b 1974#endif /* STDIO_PTR_LVALUE */
1975 }
1976/* Now (or only) set cnt */
1977#ifdef STDIO_CNT_LVALUE
eaf8b698 1978 PerlSIO_set_cnt(stdio,cnt);
9e353e3b 1979#else /* STDIO_CNT_LVALUE */
1980#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
eaf8b698 1981 PerlSIO_set_ptr(stdio,PerlSIO_get_ptr(stdio)+(PerlSIO_get_cnt(stdio)-cnt));
9e353e3b 1982#else /* STDIO_PTR_LVAL_SETS_CNT */
eaf8b698 1983 PerlProc_abort();
9e353e3b 1984#endif /* STDIO_PTR_LVAL_SETS_CNT */
1985#endif /* STDIO_CNT_LVALUE */
1986}
1987
1988#endif
1989
1990PerlIO_funcs PerlIO_stdio = {
1991 "stdio",
1992 sizeof(PerlIOStdio),
f5b9d040 1993 PERLIO_K_BUFFERED,
9e353e3b 1994 PerlIOStdio_fileno,
1995 PerlIOStdio_fdopen,
1996 PerlIOStdio_open,
1997 PerlIOStdio_reopen,
06da4f11 1998 PerlIOBase_pushed,
1999 PerlIOBase_noop_ok,
9e353e3b 2000 PerlIOStdio_read,
2001 PerlIOStdio_unread,
2002 PerlIOStdio_write,
2003 PerlIOStdio_seek,
2004 PerlIOStdio_tell,
2005 PerlIOStdio_close,
2006 PerlIOStdio_flush,
06da4f11 2007 PerlIOStdio_fill,
9e353e3b 2008 PerlIOStdio_eof,
2009 PerlIOStdio_error,
2010 PerlIOStdio_clearerr,
2011 PerlIOStdio_setlinebuf,
2012#ifdef FILE_base
2013 PerlIOStdio_get_base,
2014 PerlIOStdio_get_bufsiz,
2015#else
2016 NULL,
2017 NULL,
2018#endif
2019#ifdef USE_STDIO_PTR
2020 PerlIOStdio_get_ptr,
2021 PerlIOStdio_get_cnt,
0eb1d8a4 2022#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
9e353e3b 2023 PerlIOStdio_set_ptrcnt
2024#else /* STDIO_PTR_LVALUE */
2025 NULL
2026#endif /* STDIO_PTR_LVALUE */
2027#else /* USE_STDIO_PTR */
2028 NULL,
2029 NULL,
2030 NULL
2031#endif /* USE_STDIO_PTR */
2032};
2033
2034#undef PerlIO_exportFILE
2035FILE *
2036PerlIO_exportFILE(PerlIO *f, int fl)
2037{
f7e7eb72 2038 FILE *stdio;
9e353e3b 2039 PerlIO_flush(f);
f7e7eb72 2040 stdio = fdopen(PerlIO_fileno(f),"r+");
2041 if (stdio)
2042 {
2043 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f,&PerlIO_stdio,"r+",Nullch,0),PerlIOStdio);
2044 s->stdio = stdio;
2045 }
2046 return stdio;
9e353e3b 2047}
2048
2049#undef PerlIO_findFILE
2050FILE *
2051PerlIO_findFILE(PerlIO *f)
2052{
f7e7eb72 2053 PerlIOl *l = *f;
2054 while (l)
2055 {
2056 if (l->tab == &PerlIO_stdio)
2057 {
2058 PerlIOStdio *s = PerlIOSelf(&l,PerlIOStdio);
2059 return s->stdio;
2060 }
2061 l = *PerlIONext(&l);
2062 }
9e353e3b 2063 return PerlIO_exportFILE(f,0);
2064}
2065
2066#undef PerlIO_releaseFILE
2067void
2068PerlIO_releaseFILE(PerlIO *p, FILE *f)
2069{
2070}
2071
2072/*--------------------------------------------------------------------------------------*/
2073/* perlio buffer layer */
2074
5e2ab84b 2075IV
33af2bc7 2076PerlIOBuf_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
5e2ab84b 2077{
2078 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2079 b->posn = PerlIO_tell(PerlIONext(f));
33af2bc7 2080 return PerlIOBase_pushed(f,mode,arg,len);
5e2ab84b 2081}
2082
9e353e3b 2083PerlIO *
06da4f11 2084PerlIOBuf_fdopen(PerlIO_funcs *self, int fd, const char *mode)
9e353e3b 2085{
adb71456 2086 dTHX;
9e353e3b 2087 PerlIO_funcs *tab = PerlIO_default_btm();
c7fc522f 2088 int init = 0;
2089 PerlIO *f;
2090 if (*mode == 'I')
2091 {
2092 init = 1;
2093 mode++;
a77df51f 2094 }
10cbe18a 2095#if O_BINARY != O_TEXT
a4d3c1d3 2096 /* do something about failing setmode()? --jhi */
2097 PerlLIO_setmode(fd, O_BINARY);
10cbe18a 2098#endif
06da4f11 2099 f = (*tab->Fdopen)(tab,fd,mode);
6f9d8c32 2100 if (f)
2101 {
33af2bc7 2102 PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,mode,Nullch,0),PerlIOBuf);
f5b9d040 2103 if (init && fd == 2)
c7fc522f 2104 {
f5b9d040 2105 /* Initial stderr is unbuffered */
2106 PerlIOBase(f)->flags |= PERLIO_F_UNBUF;
a4d3c1d3 2107 }
5e2ab84b 2108#if 0
4659c93f 2109 PerlIO_debug("PerlIOBuf_fdopen %s f=%p fd=%d m=%s fl=%08"UVxf"\n",
f5b9d040 2110 self->name,f,fd,mode,PerlIOBase(f)->flags);
5e2ab84b 2111#endif
6f9d8c32 2112 }
9e353e3b 2113 return f;
760ac839 2114}
2115
9e353e3b 2116PerlIO *
06da4f11 2117PerlIOBuf_open(PerlIO_funcs *self, const char *path, const char *mode)
8c86a920 2118{
9e353e3b 2119 PerlIO_funcs *tab = PerlIO_default_btm();
06da4f11 2120 PerlIO *f = (*tab->Open)(tab,path,mode);
9e353e3b 2121 if (f)
2122 {
33af2bc7 2123 PerlIO_push(f,self,mode,Nullch,0);
9e353e3b 2124 }
2125 return f;
2126}
2127
2128int
c3d7c7c9 2129PerlIOBuf_reopen(const char *path, const char *mode, PerlIO *f)
9e353e3b 2130{
c3d7c7c9 2131 PerlIO *next = PerlIONext(f);
2132 int code = (*PerlIOBase(next)->tab->Reopen)(path,mode,next);
2133 if (code = 0)
33af2bc7 2134 code = (*PerlIOBase(f)->tab->Pushed)(f,mode,Nullch,0);
c3d7c7c9 2135 return code;
9e353e3b 2136}
2137
9e353e3b 2138/* This "flush" is akin to sfio's sync in that it handles files in either
2139 read or write state
2140*/
2141IV
2142PerlIOBuf_flush(PerlIO *f)
6f9d8c32 2143{
9e353e3b 2144 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2145 int code = 0;
2146 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
2147 {
2148 /* write() the buffer */
a5262162 2149 STDCHAR *buf = b->buf;
33af2bc7 2150 STDCHAR *p = buf;
3789aae2 2151 PerlIO *n = PerlIONext(f);
9e353e3b 2152 while (p < b->ptr)
2153 {
4b803d04 2154 SSize_t count = PerlIO_write(n,p,b->ptr - p);
9e353e3b 2155 if (count > 0)
2156 {
2157 p += count;
2158 }
3789aae2 2159 else if (count < 0 || PerlIO_error(n))
9e353e3b 2160 {
2161 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
2162 code = -1;
2163 break;
2164 }
2165 }
33af2bc7 2166 b->posn += (p - buf);
9e353e3b 2167 }
2168 else if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
6f9d8c32 2169 {
33af2bc7 2170 STDCHAR *buf = PerlIO_get_base(f);
9e353e3b 2171 /* Note position change */
33af2bc7 2172 b->posn += (b->ptr - buf);
9e353e3b 2173 if (b->ptr < b->end)
2174 {
2175 /* We did not consume all of it */
2176 if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) == 0)
2177 {
2178 b->posn = PerlIO_tell(PerlIONext(f));
2179 }
2180 }
6f9d8c32 2181 }
9e353e3b 2182 b->ptr = b->end = b->buf;
2183 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
88b61e10 2184 /* FIXME: Is this right for read case ? */
9e353e3b 2185 if (PerlIO_flush(PerlIONext(f)) != 0)
2186 code = -1;
2187 return code;
6f9d8c32 2188}
2189
06da4f11 2190IV
2191PerlIOBuf_fill(PerlIO *f)
2192{
2193 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
88b61e10 2194 PerlIO *n = PerlIONext(f);
06da4f11 2195 SSize_t avail;
88b61e10 2196 /* FIXME: doing the down-stream flush is a bad idea if it causes
2197 pre-read data in stdio buffer to be discarded
2198 but this is too simplistic - as it skips _our_ hosekeeping
2199 and breaks tell tests.
2200 if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
2201 {
2202 }
2203 */
06da4f11 2204 if (PerlIO_flush(f) != 0)
2205 return -1;
88b61e10 2206
a5262162 2207 if (!b->buf)
2208 PerlIO_get_base(f); /* allocate via vtable */
2209
2210 b->ptr = b->end = b->buf;
88b61e10 2211 if (PerlIO_fast_gets(n))
2212 {
2213 /* Layer below is also buffered
2214 * We do _NOT_ want to call its ->Read() because that will loop
2215 * till it gets what we asked for which may hang on a pipe etc.
2216 * Instead take anything it has to hand, or ask it to fill _once_.
2217 */
2218 avail = PerlIO_get_cnt(n);
2219 if (avail <= 0)
2220 {
2221 avail = PerlIO_fill(n);
2222 if (avail == 0)
2223 avail = PerlIO_get_cnt(n);
2224 else
2225 {
2226 if (!PerlIO_error(n) && PerlIO_eof(n))
2227 avail = 0;
2228 }
2229 }
2230 if (avail > 0)
2231 {
2232 STDCHAR *ptr = PerlIO_get_ptr(n);
2233 SSize_t cnt = avail;
2234 if (avail > b->bufsiz)
2235 avail = b->bufsiz;
2236 Copy(ptr,b->buf,avail,STDCHAR);
2237 PerlIO_set_ptrcnt(n,ptr+avail,cnt-avail);
2238 }
2239 }
2240 else
2241 {
2242 avail = PerlIO_read(n,b->ptr,b->bufsiz);
2243 }
06da4f11 2244 if (avail <= 0)
2245 {
2246 if (avail == 0)
2247 PerlIOBase(f)->flags |= PERLIO_F_EOF;
2248 else
2249 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
2250 return -1;
2251 }
a5262162 2252 b->end = b->buf+avail;
06da4f11 2253 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
2254 return 0;
2255}
2256
6f9d8c32 2257SSize_t
9e353e3b 2258PerlIOBuf_read(PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 2259{
99efab12 2260 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2261 STDCHAR *buf = (STDCHAR *) vbuf;
6f9d8c32 2262 if (f)
2263 {
9e353e3b 2264 if (!b->ptr)
06da4f11 2265 PerlIO_get_base(f);
9e353e3b 2266 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
f89522bf 2267 return 0;
6f9d8c32 2268 while (count > 0)
2269 {
99efab12 2270 SSize_t avail = PerlIO_get_cnt(f);
60382766 2271 SSize_t take = (count < avail) ? count : avail;
99efab12 2272 if (take > 0)
6f9d8c32 2273 {
99efab12 2274 STDCHAR *ptr = PerlIO_get_ptr(f);
2275 Copy(ptr,buf,take,STDCHAR);
2276 PerlIO_set_ptrcnt(f,ptr+take,(avail -= take));
2277 count -= take;
2278 buf += take;
6f9d8c32 2279 }
99efab12 2280 if (count > 0 && avail <= 0)
6f9d8c32 2281 {
06da4f11 2282 if (PerlIO_fill(f) != 0)
2283 break;
6f9d8c32 2284 }
2285 }
99efab12 2286 return (buf - (STDCHAR *) vbuf);
6f9d8c32 2287 }
2288 return 0;
2289}
2290
9e353e3b 2291SSize_t
2292PerlIOBuf_unread(PerlIO *f, const void *vbuf, Size_t count)
760ac839 2293{
9e353e3b 2294 const STDCHAR *buf = (const STDCHAR *) vbuf+count;
2295 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2296 SSize_t unread = 0;
2297 SSize_t avail;
9e353e3b 2298 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
2299 PerlIO_flush(f);
06da4f11 2300 if (!b->buf)
2301 PerlIO_get_base(f);
9e353e3b 2302 if (b->buf)
2303 {
2304 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
2305 {
2306 avail = (b->ptr - b->buf);
9e353e3b 2307 }
2308 else
2309 {
2310 avail = b->bufsiz;
5e2ab84b 2311 b->end = b->buf + avail;
2312 b->ptr = b->end;
2313 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
2314 b->posn -= b->bufsiz;
9e353e3b 2315 }
5e2ab84b 2316 if (avail > (SSize_t) count)
2317 avail = count;
9e353e3b 2318 if (avail > 0)
2319 {
5e2ab84b 2320 b->ptr -= avail;
9e353e3b 2321 buf -= avail;
2322 if (buf != b->ptr)
2323 {
88b61e10 2324 Copy(buf,b->ptr,avail,STDCHAR);
9e353e3b 2325 }
2326 count -= avail;
2327 unread += avail;
2328 PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
2329 }
2330 }
2331 return unread;
760ac839 2332}
2333
9e353e3b 2334SSize_t
2335PerlIOBuf_write(PerlIO *f, const void *vbuf, Size_t count)
760ac839 2336{
9e353e3b 2337 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2338 const STDCHAR *buf = (const STDCHAR *) vbuf;
2339 Size_t written = 0;
2340 if (!b->buf)
06da4f11 2341 PerlIO_get_base(f);
9e353e3b 2342 if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
2343 return 0;
2344 while (count > 0)
2345 {
2346 SSize_t avail = b->bufsiz - (b->ptr - b->buf);
2347 if ((SSize_t) count < avail)
2348 avail = count;
2349 PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
2350 if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF)
2351 {
2352 while (avail > 0)
2353 {
2354 int ch = *buf++;
2355 *(b->ptr)++ = ch;
2356 count--;
2357 avail--;
2358 written++;
2359 if (ch == '\n')
2360 {
2361 PerlIO_flush(f);
2362 break;
2363 }
2364 }
2365 }
2366 else
2367 {
2368 if (avail)
2369 {
88b61e10 2370 Copy(buf,b->ptr,avail,STDCHAR);
9e353e3b 2371 count -= avail;
2372 buf += avail;
2373 written += avail;
2374 b->ptr += avail;
2375 }
2376 }
2377 if (b->ptr >= (b->buf + b->bufsiz))
2378 PerlIO_flush(f);
2379 }
f5b9d040 2380 if (PerlIOBase(f)->flags & PERLIO_F_UNBUF)
2381 PerlIO_flush(f);
9e353e3b 2382 return written;
2383}
2384
2385IV
2386PerlIOBuf_seek(PerlIO *f, Off_t offset, int whence)
2387{
5e2ab84b 2388 IV code;
2389 if ((code = PerlIO_flush(f)) == 0)
9e353e3b 2390 {
5e2ab84b 2391 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
9e353e3b 2392 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
2393 code = PerlIO_seek(PerlIONext(f),offset,whence);
2394 if (code == 0)
2395 {
2396 b->posn = PerlIO_tell(PerlIONext(f));
2397 }
2398 }
2399 return code;
2400}
2401
2402Off_t
2403PerlIOBuf_tell(PerlIO *f)
2404{
2405 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2406 Off_t posn = b->posn;
2407 if (b->buf)
2408 posn += (b->ptr - b->buf);
2409 return posn;
2410}
2411
2412IV
2413PerlIOBuf_close(PerlIO *f)
2414{
5f1a76d0 2415 dTHX;
9e353e3b 2416 IV code = PerlIOBase_close(f);
2417 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2418 if (b->buf && b->buf != (STDCHAR *) &b->oneword)
6f9d8c32 2419 {
5f1a76d0 2420 PerlMemShared_free(b->buf);
6f9d8c32 2421 }
9e353e3b 2422 b->buf = NULL;
2423 b->ptr = b->end = b->buf;
2424 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
2425 return code;
760ac839 2426}
2427
760ac839 2428void
9e353e3b 2429PerlIOBuf_setlinebuf(PerlIO *f)
760ac839 2430{
6f9d8c32 2431 if (f)
2432 {
9e353e3b 2433 PerlIOBase(f)->flags &= ~PERLIO_F_LINEBUF;
6f9d8c32 2434 }
760ac839 2435}
2436
9e353e3b 2437STDCHAR *
2438PerlIOBuf_get_ptr(PerlIO *f)
2439{
2440 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2441 if (!b->buf)
06da4f11 2442 PerlIO_get_base(f);
9e353e3b 2443 return b->ptr;
2444}
2445
05d1247b 2446SSize_t
9e353e3b 2447PerlIOBuf_get_cnt(PerlIO *f)
2448{
2449 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2450 if (!b->buf)
06da4f11 2451 PerlIO_get_base(f);
9e353e3b 2452 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
2453 return (b->end - b->ptr);
2454 return 0;
2455}
2456
2457STDCHAR *
2458PerlIOBuf_get_base(PerlIO *f)
2459{
2460 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2461 if (!b->buf)
06da4f11 2462 {
5f1a76d0 2463 dTHX;
06da4f11 2464 if (!b->bufsiz)
2465 b->bufsiz = 4096;
5f1a76d0 2466 b->buf = PerlMemShared_calloc(b->bufsiz,sizeof(STDCHAR));
06da4f11 2467 if (!b->buf)
2468 {
2469 b->buf = (STDCHAR *)&b->oneword;
2470 b->bufsiz = sizeof(b->oneword);
2471 }
2472 b->ptr = b->buf;
2473 b->end = b->ptr;
2474 }
9e353e3b 2475 return b->buf;
2476}
2477
2478Size_t
2479PerlIOBuf_bufsiz(PerlIO *f)
2480{
2481 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2482 if (!b->buf)
06da4f11 2483 PerlIO_get_base(f);
9e353e3b 2484 return (b->end - b->buf);
2485}
2486
2487void
05d1247b 2488PerlIOBuf_set_ptrcnt(PerlIO *f, STDCHAR *ptr, SSize_t cnt)
9e353e3b 2489{
2490 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2491 if (!b->buf)
06da4f11 2492 PerlIO_get_base(f);
9e353e3b 2493 b->ptr = ptr;
2494 if (PerlIO_get_cnt(f) != cnt || b->ptr < b->buf)
6f9d8c32 2495 {
9e353e3b 2496 dTHX;
2497 assert(PerlIO_get_cnt(f) == cnt);
2498 assert(b->ptr >= b->buf);
6f9d8c32 2499 }
9e353e3b 2500 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
760ac839 2501}
2502
9e353e3b 2503PerlIO_funcs PerlIO_perlio = {
2504 "perlio",
2505 sizeof(PerlIOBuf),
f5b9d040 2506 PERLIO_K_BUFFERED,
9e353e3b 2507 PerlIOBase_fileno,
2508 PerlIOBuf_fdopen,
2509 PerlIOBuf_open,
c3d7c7c9 2510 PerlIOBuf_reopen,
5e2ab84b 2511 PerlIOBuf_pushed,
06da4f11 2512 PerlIOBase_noop_ok,
9e353e3b 2513 PerlIOBuf_read,
2514 PerlIOBuf_unread,
2515 PerlIOBuf_write,
2516 PerlIOBuf_seek,
2517 PerlIOBuf_tell,
2518 PerlIOBuf_close,
2519 PerlIOBuf_flush,
06da4f11 2520 PerlIOBuf_fill,
9e353e3b 2521 PerlIOBase_eof,
2522 PerlIOBase_error,
2523 PerlIOBase_clearerr,
2524 PerlIOBuf_setlinebuf,
2525 PerlIOBuf_get_base,
2526 PerlIOBuf_bufsiz,
2527 PerlIOBuf_get_ptr,
2528 PerlIOBuf_get_cnt,
2529 PerlIOBuf_set_ptrcnt,
2530};
2531
66ecd56b 2532/*--------------------------------------------------------------------------------------*/
5e2ab84b 2533/* Temp layer to hold unread chars when cannot do it any other way */
2534
2535IV
2536PerlIOPending_fill(PerlIO *f)
2537{
2538 /* Should never happen */
2539 PerlIO_flush(f);
2540 return 0;
2541}
2542
2543IV
2544PerlIOPending_close(PerlIO *f)
2545{
2546 /* A tad tricky - flush pops us, then we close new top */
2547 PerlIO_flush(f);
2548 return PerlIO_close(f);
2549}
2550
2551IV
2552PerlIOPending_seek(PerlIO *f, Off_t offset, int whence)
2553{
2554 /* A tad tricky - flush pops us, then we seek new top */
2555 PerlIO_flush(f);
2556 return PerlIO_seek(f,offset,whence);
2557}
2558
2559
2560IV
2561PerlIOPending_flush(PerlIO *f)
2562{
2563 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2564 if (b->buf && b->buf != (STDCHAR *) &b->oneword)
2565 {
5f1a76d0 2566 dTHX;
2567 PerlMemShared_free(b->buf);
5e2ab84b 2568 b->buf = NULL;
2569 }
2570 PerlIO_pop(f);
2571 return 0;
2572}
2573
2574void
2575PerlIOPending_set_ptrcnt(PerlIO *f, STDCHAR *ptr, SSize_t cnt)
2576{
2577 if (cnt <= 0)
2578 {
2579 PerlIO_flush(f);
2580 }
2581 else
2582 {
2583 PerlIOBuf_set_ptrcnt(f,ptr,cnt);
2584 }
2585}
2586
2587IV
33af2bc7 2588PerlIOPending_pushed(PerlIO *f,const char *mode,const char *arg,STRLEN len)
5e2ab84b 2589{
72e44f29 2590 IV code = PerlIOBase_pushed(f,mode,arg,len);
5e2ab84b 2591 PerlIOl *l = PerlIOBase(f);
2592 /* Our PerlIO_fast_gets must match what we are pushed on,
2593 or sv_gets() etc. get muddled when it changes mid-string
2594 when we auto-pop.
2595 */
72e44f29 2596 l->flags = (l->flags & ~(PERLIO_F_FASTGETS|PERLIO_F_UTF8)) |
2597 (PerlIOBase(PerlIONext(f))->flags & (PERLIO_F_FASTGETS|PERLIO_F_UTF8));
5e2ab84b 2598 return code;
2599}
2600
2601SSize_t
2602PerlIOPending_read(PerlIO *f, void *vbuf, Size_t count)
2603{
2604 SSize_t avail = PerlIO_get_cnt(f);
2605 SSize_t got = 0;
2606 if (count < avail)
2607 avail = count;
2608 if (avail > 0)
2609 got = PerlIOBuf_read(f,vbuf,avail);
2610 if (got < count)
2611 got += PerlIO_read(f,((STDCHAR *) vbuf)+got,count-got);
2612 return got;
2613}
2614
2615
2616PerlIO_funcs PerlIO_pending = {
2617 "pending",
2618 sizeof(PerlIOBuf),
2619 PERLIO_K_BUFFERED,
2620 PerlIOBase_fileno,
2621 NULL,
2622 NULL,
2623 NULL,
2624 PerlIOPending_pushed,
2625 PerlIOBase_noop_ok,
2626 PerlIOPending_read,
2627 PerlIOBuf_unread,
2628 PerlIOBuf_write,
2629 PerlIOPending_seek,
2630 PerlIOBuf_tell,
2631 PerlIOPending_close,
2632 PerlIOPending_flush,
2633 PerlIOPending_fill,
2634 PerlIOBase_eof,
2635 PerlIOBase_error,
2636 PerlIOBase_clearerr,
2637 PerlIOBuf_setlinebuf,
2638 PerlIOBuf_get_base,
2639 PerlIOBuf_bufsiz,
2640 PerlIOBuf_get_ptr,
2641 PerlIOBuf_get_cnt,
2642 PerlIOPending_set_ptrcnt,
2643};
2644
2645
2646
2647/*--------------------------------------------------------------------------------------*/
99efab12 2648/* crlf - translation
2649 On read translate CR,LF to "\n" we do this by overriding ptr/cnt entries
60382766 2650 to hand back a line at a time and keeping a record of which nl we "lied" about.
99efab12 2651 On write translate "\n" to CR,LF
66ecd56b 2652 */
2653
99efab12 2654typedef struct
2655{
2656 PerlIOBuf base; /* PerlIOBuf stuff */
60382766 2657 STDCHAR *nl; /* Position of crlf we "lied" about in the buffer */
99efab12 2658} PerlIOCrlf;
2659
f5b9d040 2660IV
33af2bc7 2661PerlIOCrlf_pushed(PerlIO *f, const char *mode,const char *arg,STRLEN len)
f5b9d040 2662{
2663 IV code;
2664 PerlIOBase(f)->flags |= PERLIO_F_CRLF;
33af2bc7 2665 code = PerlIOBuf_pushed(f,mode,arg,len);
5e2ab84b 2666#if 0
4659c93f 2667 PerlIO_debug("PerlIOCrlf_pushed f=%p %s %s fl=%08"UVxf"\n",
f5b9d040 2668 f,PerlIOBase(f)->tab->name,(mode) ? mode : "(Null)",
a4d3c1d3 2669 PerlIOBase(f)->flags);
5e2ab84b 2670#endif
f5b9d040 2671 return code;
2672}
2673
2674
99efab12 2675SSize_t
2676PerlIOCrlf_unread(PerlIO *f, const void *vbuf, Size_t count)
2677{
60382766 2678 PerlIOCrlf *c = PerlIOSelf(f,PerlIOCrlf);
60382766 2679 if (c->nl)
2680 {
2681 *(c->nl) = 0xd;
2682 c->nl = NULL;
2683 }
f5b9d040 2684 if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF))
2685 return PerlIOBuf_unread(f,vbuf,count);
2686 else
99efab12 2687 {
a4d3c1d3 2688 const STDCHAR *buf = (const STDCHAR *) vbuf+count;
f5b9d040 2689 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2690 SSize_t unread = 0;
2691 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
2692 PerlIO_flush(f);
2693 if (!b->buf)
2694 PerlIO_get_base(f);
2695 if (b->buf)
99efab12 2696 {
f5b9d040 2697 if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
99efab12 2698 {
f5b9d040 2699 b->end = b->ptr = b->buf + b->bufsiz;
2700 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
5e2ab84b 2701 b->posn -= b->bufsiz;
f5b9d040 2702 }
2703 while (count > 0 && b->ptr > b->buf)
2704 {
2705 int ch = *--buf;
2706 if (ch == '\n')
99efab12 2707 {
f5b9d040 2708 if (b->ptr - 2 >= b->buf)
2709 {
2710 *--(b->ptr) = 0xa;
2711 *--(b->ptr) = 0xd;
2712 unread++;
2713 count--;
2714 }
2715 else
2716 {
2717 buf++;
2718 break;
2719 }
99efab12 2720 }
2721 else
2722 {
f5b9d040 2723 *--(b->ptr) = ch;
2724 unread++;
2725 count--;
99efab12 2726 }
2727 }
99efab12 2728 }
f5b9d040 2729 return unread;
99efab12 2730 }
99efab12 2731}
2732
2733SSize_t
2734PerlIOCrlf_get_cnt(PerlIO *f)
2735{
2736 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2737 if (!b->buf)
2738 PerlIO_get_base(f);
2739 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
2740 {
2741 PerlIOCrlf *c = PerlIOSelf(f,PerlIOCrlf);
f5b9d040 2742 if ((PerlIOBase(f)->flags & PERLIO_F_CRLF) && !c->nl)
99efab12 2743 {
2744 STDCHAR *nl = b->ptr;
60382766 2745 scan:
99efab12 2746 while (nl < b->end && *nl != 0xd)
2747 nl++;
2748 if (nl < b->end && *nl == 0xd)
2749 {
60382766 2750 test:
99efab12 2751 if (nl+1 < b->end)
2752 {
2753 if (nl[1] == 0xa)
2754 {
2755 *nl = '\n';
60382766 2756 c->nl = nl;
99efab12 2757 }
60382766 2758 else
99efab12 2759 {
2760 /* Not CR,LF but just CR */
2761 nl++;
60382766 2762 goto scan;
99efab12 2763 }
2764 }
2765 else
2766 {
60382766 2767 /* Blast - found CR as last char in buffer */
99efab12 2768 if (b->ptr < nl)
2769 {
2770 /* They may not care, defer work as long as possible */
60382766 2771 return (nl - b->ptr);
99efab12 2772 }
2773 else
2774 {
2775 int code;
2776 dTHX;
99efab12 2777 b->ptr++; /* say we have read it as far as flush() is concerned */
2778 b->buf++; /* Leave space an front of buffer */
2779 b->bufsiz--; /* Buffer is thus smaller */
2780 code = PerlIO_fill(f); /* Fetch some more */
2781 b->bufsiz++; /* Restore size for next time */
2782 b->buf--; /* Point at space */
2783 b->ptr = nl = b->buf; /* Which is what we hand off */
2784 b->posn--; /* Buffer starts here */
2785 *nl = 0xd; /* Fill in the CR */
60382766 2786 if (code == 0)
99efab12 2787 goto test; /* fill() call worked */
2788 /* CR at EOF - just fall through */
2789 }
2790 }
60382766 2791 }
2792 }
99efab12 2793 return (((c->nl) ? (c->nl+1) : b->end) - b->ptr);
2794 }
2795 return 0;
2796}
2797
2798void
2799PerlIOCrlf_set_ptrcnt(PerlIO *f, STDCHAR *ptr, SSize_t cnt)
2800{
2801 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2802 PerlIOCrlf *c = PerlIOSelf(f,PerlIOCrlf);
f5b9d040 2803 IV flags = PerlIOBase(f)->flags;
99efab12 2804 if (!b->buf)
2805 PerlIO_get_base(f);
2806 if (!ptr)
60382766 2807 {
63dbdb06 2808 if (c->nl)
2809 ptr = c->nl+1;
2810 else
2811 {
2812 ptr = b->end;
f5b9d040 2813 if ((flags & PERLIO_F_CRLF) && ptr > b->buf && ptr[-1] == 0xd)
63dbdb06 2814 ptr--;
2815 }
2816 ptr -= cnt;
60382766 2817 }
2818 else
2819 {
63dbdb06 2820 /* Test code - delete when it works ... */
2821 STDCHAR *chk;
2822 if (c->nl)
2823 chk = c->nl+1;
2824 else
2825 {
2826 chk = b->end;
f5b9d040 2827 if ((flags & PERLIO_F_CRLF) && chk > b->buf && chk[-1] == 0xd)
63dbdb06 2828 chk--;
2829 }
2830 chk -= cnt;
a4d3c1d3 2831
63dbdb06 2832 if (ptr != chk)
2833 {
2834 dTHX;
4659c93f 2835 Perl_croak(aTHX_ "ptr wrong %p != %p fl=%08"UVxf" nl=%p e=%p for %d",
a4d3c1d3 2836 ptr, chk, flags, c->nl, b->end, cnt);
63dbdb06 2837 }
60382766 2838 }
99efab12 2839 if (c->nl)
2840 {
2841 if (ptr > c->nl)
2842 {
2843 /* They have taken what we lied about */
2844 *(c->nl) = 0xd;
2845 c->nl = NULL;
2846 ptr++;
60382766 2847 }
99efab12 2848 }
2849 b->ptr = ptr;
2850 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
2851}
2852
2853SSize_t
2854PerlIOCrlf_write(PerlIO *f, const void *vbuf, Size_t count)
2855{
f5b9d040 2856 if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF))
2857 return PerlIOBuf_write(f,vbuf,count);
2858 else
99efab12 2859 {
a4d3c1d3 2860 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
f5b9d040 2861 const STDCHAR *buf = (const STDCHAR *) vbuf;
2862 const STDCHAR *ebuf = buf+count;
2863 if (!b->buf)
2864 PerlIO_get_base(f);
2865 if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
2866 return 0;
2867 while (buf < ebuf)
99efab12 2868 {
f5b9d040 2869 STDCHAR *eptr = b->buf+b->bufsiz;
2870 PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
2871 while (buf < ebuf && b->ptr < eptr)
99efab12 2872 {
f5b9d040 2873 if (*buf == '\n')
60382766 2874 {
f5b9d040 2875 if ((b->ptr + 2) > eptr)
60382766 2876 {
f5b9d040 2877 /* Not room for both */
60382766 2878 PerlIO_flush(f);
2879 break;
2880 }
f5b9d040 2881 else
2882 {
2883 *(b->ptr)++ = 0xd; /* CR */
2884 *(b->ptr)++ = 0xa; /* LF */
2885 buf++;
2886 if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF)
2887 {
2888 PerlIO_flush(f);
2889 break;
2890 }
2891 }
2892 }
2893 else
2894 {
2895 int ch = *buf++;
2896 *(b->ptr)++ = ch;
2897 }
2898 if (b->ptr >= eptr)
2899 {
2900 PerlIO_flush(f);
2901 break;
99efab12 2902 }
99efab12 2903 }
2904 }
f5b9d040 2905 if (PerlIOBase(f)->flags & PERLIO_F_UNBUF)
2906 PerlIO_flush(f);
2907 return (buf - (STDCHAR *) vbuf);
99efab12 2908 }
99efab12 2909}
2910
2911IV
2912PerlIOCrlf_flush(PerlIO *f)
2913{
2914 PerlIOCrlf *c = PerlIOSelf(f,PerlIOCrlf);
2915 if (c->nl)
2916 {
99efab12 2917 *(c->nl) = 0xd;
60382766 2918 c->nl = NULL;
99efab12 2919 }
2920 return PerlIOBuf_flush(f);
2921}
2922
66ecd56b 2923PerlIO_funcs PerlIO_crlf = {
2924 "crlf",
99efab12 2925 sizeof(PerlIOCrlf),
f5b9d040 2926 PERLIO_K_BUFFERED|PERLIO_K_CANCRLF,
66ecd56b 2927 PerlIOBase_fileno,
2928 PerlIOBuf_fdopen,
2929 PerlIOBuf_open,
2930 PerlIOBuf_reopen,
f5b9d040 2931 PerlIOCrlf_pushed,
99efab12 2932 PerlIOBase_noop_ok, /* popped */
2933 PerlIOBuf_read, /* generic read works with ptr/cnt lies ... */
2934 PerlIOCrlf_unread, /* Put CR,LF in buffer for each '\n' */
2935 PerlIOCrlf_write, /* Put CR,LF in buffer for each '\n' */
66ecd56b 2936 PerlIOBuf_seek,
2937 PerlIOBuf_tell,
2938 PerlIOBuf_close,
99efab12 2939 PerlIOCrlf_flush,
66ecd56b 2940 PerlIOBuf_fill,
2941 PerlIOBase_eof,
2942 PerlIOBase_error,
2943 PerlIOBase_clearerr,
2944 PerlIOBuf_setlinebuf,
2945 PerlIOBuf_get_base,
2946 PerlIOBuf_bufsiz,
2947 PerlIOBuf_get_ptr,
99efab12 2948 PerlIOCrlf_get_cnt,
2949 PerlIOCrlf_set_ptrcnt,
66ecd56b 2950};
2951
06da4f11 2952#ifdef HAS_MMAP
2953/*--------------------------------------------------------------------------------------*/
2954/* mmap as "buffer" layer */
2955
2956typedef struct
2957{
2958 PerlIOBuf base; /* PerlIOBuf stuff */
c3d7c7c9 2959 Mmap_t mptr; /* Mapped address */
06da4f11 2960 Size_t len; /* mapped length */
2961 STDCHAR *bbuf; /* malloced buffer if map fails */
2962} PerlIOMmap;
2963
c3d7c7c9 2964static size_t page_size = 0;
2965
06da4f11 2966IV
2967PerlIOMmap_map(PerlIO *f)
2968{
68d873c6 2969 dTHX;
06da4f11 2970 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2971 PerlIOBuf *b = &m->base;
2972 IV flags = PerlIOBase(f)->flags;
2973 IV code = 0;
2974 if (m->len)
2975 abort();
2976 if (flags & PERLIO_F_CANREAD)
2977 {
2978 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2979 int fd = PerlIO_fileno(f);
2980 struct stat st;
2981 code = fstat(fd,&st);
2982 if (code == 0 && S_ISREG(st.st_mode))
2983 {
2984 SSize_t len = st.st_size - b->posn;
2985 if (len > 0)
2986 {
c3d7c7c9 2987 Off_t posn;
68d873c6 2988 if (!page_size) {
2989#if defined(HAS_SYSCONF) && (defined(_SC_PAGESIZE) || defined(_SC_PAGE_SIZE))
2990 {
2991 SETERRNO(0,SS$_NORMAL);
2992# ifdef _SC_PAGESIZE
2993 page_size = sysconf(_SC_PAGESIZE);
2994# else
2995 page_size = sysconf(_SC_PAGE_SIZE);
14aaf8e8 2996# endif
68d873c6 2997 if ((long)page_size < 0) {
2998 if (errno) {
2999 SV *error = ERRSV;
3000 char *msg;
3001 STRLEN n_a;
3002 (void)SvUPGRADE(error, SVt_PV);
3003 msg = SvPVx(error, n_a);
14aaf8e8 3004 Perl_croak(aTHX_ "panic: sysconf: %s", msg);
68d873c6 3005 }
3006 else
14aaf8e8 3007 Perl_croak(aTHX_ "panic: sysconf: pagesize unknown");
68d873c6 3008 }
3009 }
3010#else
3011# ifdef HAS_GETPAGESIZE
c3d7c7c9 3012 page_size = getpagesize();
68d873c6 3013# else
3014# if defined(I_SYS_PARAM) && defined(PAGESIZE)
3015 page_size = PAGESIZE; /* compiletime, bad */
3016# endif
3017# endif
3018#endif
3019 if ((IV)page_size <= 0)
14aaf8e8 3020 Perl_croak(aTHX_ "panic: bad pagesize %"IVdf, (IV)page_size);
68d873c6 3021 }
c3d7c7c9 3022 if (b->posn < 0)
3023 {
3024 /* This is a hack - should never happen - open should have set it ! */
3025 b->posn = PerlIO_tell(PerlIONext(f));
3026 }
3027 posn = (b->posn / page_size) * page_size;
3028 len = st.st_size - posn;
a5262162 3029 m->mptr = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, posn);
c3d7c7c9 3030 if (m->mptr && m->mptr != (Mmap_t) -1)
06da4f11 3031 {
a5262162 3032#if 0 && defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
c3d7c7c9 3033 madvise(m->mptr, len, MADV_SEQUENTIAL);
06da4f11 3034#endif
a5262162 3035#if 0 && defined(HAS_MADVISE) && defined(MADV_WILLNEED)
3036 madvise(m->mptr, len, MADV_WILLNEED);
3037#endif
c3d7c7c9 3038 PerlIOBase(f)->flags = (flags & ~PERLIO_F_EOF) | PERLIO_F_RDBUF;
3039 b->end = ((STDCHAR *)m->mptr) + len;
3040 b->buf = ((STDCHAR *)m->mptr) + (b->posn - posn);
3041 b->ptr = b->buf;
3042 m->len = len;
06da4f11 3043 }
3044 else
3045 {
3046 b->buf = NULL;
3047 }
3048 }
3049 else
3050 {
3051 PerlIOBase(f)->flags = flags | PERLIO_F_EOF | PERLIO_F_RDBUF;
3052 b->buf = NULL;
3053 b->ptr = b->end = b->ptr;
3054 code = -1;
3055 }
3056 }
3057 }
3058 return code;
3059}
3060
3061IV
3062PerlIOMmap_unmap(PerlIO *f)
3063{
3064 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
3065 PerlIOBuf *b = &m->base;
3066 IV code = 0;
3067 if (m->len)
3068 {
3069 if (b->buf)
3070 {
c3d7c7c9 3071 code = munmap(m->mptr, m->len);
3072 b->buf = NULL;
3073 m->len = 0;
3074 m->mptr = NULL;
06da4f11 3075 if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) != 0)
3076 code = -1;
06da4f11 3077 }
3078 b->ptr = b->end = b->buf;
3079 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
3080 }
3081 return code;
3082}
3083
3084STDCHAR *
3085PerlIOMmap_get_base(PerlIO *f)
3086{
3087 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
3088 PerlIOBuf *b = &m->base;
3089 if (b->buf && (PerlIOBase(f)->flags & PERLIO_F_RDBUF))
3090 {
3091 /* Already have a readbuffer in progress */
3092 return b->buf;
3093 }
3094 if (b->buf)
3095 {
3096 /* We have a write buffer or flushed PerlIOBuf read buffer */
3097 m->bbuf = b->buf; /* save it in case we need it again */
3098 b->buf = NULL; /* Clear to trigger below */
3099 }
3100 if (!b->buf)
3101 {
3102 PerlIOMmap_map(f); /* Try and map it */
3103 if (!b->buf)
3104 {
3105 /* Map did not work - recover PerlIOBuf buffer if we have one */
3106 b->buf = m->bbuf;
3107 }
3108 }
3109 b->ptr = b->end = b->buf;
3110 if (b->buf)
3111 return b->buf;
3112 return PerlIOBuf_get_base(f);
3113}
3114
3115SSize_t
3116PerlIOMmap_unread(PerlIO *f, const void *vbuf, Size_t count)
3117{
3118 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
3119 PerlIOBuf *b = &m->base;
3120 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
3121 PerlIO_flush(f);
3122 if (b->ptr && (b->ptr - count) >= b->buf && memEQ(b->ptr - count,vbuf,count))
3123 {
3124 b->ptr -= count;
3125 PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
3126 return count;
3127 }
3128 if (m->len)
3129 {
4a4a6116 3130 /* Loose the unwritable mapped buffer */
06da4f11 3131 PerlIO_flush(f);
c3d7c7c9 3132 /* If flush took the "buffer" see if we have one from before */
3133 if (!b->buf && m->bbuf)
3134 b->buf = m->bbuf;
3135 if (!b->buf)
3136 {
3137 PerlIOBuf_get_base(f);
3138 m->bbuf = b->buf;
3139 }
06da4f11 3140 }
5e2ab84b 3141return PerlIOBuf_unread(f,vbuf,count);
06da4f11 3142}
3143
3144SSize_t
3145PerlIOMmap_write(PerlIO *f, const void *vbuf, Size_t count)
3146{
3147 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
3148 PerlIOBuf *b = &m->base;
3149 if (!b->buf || !(PerlIOBase(f)->flags & PERLIO_F_WRBUF))
3150 {
3151 /* No, or wrong sort of, buffer */
3152 if (m->len)
3153 {
3154 if (PerlIOMmap_unmap(f) != 0)
3155 return 0;
3156 }
3157 /* If unmap took the "buffer" see if we have one from before */
3158 if (!b->buf && m->bbuf)
3159 b->buf = m->bbuf;
3160 if (!b->buf)
3161 {
3162 PerlIOBuf_get_base(f);
3163 m->bbuf = b->buf;
3164 }
3165 }
3166 return PerlIOBuf_write(f,vbuf,count);
3167}
3168
3169IV
3170PerlIOMmap_flush(PerlIO *f)
3171{
3172 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
3173 PerlIOBuf *b = &m->base;
3174 IV code = PerlIOBuf_flush(f);
3175 /* Now we are "synced" at PerlIOBuf level */
3176 if (b->buf)
3177 {
3178 if (m->len)
3179 {
3180 /* Unmap the buffer */
3181 if (PerlIOMmap_unmap(f) != 0)
3182 code = -1;
3183 }
3184 else
3185 {
3186 /* We seem to have a PerlIOBuf buffer which was not mapped
3187 * remember it in case we need one later
3188 */
3189 m->bbuf = b->buf;
3190 }
3191 }
06da4f11 3192 return code;
3193}
3194
3195IV
3196PerlIOMmap_fill(PerlIO *f)
3197{
3198 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
3199 IV code = PerlIO_flush(f);
06da4f11 3200 if (code == 0 && !b->buf)
3201 {
3202 code = PerlIOMmap_map(f);
06da4f11 3203 }
3204 if (code == 0 && !(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
3205 {
3206 code = PerlIOBuf_fill(f);
06da4f11 3207 }
3208 return code;
3209}
3210
3211IV
3212PerlIOMmap_close(PerlIO *f)
3213{
3214 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
3215 PerlIOBuf *b = &m->base;
3216 IV code = PerlIO_flush(f);
3217 if (m->bbuf)
3218 {
3219 b->buf = m->bbuf;
3220 m->bbuf = NULL;
3221 b->ptr = b->end = b->buf;
3222 }
3223 if (PerlIOBuf_close(f) != 0)
3224 code = -1;
06da4f11 3225 return code;
3226}
3227
3228
3229PerlIO_funcs PerlIO_mmap = {
3230 "mmap",
3231 sizeof(PerlIOMmap),
f5b9d040 3232 PERLIO_K_BUFFERED,
06da4f11 3233 PerlIOBase_fileno,
3234 PerlIOBuf_fdopen,
3235 PerlIOBuf_open,
c3d7c7c9 3236 PerlIOBuf_reopen,
5e2ab84b 3237 PerlIOBuf_pushed,
06da4f11 3238 PerlIOBase_noop_ok,
3239 PerlIOBuf_read,
3240 PerlIOMmap_unread,
3241 PerlIOMmap_write,
3242 PerlIOBuf_seek,
3243 PerlIOBuf_tell,
3244 PerlIOBuf_close,
3245 PerlIOMmap_flush,
3246 PerlIOMmap_fill,
3247 PerlIOBase_eof,
3248 PerlIOBase_error,
3249 PerlIOBase_clearerr,
3250 PerlIOBuf_setlinebuf,
3251 PerlIOMmap_get_base,
3252 PerlIOBuf_bufsiz,
3253 PerlIOBuf_get_ptr,
3254 PerlIOBuf_get_cnt,
3255 PerlIOBuf_set_ptrcnt,
3256};
3257
3258#endif /* HAS_MMAP */
3259
9e353e3b 3260void
3261PerlIO_init(void)
760ac839 3262{
9e353e3b 3263 if (!_perlio)
6f9d8c32 3264 {
be696b0a 3265#ifndef WIN32
9e353e3b 3266 atexit(&PerlIO_cleanup);
be696b0a 3267#endif
6f9d8c32 3268 }
760ac839 3269}
3270
dfebf958 3271
3272
9e353e3b 3273#undef PerlIO_stdin
3274PerlIO *
3275PerlIO_stdin(void)
3276{
3277 if (!_perlio)
f3862f8b 3278 PerlIO_stdstreams();
05d1247b 3279 return &_perlio[1];
9e353e3b 3280}
3281
3282#undef PerlIO_stdout
3283PerlIO *
3284PerlIO_stdout(void)
3285{
3286 if (!_perlio)
f3862f8b 3287 PerlIO_stdstreams();
05d1247b 3288 return &_perlio[2];
9e353e3b 3289}
3290
3291#undef PerlIO_stderr
3292PerlIO *
3293PerlIO_stderr(void)
3294{
3295 if (!_perlio)
f3862f8b 3296 PerlIO_stdstreams();
05d1247b 3297 return &_perlio[3];
9e353e3b 3298}
3299
3300/*--------------------------------------------------------------------------------------*/
3301
3302#undef PerlIO_getname
3303char *
3304PerlIO_getname(PerlIO *f, char *buf)
3305{
3306 dTHX;
3307 Perl_croak(aTHX_ "Don't know how to get file name");
3308 return NULL;
3309}
3310
3311
3312/*--------------------------------------------------------------------------------------*/
3313/* Functions which can be called on any kind of PerlIO implemented
3314 in terms of above
3315*/
3316
3317#undef PerlIO_getc
6f9d8c32 3318int
9e353e3b 3319PerlIO_getc(PerlIO *f)
760ac839 3320{
313ca112 3321 STDCHAR buf[1];
3322 SSize_t count = PerlIO_read(f,buf,1);
9e353e3b 3323 if (count == 1)
313ca112 3324 {
3325 return (unsigned char) buf[0];
3326 }
3327 return EOF;
3328}
3329
3330#undef PerlIO_ungetc
3331int
3332PerlIO_ungetc(PerlIO *f, int ch)
3333{
3334 if (ch != EOF)
3335 {
3336 STDCHAR buf = ch;
3337 if (PerlIO_unread(f,&buf,1) == 1)
3338 return ch;
3339 }
3340 return EOF;
760ac839 3341}
3342
9e353e3b 3343#undef PerlIO_putc
3344int
3345PerlIO_putc(PerlIO *f, int ch)
760ac839 3346{
9e353e3b 3347 STDCHAR buf = ch;
3348 return PerlIO_write(f,&buf,1);
760ac839 3349}
3350
9e353e3b 3351#undef PerlIO_puts
760ac839 3352int
9e353e3b 3353PerlIO_puts(PerlIO *f, const char *s)
760ac839 3354{
9e353e3b 3355 STRLEN len = strlen(s);
3356 return PerlIO_write(f,s,len);
760ac839 3357}
3358
3359#undef PerlIO_rewind
3360void
c78749f2 3361PerlIO_rewind(PerlIO *f)
760ac839 3362{
6f9d8c32 3363 PerlIO_seek(f,(Off_t)0,SEEK_SET);
9e353e3b 3364 PerlIO_clearerr(f);
6f9d8c32 3365}
3366
3367#undef PerlIO_vprintf
3368int
3369PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
3370{
3371 dTHX;
bb9950b7 3372 SV *sv = newSVpvn("",0);
6f9d8c32 3373 char *s;
3374 STRLEN len;
2cc61e15 3375#ifdef NEED_VA_COPY
3376 va_list apc;
3377 Perl_va_copy(ap, apc);
3378 sv_vcatpvf(sv, fmt, &apc);
3379#else
6f9d8c32 3380 sv_vcatpvf(sv, fmt, &ap);
2cc61e15 3381#endif
6f9d8c32 3382 s = SvPV(sv,len);
bb9950b7 3383 return PerlIO_write(f,s,len);
760ac839 3384}
3385
3386#undef PerlIO_printf
6f9d8c32 3387int
760ac839 3388PerlIO_printf(PerlIO *f,const char *fmt,...)
760ac839 3389{
3390 va_list ap;
3391 int result;
760ac839 3392 va_start(ap,fmt);
6f9d8c32 3393 result = PerlIO_vprintf(f,fmt,ap);
760ac839 3394 va_end(ap);
3395 return result;
3396}
3397
3398#undef PerlIO_stdoutf
6f9d8c32 3399int
760ac839 3400PerlIO_stdoutf(const char *fmt,...)
760ac839 3401{
3402 va_list ap;
3403 int result;
760ac839 3404 va_start(ap,fmt);
760ac839 3405 result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
3406 va_end(ap);
3407 return result;
3408}
3409
3410#undef PerlIO_tmpfile
3411PerlIO *
c78749f2 3412PerlIO_tmpfile(void)
760ac839 3413{
b1ef6e3b 3414 /* I have no idea how portable mkstemp() is ... */
83b075c3 3415#if defined(WIN32) || !defined(HAVE_MKSTEMP)
adb71456 3416 dTHX;
83b075c3 3417 PerlIO *f = NULL;
eaf8b698 3418 FILE *stdio = PerlSIO_tmpfile();
83b075c3 3419 if (stdio)
3420 {
33af2bc7 3421 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),&PerlIO_stdio,"w+",Nullch,0),PerlIOStdio);
83b075c3 3422 s->stdio = stdio;
3423 }
3424 return f;
3425#else
3426 dTHX;
6f9d8c32 3427 SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
3428 int fd = mkstemp(SvPVX(sv));
3429 PerlIO *f = NULL;
3430 if (fd >= 0)
3431 {
b1ef6e3b 3432 f = PerlIO_fdopen(fd,"w+");
6f9d8c32 3433 if (f)
3434 {
9e353e3b 3435 PerlIOBase(f)->flags |= PERLIO_F_TEMP;
6f9d8c32 3436 }
00b02797 3437 PerlLIO_unlink(SvPVX(sv));
6f9d8c32 3438 SvREFCNT_dec(sv);
3439 }
3440 return f;
83b075c3 3441#endif
760ac839 3442}
3443
6f9d8c32 3444#undef HAS_FSETPOS
3445#undef HAS_FGETPOS
3446
760ac839 3447#endif /* USE_SFIO */
3448#endif /* PERLIO_IS_STDIO */
3449
9e353e3b 3450/*======================================================================================*/
3451/* Now some functions in terms of above which may be needed even if
3452 we are not in true PerlIO mode
3453 */
3454
760ac839 3455#ifndef HAS_FSETPOS
3456#undef PerlIO_setpos
3457int
766a733e 3458PerlIO_setpos(PerlIO *f, SV *pos)
760ac839 3459{
766a733e 3460 dTHX;
3461 if (SvOK(pos))
3462 {
3463 STRLEN len;
3464 Off_t *posn = (Off_t *) SvPV(pos,len);
3465 if (f && len == sizeof(Off_t))
3466 return PerlIO_seek(f,*posn,SEEK_SET);
3467 }
3468 errno = EINVAL;
3469 return -1;
760ac839 3470}
c411622e 3471#else
c411622e 3472#undef PerlIO_setpos
3473int
766a733e 3474PerlIO_setpos(PerlIO *f, SV *pos)
c411622e 3475{
766a733e 3476 dTHX;
3477 if (SvOK(pos))
3478 {
3479 STRLEN len;
3480 Fpos_t *fpos = (Fpos_t *) SvPV(pos,len);
3481 if (f && len == sizeof(Fpos_t))
3482 {
2d4389e4 3483#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
766a733e 3484 return fsetpos64(f, fpos);
d9b3e12d 3485#else
766a733e 3486 return fsetpos(f, fpos);
d9b3e12d 3487#endif
766a733e 3488 }
3489 }
3490 errno = EINVAL;
3491 return -1;
c411622e 3492}
3493#endif
760ac839 3494
3495#ifndef HAS_FGETPOS
3496#undef PerlIO_getpos
3497int
766a733e 3498PerlIO_getpos(PerlIO *f, SV *pos)
760ac839 3499{
766a733e 3500 dTHX;
3501 Off_t posn = PerlIO_tell(f);
3502 sv_setpvn(pos,(char *)&posn,sizeof(posn));
3503 return (posn == (Off_t)-1) ? -1 : 0;
760ac839 3504}
c411622e 3505#else
c411622e 3506#undef PerlIO_getpos
3507int
766a733e 3508PerlIO_getpos(PerlIO *f, SV *pos)
c411622e 3509{
766a733e 3510 dTHX;
3511 Fpos_t fpos;
3512 int code;
2d4389e4 3513#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
766a733e 3514 code = fgetpos64(f, &fpos);
d9b3e12d 3515#else
766a733e 3516 code = fgetpos(f, &fpos);
d9b3e12d 3517#endif
766a733e 3518 sv_setpvn(pos,(char *)&fpos,sizeof(fpos));
3519 return code;
c411622e 3520}
3521#endif
760ac839 3522
3523#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
3524
3525int
c78749f2 3526vprintf(char *pat, char *args)
662a7e3f 3527{
3528 _doprnt(pat, args, stdout);
3529 return 0; /* wrong, but perl doesn't use the return value */
3530}
3531
3532int
c78749f2 3533vfprintf(FILE *fd, char *pat, char *args)
760ac839 3534{
3535 _doprnt(pat, args, fd);
3536 return 0; /* wrong, but perl doesn't use the return value */
3537}
3538
3539#endif
3540
3541#ifndef PerlIO_vsprintf
6f9d8c32 3542int
8ac85365 3543PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
760ac839 3544{
3545 int val = vsprintf(s, fmt, ap);
3546 if (n >= 0)
3547 {
8c86a920 3548 if (strlen(s) >= (STRLEN)n)
760ac839 3549 {
bf49b057 3550 dTHX;
fb4a9925 3551 (void)PerlIO_puts(Perl_error_log,
3552 "panic: sprintf overflow - memory corrupted!\n");
bf49b057 3553 my_exit(1);
760ac839 3554 }
3555 }
3556 return val;
3557}
3558#endif
3559
3560#ifndef PerlIO_sprintf
6f9d8c32 3561int
760ac839 3562PerlIO_sprintf(char *s, int n, const char *fmt,...)
760ac839 3563{
3564 va_list ap;
3565 int result;
760ac839 3566 va_start(ap,fmt);
760ac839 3567 result = PerlIO_vsprintf(s, n, fmt, ap);
3568 va_end(ap);
3569 return result;
3570}
3571#endif
3572
c5be433b 3573