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