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