Nickety nits.
[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}
43#endif
44
32e30700 45#if !defined(PERL_IMPLICIT_SYS)
46
6f9d8c32 47#ifdef PERLIO_IS_STDIO
760ac839 48
49void
8ac85365 50PerlIO_init(void)
760ac839 51{
6f9d8c32 52 /* Does nothing (yet) except force this file to be included
760ac839 53 in perl binary. That allows this file to force inclusion
6f9d8c32 54 of other functions that may be required by loadable
55 extensions e.g. for FileHandle::tmpfile
760ac839 56 */
57}
58
33dcbb9a 59#undef PerlIO_tmpfile
60PerlIO *
8ac85365 61PerlIO_tmpfile(void)
33dcbb9a 62{
63 return tmpfile();
64}
65
760ac839 66#else /* PERLIO_IS_STDIO */
67
68#ifdef USE_SFIO
69
70#undef HAS_FSETPOS
71#undef HAS_FGETPOS
72
6f9d8c32 73/* This section is just to make sure these functions
760ac839 74 get pulled in from libsfio.a
75*/
76
77#undef PerlIO_tmpfile
78PerlIO *
c78749f2 79PerlIO_tmpfile(void)
760ac839 80{
81 return sftmp(0);
82}
83
84void
c78749f2 85PerlIO_init(void)
760ac839 86{
6f9d8c32 87 /* Force this file to be included in perl binary. Which allows
88 * this file to force inclusion of other functions that may be
89 * required by loadable extensions e.g. for FileHandle::tmpfile
760ac839 90 */
91
92 /* Hack
93 * sfio does its own 'autoflush' on stdout in common cases.
6f9d8c32 94 * Flush results in a lot of lseek()s to regular files and
760ac839 95 * lot of small writes to pipes.
96 */
97 sfset(sfstdout,SF_SHARE,0);
98}
99
17c3b450 100#else /* USE_SFIO */
6f9d8c32 101/*======================================================================================*/
6f9d8c32 102/* Implement all the PerlIO interface ourselves.
9e353e3b 103 */
760ac839 104
76ced9ad 105#include "perliol.h"
106
b1ef6e3b 107/* We _MUST_ have <unistd.h> if we are using lseek() and may have large files */
02f66e2f 108#ifdef I_UNISTD
109#include <unistd.h>
110#endif
06da4f11 111#ifdef HAS_MMAP
112#include <sys/mman.h>
113#endif
114
f3862f8b 115#include "XSUB.h"
02f66e2f 116
88b61e10 117void PerlIO_debug(const char *fmt,...) __attribute__((format(__printf__,1,2)));
6f9d8c32 118
6f9d8c32 119void
88b61e10 120PerlIO_debug(const char *fmt,...)
6f9d8c32 121{
122 static int dbg = 0;
88b61e10 123 va_list ap;
124 va_start(ap,fmt);
6f9d8c32 125 if (!dbg)
126 {
00b02797 127 char *s = PerlEnv_getenv("PERLIO_DEBUG");
6f9d8c32 128 if (s && *s)
00b02797 129 dbg = PerlLIO_open3(s,O_WRONLY|O_CREAT|O_APPEND,0666);
6f9d8c32 130 else
131 dbg = -1;
132 }
133 if (dbg > 0)
134 {
135 dTHX;
6f9d8c32 136 SV *sv = newSVpvn("",0);
137 char *s;
138 STRLEN len;
05d1247b 139 s = CopFILE(PL_curcop);
140 if (!s)
141 s = "(none)";
142 Perl_sv_catpvf(aTHX_ sv, "%s:%"IVdf" ", s, (IV)CopLINE(PL_curcop));
c7fc522f 143 Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap);
144
6f9d8c32 145 s = SvPV(sv,len);
00b02797 146 PerlLIO_write(dbg,s,len);
6f9d8c32 147 SvREFCNT_dec(sv);
148 }
88b61e10 149 va_end(ap);
6f9d8c32 150}
151
9e353e3b 152/*--------------------------------------------------------------------------------------*/
153
9e353e3b 154/* Inner level routines */
155
b1ef6e3b 156/* Table of pointers to the PerlIO structs (malloc'ed) */
05d1247b 157PerlIO *_perlio = NULL;
158#define PERLIO_TABLE_SIZE 64
6f9d8c32 159
760ac839 160PerlIO *
6f9d8c32 161PerlIO_allocate(void)
162{
f3862f8b 163 /* Find a free slot in the table, allocating new table as necessary */
05d1247b 164 PerlIO **last = &_perlio;
6f9d8c32 165 PerlIO *f;
05d1247b 166 while ((f = *last))
6f9d8c32 167 {
05d1247b 168 int i;
169 last = (PerlIO **)(f);
170 for (i=1; i < PERLIO_TABLE_SIZE; i++)
6f9d8c32 171 {
05d1247b 172 if (!*++f)
6f9d8c32 173 {
6f9d8c32 174 return f;
175 }
6f9d8c32 176 }
6f9d8c32 177 }
05d1247b 178 Newz('I',f,PERLIO_TABLE_SIZE,PerlIO);
179 if (!f)
180 return NULL;
181 *last = f;
182 return f+1;
183}
184
185void
186PerlIO_cleantable(PerlIO **tablep)
187{
188 PerlIO *table = *tablep;
189 if (table)
190 {
191 int i;
192 PerlIO_cleantable((PerlIO **) &(table[0]));
193 for (i=PERLIO_TABLE_SIZE-1; i > 0; i--)
194 {
195 PerlIO *f = table+i;
196 if (*f)
197 PerlIO_close(f);
198 }
199 Safefree(table);
200 *tablep = NULL;
201 }
202}
203
4a4a6116 204HV *PerlIO_layer_hv;
205AV *PerlIO_layer_av;
206
05d1247b 207void
208PerlIO_cleanup(void)
209{
210 PerlIO_cleantable(&_perlio);
6f9d8c32 211}
212
9e353e3b 213void
214PerlIO_pop(PerlIO *f)
760ac839 215{
9e353e3b 216 PerlIOl *l = *f;
217 if (l)
6f9d8c32 218 {
06da4f11 219 (*l->tab->Popped)(f);
9e353e3b 220 *f = l->next;
221 Safefree(l);
6f9d8c32 222 }
6f9d8c32 223}
224
9e353e3b 225/*--------------------------------------------------------------------------------------*/
b931b1d9 226/* XS Interface for perl code */
9e353e3b 227
b931b1d9 228XS(XS_perlio_import)
f3862f8b 229{
230 dXSARGS;
231 GV *gv = CvGV(cv);
232 char *s = GvNAME(gv);
233 STRLEN l = GvNAMELEN(gv);
234 PerlIO_debug("%.*s\n",(int) l,s);
235 XSRETURN_EMPTY;
236}
237
b931b1d9 238XS(XS_perlio_unimport)
f3862f8b 239{
240 dXSARGS;
241 GV *gv = CvGV(cv);
242 char *s = GvNAME(gv);
243 STRLEN l = GvNAMELEN(gv);
244 PerlIO_debug("%.*s\n",(int) l,s);
245 XSRETURN_EMPTY;
246}
247
f3862f8b 248SV *
ac27b0f5 249PerlIO_find_layer(const char *name, STRLEN len)
f3862f8b 250{
251 dTHX;
252 SV **svp;
253 SV *sv;
254 if (len <= 0)
255 len = strlen(name);
256 svp = hv_fetch(PerlIO_layer_hv,name,len,0);
257 if (svp && (sv = *svp) && SvROK(sv))
258 return *svp;
259 return NULL;
260}
261
b13b2135 262
263static int
264perlio_mg_set(pTHX_ SV *sv, MAGIC *mg)
265{
266 if (SvROK(sv))
267 {
b931b1d9 268 IO *io = GvIOn((GV *)SvRV(sv));
b13b2135 269 PerlIO *ifp = IoIFP(io);
270 PerlIO *ofp = IoOFP(io);
271 AV *av = (AV *) mg->mg_obj;
272 Perl_warn(aTHX_ "set %_ %p %p %p",sv,io,ifp,ofp);
273 }
274 return 0;
275}
276
277static int
278perlio_mg_get(pTHX_ SV *sv, MAGIC *mg)
279{
280 if (SvROK(sv))
281 {
b931b1d9 282 IO *io = GvIOn((GV *)SvRV(sv));
b13b2135 283 PerlIO *ifp = IoIFP(io);
284 PerlIO *ofp = IoOFP(io);
285 AV *av = (AV *) mg->mg_obj;
286 Perl_warn(aTHX_ "get %_ %p %p %p",sv,io,ifp,ofp);
287 }
288 return 0;
289}
290
291static int
292perlio_mg_clear(pTHX_ SV *sv, MAGIC *mg)
293{
294 Perl_warn(aTHX_ "clear %_",sv);
295 return 0;
296}
297
298static int
299perlio_mg_free(pTHX_ SV *sv, MAGIC *mg)
300{
301 Perl_warn(aTHX_ "free %_",sv);
302 return 0;
303}
304
305MGVTBL perlio_vtab = {
306 perlio_mg_get,
307 perlio_mg_set,
308 NULL, /* len */
309 NULL,
310 perlio_mg_free
311};
312
313XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
314{
315 dXSARGS;
316 SV *sv = SvRV(ST(1));
317 AV *av = newAV();
318 MAGIC *mg;
319 int count = 0;
320 int i;
321 sv_magic(sv, (SV *)av, '~', NULL, 0);
322 SvRMAGICAL_off(sv);
323 mg = mg_find(sv,'~');
324 mg->mg_virtual = &perlio_vtab;
325 mg_magical(sv);
326 Perl_warn(aTHX_ "attrib %_",sv);
327 for (i=2; i < items; i++)
328 {
329 STRLEN len;
ac27b0f5 330 const char *name = SvPV(ST(i),len);
b13b2135 331 SV *layer = PerlIO_find_layer(name,len);
332 if (layer)
333 {
334 av_push(av,SvREFCNT_inc(layer));
335 }
336 else
337 {
338 ST(count) = ST(i);
339 count++;
340 }
341 }
342 SvREFCNT_dec(av);
343 XSRETURN(count);
344}
345
f3862f8b 346void
347PerlIO_define_layer(PerlIO_funcs *tab)
348{
349 dTHX;
b931b1d9 350 HV *stash = gv_stashpv("perlio::Layer", TRUE);
e7778b43 351 SV *sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))),stash);
f3862f8b 352 hv_store(PerlIO_layer_hv,tab->name,strlen(tab->name),sv,0);
353}
354
355PerlIO_funcs *
356PerlIO_default_layer(I32 n)
357{
358 dTHX;
359 SV **svp;
360 SV *layer;
361 PerlIO_funcs *tab = &PerlIO_stdio;
362 int len;
363 if (!PerlIO_layer_hv)
364 {
ac27b0f5 365 const char *s = PerlEnv_getenv("PERLIO");
b931b1d9 366 newXS("perlio::import",XS_perlio_import,__FILE__);
367 newXS("perlio::unimport",XS_perlio_unimport,__FILE__);
368#if 0
b13b2135 369 newXS("io::MODIFY_SCALAR_ATTRIBUTES",XS_io_MODIFY_SCALAR_ATTRIBUTES,__FILE__);
b931b1d9 370#endif
371 PerlIO_layer_hv = get_hv("open::layers",GV_ADD|GV_ADDMULTI);
372 PerlIO_layer_av = get_av("open::layers",GV_ADD|GV_ADDMULTI);
f3862f8b 373 PerlIO_define_layer(&PerlIO_unix);
f3862f8b 374 PerlIO_define_layer(&PerlIO_perlio);
375 PerlIO_define_layer(&PerlIO_stdio);
66ecd56b 376 PerlIO_define_layer(&PerlIO_crlf);
06da4f11 377#ifdef HAS_MMAP
378 PerlIO_define_layer(&PerlIO_mmap);
379#endif
f3862f8b 380 av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(PerlIO_unix.name,0)));
381 if (s)
382 {
383 while (*s)
384 {
00b02797 385 while (*s && isSPACE((unsigned char)*s))
f3862f8b 386 s++;
387 if (*s)
388 {
ac27b0f5 389 const char *e = s;
f3862f8b 390 SV *layer;
00b02797 391 while (*e && !isSPACE((unsigned char)*e))
f3862f8b 392 e++;
ac27b0f5 393 if (*s == ':')
394 s++;
f3862f8b 395 layer = PerlIO_find_layer(s,e-s);
396 if (layer)
397 {
398 PerlIO_debug("Pushing %.*s\n",(e-s),s);
399 av_push(PerlIO_layer_av,SvREFCNT_inc(layer));
400 }
401 else
ef0f9817 402 Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",(e-s),s);
f3862f8b 403 s = e;
404 }
405 }
406 }
407 }
408 len = av_len(PerlIO_layer_av);
409 if (len < 1)
410 {
411 if (PerlIO_stdio.Set_ptrcnt)
412 {
413 av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(PerlIO_stdio.name,0)));
414 }
415 else
416 {
417 av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(PerlIO_perlio.name,0)));
418 }
419 len = av_len(PerlIO_layer_av);
420 }
421 if (n < 0)
422 n += len+1;
423 svp = av_fetch(PerlIO_layer_av,n,0);
424 if (svp && (layer = *svp) && SvROK(layer) && SvIOK((layer = SvRV(layer))))
425 {
e7778b43 426 tab = INT2PTR(PerlIO_funcs *, SvIV(layer));
f3862f8b 427 }
428 /* PerlIO_debug("Layer %d is %s\n",n,tab->name); */
429 return tab;
430}
431
ac27b0f5 432int
433PerlIO_apply_layers(pTHX_ PerlIO *f, const char *mode, const char *names)
434{
435 if (names)
436 {
437 const char *s = names;
438 while (*s)
439 {
440 while (isSPACE(*s))
441 s++;
442 if (*s == ':')
443 s++;
444 if (*s)
445 {
446 const char *e = s;
447 while (*e && *e != ':' && !isSPACE(*e))
448 e++;
449 if (e > s)
450 {
451 SV *layer = PerlIO_find_layer(s,e-s);
452 if (layer)
453 {
66ecd56b 454 PerlIO_funcs *tab = INT2PTR(PerlIO_funcs *, SvIV(SvRV(layer)));
ac27b0f5 455 if (tab)
456 {
457 PerlIO *new = PerlIO_push(f,tab,mode);
458 if (!new)
459 return -1;
460 }
461 }
462 else
463 Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",(e-s),s);
464 }
465 s = e;
466 }
467 }
468 }
469 return 0;
470}
471
f3862f8b 472#define PerlIO_default_top() PerlIO_default_layer(-1)
473#define PerlIO_default_btm() PerlIO_default_layer(0)
474
475void
476PerlIO_stdstreams()
477{
478 if (!_perlio)
479 {
480 PerlIO_allocate();
481 PerlIO_fdopen(0,"Ir");
482 PerlIO_fdopen(1,"Iw");
483 PerlIO_fdopen(2,"Iw");
484 }
485}
9e353e3b 486
76ced9ad 487PerlIO *
488PerlIO_push(PerlIO *f,PerlIO_funcs *tab,const char *mode)
489{
490 PerlIOl *l = NULL;
491 Newc('L',l,tab->size,char,PerlIOl);
492 if (l)
493 {
494 Zero(l,tab->size,char);
495 l->next = *f;
496 l->tab = tab;
497 *f = l;
498 if ((*l->tab->Pushed)(f,mode) != 0)
499 {
500 PerlIO_pop(f);
501 return NULL;
502 }
503 }
504 return f;
505}
506
b931b1d9 507/*--------------------------------------------------------------------------------------*/
508/* Given the abstraction above the public API functions */
509
510#undef PerlIO_close
511int
512PerlIO_close(PerlIO *f)
513{
514 int code = (*PerlIOBase(f)->tab->Close)(f);
515 while (*f)
516 {
517 PerlIO_pop(f);
518 }
519 return code;
520}
521
522#undef PerlIO_fileno
523int
524PerlIO_fileno(PerlIO *f)
525{
526 return (*PerlIOBase(f)->tab->Fileno)(f);
527}
528
529
530
9e353e3b 531#undef PerlIO_fdopen
532PerlIO *
533PerlIO_fdopen(int fd, const char *mode)
534{
535 PerlIO_funcs *tab = PerlIO_default_top();
f3862f8b 536 if (!_perlio)
537 PerlIO_stdstreams();
06da4f11 538 return (*tab->Fdopen)(tab,fd,mode);
9e353e3b 539}
540
6f9d8c32 541#undef PerlIO_open
542PerlIO *
543PerlIO_open(const char *path, const char *mode)
544{
9e353e3b 545 PerlIO_funcs *tab = PerlIO_default_top();
f3862f8b 546 if (!_perlio)
547 PerlIO_stdstreams();
06da4f11 548 return (*tab->Open)(tab,path,mode);
6f9d8c32 549}
550
9e353e3b 551#undef PerlIO_reopen
552PerlIO *
553PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
6f9d8c32 554{
9e353e3b 555 if (f)
6f9d8c32 556 {
9e353e3b 557 PerlIO_flush(f);
558 if ((*PerlIOBase(f)->tab->Reopen)(path,mode,f) == 0)
559 {
06da4f11 560 if ((*PerlIOBase(f)->tab->Pushed)(f,mode) == 0)
561 return f;
9e353e3b 562 }
563 return NULL;
6f9d8c32 564 }
9e353e3b 565 else
566 return PerlIO_open(path,mode);
760ac839 567}
568
9e353e3b 569#undef PerlIO_read
570SSize_t
571PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 572{
9e353e3b 573 return (*PerlIOBase(f)->tab->Read)(f,vbuf,count);
760ac839 574}
575
313ca112 576#undef PerlIO_unread
577SSize_t
578PerlIO_unread(PerlIO *f, const void *vbuf, Size_t count)
760ac839 579{
313ca112 580 return (*PerlIOBase(f)->tab->Unread)(f,vbuf,count);
760ac839 581}
582
9e353e3b 583#undef PerlIO_write
584SSize_t
585PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
760ac839 586{
9e353e3b 587 return (*PerlIOBase(f)->tab->Write)(f,vbuf,count);
760ac839 588}
589
9e353e3b 590#undef PerlIO_seek
6f9d8c32 591int
9e353e3b 592PerlIO_seek(PerlIO *f, Off_t offset, int whence)
760ac839 593{
9e353e3b 594 return (*PerlIOBase(f)->tab->Seek)(f,offset,whence);
760ac839 595}
596
9e353e3b 597#undef PerlIO_tell
598Off_t
599PerlIO_tell(PerlIO *f)
760ac839 600{
9e353e3b 601 return (*PerlIOBase(f)->tab->Tell)(f);
760ac839 602}
603
9e353e3b 604#undef PerlIO_flush
6f9d8c32 605int
9e353e3b 606PerlIO_flush(PerlIO *f)
760ac839 607{
6f9d8c32 608 if (f)
609 {
9e353e3b 610 return (*PerlIOBase(f)->tab->Flush)(f);
6f9d8c32 611 }
9e353e3b 612 else
6f9d8c32 613 {
05d1247b 614 PerlIO **table = &_perlio;
9e353e3b 615 int code = 0;
05d1247b 616 while ((f = *table))
6f9d8c32 617 {
05d1247b 618 int i;
619 table = (PerlIO **)(f++);
620 for (i=1; i < PERLIO_TABLE_SIZE; i++)
9e353e3b 621 {
622 if (*f && PerlIO_flush(f) != 0)
623 code = -1;
05d1247b 624 f++;
9e353e3b 625 }
6f9d8c32 626 }
9e353e3b 627 return code;
6f9d8c32 628 }
760ac839 629}
630
06da4f11 631#undef PerlIO_fill
632int
633PerlIO_fill(PerlIO *f)
634{
635 return (*PerlIOBase(f)->tab->Fill)(f);
636}
637
f3862f8b 638#undef PerlIO_isutf8
639int
640PerlIO_isutf8(PerlIO *f)
641{
642 return (PerlIOBase(f)->flags & PERLIO_F_UTF8) != 0;
643}
644
9e353e3b 645#undef PerlIO_eof
6f9d8c32 646int
9e353e3b 647PerlIO_eof(PerlIO *f)
760ac839 648{
9e353e3b 649 return (*PerlIOBase(f)->tab->Eof)(f);
650}
651
652#undef PerlIO_error
653int
654PerlIO_error(PerlIO *f)
655{
656 return (*PerlIOBase(f)->tab->Error)(f);
657}
658
659#undef PerlIO_clearerr
660void
661PerlIO_clearerr(PerlIO *f)
662{
663 (*PerlIOBase(f)->tab->Clearerr)(f);
664}
665
666#undef PerlIO_setlinebuf
667void
668PerlIO_setlinebuf(PerlIO *f)
669{
670 (*PerlIOBase(f)->tab->Setlinebuf)(f);
671}
672
673#undef PerlIO_has_base
674int
675PerlIO_has_base(PerlIO *f)
676{
677 if (f && *f)
6f9d8c32 678 {
9e353e3b 679 return (PerlIOBase(f)->tab->Get_base != NULL);
6f9d8c32 680 }
9e353e3b 681 return 0;
760ac839 682}
683
9e353e3b 684#undef PerlIO_fast_gets
685int
686PerlIO_fast_gets(PerlIO *f)
760ac839 687{
9e353e3b 688 if (f && *f)
6f9d8c32 689 {
c7fc522f 690 PerlIOl *l = PerlIOBase(f);
691 return (l->tab->Set_ptrcnt != NULL);
6f9d8c32 692 }
9e353e3b 693 return 0;
694}
695
696#undef PerlIO_has_cntptr
697int
698PerlIO_has_cntptr(PerlIO *f)
699{
700 if (f && *f)
701 {
702 PerlIO_funcs *tab = PerlIOBase(f)->tab;
703 return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
704 }
705 return 0;
706}
707
708#undef PerlIO_canset_cnt
709int
710PerlIO_canset_cnt(PerlIO *f)
711{
712 if (f && *f)
713 {
c7fc522f 714 PerlIOl *l = PerlIOBase(f);
715 return (l->tab->Set_ptrcnt != NULL);
9e353e3b 716 }
c7fc522f 717 return 0;
760ac839 718}
719
720#undef PerlIO_get_base
888911fc 721STDCHAR *
a20bf0c3 722PerlIO_get_base(PerlIO *f)
760ac839 723{
9e353e3b 724 return (*PerlIOBase(f)->tab->Get_base)(f);
725}
726
727#undef PerlIO_get_bufsiz
728int
729PerlIO_get_bufsiz(PerlIO *f)
730{
731 return (*PerlIOBase(f)->tab->Get_bufsiz)(f);
732}
733
734#undef PerlIO_get_ptr
735STDCHAR *
736PerlIO_get_ptr(PerlIO *f)
737{
738 return (*PerlIOBase(f)->tab->Get_ptr)(f);
739}
740
741#undef PerlIO_get_cnt
05d1247b 742int
9e353e3b 743PerlIO_get_cnt(PerlIO *f)
744{
745 return (*PerlIOBase(f)->tab->Get_cnt)(f);
746}
747
748#undef PerlIO_set_cnt
749void
05d1247b 750PerlIO_set_cnt(PerlIO *f,int cnt)
9e353e3b 751{
f3862f8b 752 (*PerlIOBase(f)->tab->Set_ptrcnt)(f,NULL,cnt);
9e353e3b 753}
754
755#undef PerlIO_set_ptrcnt
756void
05d1247b 757PerlIO_set_ptrcnt(PerlIO *f, STDCHAR *ptr, int cnt)
9e353e3b 758{
f3862f8b 759 (*PerlIOBase(f)->tab->Set_ptrcnt)(f,ptr,cnt);
9e353e3b 760}
761
762/*--------------------------------------------------------------------------------------*/
763/* "Methods" of the "base class" */
764
765IV
766PerlIOBase_fileno(PerlIO *f)
767{
768 return PerlIO_fileno(PerlIONext(f));
769}
770
76ced9ad 771IV
772PerlIOBase_pushed(PerlIO *f, const char *mode)
9e353e3b 773{
76ced9ad 774 PerlIOl *l = PerlIOBase(f);
775 l->flags &= ~(PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
776 PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
777 if (mode)
6f9d8c32 778 {
76ced9ad 779 switch (*mode++)
06da4f11 780 {
76ced9ad 781 case 'r':
782 l->flags = PERLIO_F_CANREAD;
783 break;
784 case 'a':
785 l->flags = PERLIO_F_APPEND|PERLIO_F_CANWRITE;
786 break;
787 case 'w':
788 l->flags = PERLIO_F_TRUNCATE|PERLIO_F_CANWRITE;
789 break;
790 default:
791 errno = EINVAL;
792 return -1;
793 }
794 while (*mode)
795 {
796 switch (*mode++)
797 {
798 case '+':
799 l->flags |= PERLIO_F_CANREAD|PERLIO_F_CANWRITE;
800 break;
801 case 'b':
802 l->flags |= PERLIO_F_BINARY;
803 break;
804 default:
805 errno = EINVAL;
806 return -1;
807 }
06da4f11 808 }
6f9d8c32 809 }
76ced9ad 810 else
811 {
812 if (l->next)
813 {
814 l->flags |= l->next->flags &
815 (PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
816 PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
817 }
818 }
819 return 0;
820}
821
822IV
823PerlIOBase_popped(PerlIO *f)
824{
825 return 0;
760ac839 826}
827
9e353e3b 828SSize_t
829PerlIOBase_unread(PerlIO *f, const void *vbuf, Size_t count)
830{
831 Off_t old = PerlIO_tell(f);
832 if (PerlIO_seek(f,-((Off_t)count),SEEK_CUR) == 0)
833 {
834 Off_t new = PerlIO_tell(f);
835 return old - new;
836 }
837 return 0;
838}
839
840IV
06da4f11 841PerlIOBase_noop_ok(PerlIO *f)
9e353e3b 842{
843 return 0;
844}
845
846IV
06da4f11 847PerlIOBase_noop_fail(PerlIO *f)
848{
849 return -1;
850}
851
852IV
9e353e3b 853PerlIOBase_close(PerlIO *f)
854{
855 IV code = 0;
856 if (PerlIO_flush(f) != 0)
857 code = -1;
858 if (PerlIO_close(PerlIONext(f)) != 0)
859 code = -1;
860 PerlIOBase(f)->flags &= ~(PERLIO_F_CANREAD|PERLIO_F_CANWRITE|PERLIO_F_OPEN);
861 return code;
862}
863
864IV
865PerlIOBase_eof(PerlIO *f)
866{
867 if (f && *f)
868 {
869 return (PerlIOBase(f)->flags & PERLIO_F_EOF) != 0;
870 }
871 return 1;
872}
873
874IV
875PerlIOBase_error(PerlIO *f)
876{
877 if (f && *f)
878 {
879 return (PerlIOBase(f)->flags & PERLIO_F_ERROR) != 0;
880 }
881 return 1;
882}
883
884void
885PerlIOBase_clearerr(PerlIO *f)
886{
887 if (f && *f)
888 {
889 PerlIOBase(f)->flags &= ~PERLIO_F_ERROR;
890 }
891}
892
893void
894PerlIOBase_setlinebuf(PerlIO *f)
895{
896
897}
898
9e353e3b 899/*--------------------------------------------------------------------------------------*/
900/* Bottom-most level for UNIX-like case */
901
902typedef struct
903{
904 struct _PerlIO base; /* The generic part */
905 int fd; /* UNIX like file descriptor */
906 int oflags; /* open/fcntl flags */
907} PerlIOUnix;
908
6f9d8c32 909int
9e353e3b 910PerlIOUnix_oflags(const char *mode)
760ac839 911{
9e353e3b 912 int oflags = -1;
913 switch(*mode)
914 {
915 case 'r':
916 oflags = O_RDONLY;
917 if (*++mode == '+')
918 {
919 oflags = O_RDWR;
920 mode++;
921 }
922 break;
923
924 case 'w':
925 oflags = O_CREAT|O_TRUNC;
926 if (*++mode == '+')
927 {
928 oflags |= O_RDWR;
929 mode++;
930 }
931 else
932 oflags |= O_WRONLY;
933 break;
934
935 case 'a':
936 oflags = O_CREAT|O_APPEND;
937 if (*++mode == '+')
938 {
939 oflags |= O_RDWR;
940 mode++;
941 }
942 else
943 oflags |= O_WRONLY;
944 break;
945 }
83b075c3 946 if (*mode == 'b')
947 {
948 oflags |= O_BINARY;
949 mode++;
950 }
9e353e3b 951 if (*mode || oflags == -1)
6f9d8c32 952 {
9e353e3b 953 errno = EINVAL;
954 oflags = -1;
6f9d8c32 955 }
9e353e3b 956 return oflags;
957}
958
959IV
960PerlIOUnix_fileno(PerlIO *f)
961{
962 return PerlIOSelf(f,PerlIOUnix)->fd;
963}
964
965PerlIO *
06da4f11 966PerlIOUnix_fdopen(PerlIO_funcs *self, int fd,const char *mode)
9e353e3b 967{
968 PerlIO *f = NULL;
c7fc522f 969 if (*mode == 'I')
970 mode++;
9e353e3b 971 if (fd >= 0)
972 {
973 int oflags = PerlIOUnix_oflags(mode);
974 if (oflags != -1)
975 {
06da4f11 976 PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
9e353e3b 977 s->fd = fd;
978 s->oflags = oflags;
979 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
980 }
981 }
982 return f;
983}
984
985PerlIO *
06da4f11 986PerlIOUnix_open(PerlIO_funcs *self, const char *path,const char *mode)
9e353e3b 987{
988 PerlIO *f = NULL;
989 int oflags = PerlIOUnix_oflags(mode);
990 if (oflags != -1)
991 {
00b02797 992 int fd = PerlLIO_open3(path,oflags,0666);
9e353e3b 993 if (fd >= 0)
994 {
06da4f11 995 PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
9e353e3b 996 s->fd = fd;
997 s->oflags = oflags;
998 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
999 }
1000 }
1001 return f;
760ac839 1002}
1003
760ac839 1004int
9e353e3b 1005PerlIOUnix_reopen(const char *path, const char *mode, PerlIO *f)
760ac839 1006{
9e353e3b 1007 PerlIOUnix *s = PerlIOSelf(f,PerlIOUnix);
1008 int oflags = PerlIOUnix_oflags(mode);
1009 if (PerlIOBase(f)->flags & PERLIO_F_OPEN)
1010 (*PerlIOBase(f)->tab->Close)(f);
1011 if (oflags != -1)
1012 {
00b02797 1013 int fd = PerlLIO_open3(path,oflags,0666);
9e353e3b 1014 if (fd >= 0)
1015 {
1016 s->fd = fd;
1017 s->oflags = oflags;
1018 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
1019 return 0;
1020 }
1021 }
1022 return -1;
1023}
1024
1025SSize_t
1026PerlIOUnix_read(PerlIO *f, void *vbuf, Size_t count)
1027{
1028 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
8f24bd79 1029 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
1030 return 0;
9e353e3b 1031 while (1)
1032 {
00b02797 1033 SSize_t len = PerlLIO_read(fd,vbuf,count);
9e353e3b 1034 if (len >= 0 || errno != EINTR)
06da4f11 1035 {
1036 if (len < 0)
1037 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1038 else if (len == 0 && count != 0)
1039 PerlIOBase(f)->flags |= PERLIO_F_EOF;
1040 return len;
1041 }
9e353e3b 1042 }
1043}
1044
1045SSize_t
1046PerlIOUnix_write(PerlIO *f, const void *vbuf, Size_t count)
1047{
1048 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
1049 while (1)
1050 {
00b02797 1051 SSize_t len = PerlLIO_write(fd,vbuf,count);
9e353e3b 1052 if (len >= 0 || errno != EINTR)
06da4f11 1053 {
1054 if (len < 0)
1055 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1056 return len;
1057 }
9e353e3b 1058 }
1059}
1060
1061IV
1062PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence)
1063{
00b02797 1064 Off_t new = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence);
06da4f11 1065 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
9e353e3b 1066 return (new == (Off_t) -1) ? -1 : 0;
1067}
1068
1069Off_t
1070PerlIOUnix_tell(PerlIO *f)
1071{
00b02797 1072 return PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
9e353e3b 1073}
1074
1075IV
1076PerlIOUnix_close(PerlIO *f)
1077{
1078 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
1079 int code = 0;
00b02797 1080 while (PerlLIO_close(fd) != 0)
9e353e3b 1081 {
1082 if (errno != EINTR)
1083 {
1084 code = -1;
1085 break;
1086 }
1087 }
1088 if (code == 0)
1089 {
1090 PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
1091 }
1092 return code;
1093}
1094
1095PerlIO_funcs PerlIO_unix = {
1096 "unix",
1097 sizeof(PerlIOUnix),
1098 0,
1099 PerlIOUnix_fileno,
1100 PerlIOUnix_fdopen,
1101 PerlIOUnix_open,
1102 PerlIOUnix_reopen,
06da4f11 1103 PerlIOBase_pushed,
1104 PerlIOBase_noop_ok,
9e353e3b 1105 PerlIOUnix_read,
1106 PerlIOBase_unread,
1107 PerlIOUnix_write,
1108 PerlIOUnix_seek,
1109 PerlIOUnix_tell,
1110 PerlIOUnix_close,
76ced9ad 1111 PerlIOBase_noop_ok, /* flush */
1112 PerlIOBase_noop_fail, /* fill */
9e353e3b 1113 PerlIOBase_eof,
1114 PerlIOBase_error,
1115 PerlIOBase_clearerr,
1116 PerlIOBase_setlinebuf,
1117 NULL, /* get_base */
1118 NULL, /* get_bufsiz */
1119 NULL, /* get_ptr */
1120 NULL, /* get_cnt */
1121 NULL, /* set_ptrcnt */
1122};
1123
1124/*--------------------------------------------------------------------------------------*/
1125/* stdio as a layer */
1126
1127typedef struct
1128{
1129 struct _PerlIO base;
1130 FILE * stdio; /* The stream */
1131} PerlIOStdio;
1132
1133IV
1134PerlIOStdio_fileno(PerlIO *f)
1135{
1136 return fileno(PerlIOSelf(f,PerlIOStdio)->stdio);
1137}
1138
1139
1140PerlIO *
06da4f11 1141PerlIOStdio_fdopen(PerlIO_funcs *self, int fd,const char *mode)
9e353e3b 1142{
1143 PerlIO *f = NULL;
c7fc522f 1144 int init = 0;
1145 if (*mode == 'I')
1146 {
1147 init = 1;
1148 mode++;
1149 }
9e353e3b 1150 if (fd >= 0)
1151 {
c7fc522f 1152 FILE *stdio = NULL;
1153 if (init)
1154 {
1155 switch(fd)
1156 {
1157 case 0:
1158 stdio = stdin;
1159 break;
1160 case 1:
1161 stdio = stdout;
1162 break;
1163 case 2:
1164 stdio = stderr;
1165 break;
1166 }
1167 }
1168 else
1169 stdio = fdopen(fd,mode);
9e353e3b 1170 if (stdio)
1171 {
06da4f11 1172 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOStdio);
9e353e3b 1173 s->stdio = stdio;
1174 }
1175 }
1176 return f;
1177}
1178
1179#undef PerlIO_importFILE
1180PerlIO *
1181PerlIO_importFILE(FILE *stdio, int fl)
1182{
1183 PerlIO *f = NULL;
1184 if (stdio)
1185 {
1186 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),&PerlIO_stdio,"r+"),PerlIOStdio);
1187 s->stdio = stdio;
1188 }
1189 return f;
1190}
1191
1192PerlIO *
06da4f11 1193PerlIOStdio_open(PerlIO_funcs *self, const char *path,const char *mode)
9e353e3b 1194{
1195 PerlIO *f = NULL;
1196 FILE *stdio = fopen(path,mode);
1197 if (stdio)
1198 {
06da4f11 1199 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOStdio);
9e353e3b 1200 s->stdio = stdio;
1201 }
1202 return f;
760ac839 1203}
1204
6f9d8c32 1205int
9e353e3b 1206PerlIOStdio_reopen(const char *path, const char *mode, PerlIO *f)
1207{
1208 PerlIOStdio *s = PerlIOSelf(f,PerlIOStdio);
1209 FILE *stdio = freopen(path,mode,s->stdio);
1210 if (!s->stdio)
1211 return -1;
1212 s->stdio = stdio;
1213 return 0;
1214}
1215
1216SSize_t
1217PerlIOStdio_read(PerlIO *f, void *vbuf, Size_t count)
1218{
1219 FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
c7fc522f 1220 SSize_t got = 0;
9e353e3b 1221 if (count == 1)
1222 {
1223 STDCHAR *buf = (STDCHAR *) vbuf;
1224 /* Perl is expecting PerlIO_getc() to fill the buffer
1225 * Linux's stdio does not do that for fread()
1226 */
1227 int ch = fgetc(s);
1228 if (ch != EOF)
1229 {
1230 *buf = ch;
c7fc522f 1231 got = 1;
9e353e3b 1232 }
9e353e3b 1233 }
c7fc522f 1234 else
1235 got = fread(vbuf,1,count,s);
1236 return got;
9e353e3b 1237}
1238
1239SSize_t
1240PerlIOStdio_unread(PerlIO *f, const void *vbuf, Size_t count)
1241{
1242 FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
1243 STDCHAR *buf = ((STDCHAR *)vbuf)+count-1;
1244 SSize_t unread = 0;
1245 while (count > 0)
1246 {
1247 int ch = *buf-- & 0xff;
1248 if (ungetc(ch,s) != ch)
1249 break;
1250 unread++;
1251 count--;
1252 }
1253 return unread;
1254}
1255
1256SSize_t
1257PerlIOStdio_write(PerlIO *f, const void *vbuf, Size_t count)
1258{
1259 return fwrite(vbuf,1,count,PerlIOSelf(f,PerlIOStdio)->stdio);
1260}
1261
1262IV
1263PerlIOStdio_seek(PerlIO *f, Off_t offset, int whence)
1264{
c7fc522f 1265 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1266 return fseek(stdio,offset,whence);
9e353e3b 1267}
1268
1269Off_t
1270PerlIOStdio_tell(PerlIO *f)
1271{
c7fc522f 1272 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1273 return ftell(stdio);
9e353e3b 1274}
1275
1276IV
1277PerlIOStdio_close(PerlIO *f)
1278{
1279 return fclose(PerlIOSelf(f,PerlIOStdio)->stdio);
1280}
1281
1282IV
1283PerlIOStdio_flush(PerlIO *f)
1284{
1285 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
88b61e10 1286 if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE)
1287 {
1288 return fflush(stdio);
1289 }
1290 else
1291 {
1292#if 0
1293 /* FIXME: This discards ungetc() and pre-read stuff which is
1294 not right if this is just a "sync" from a layer above
1295 Suspect right design is to do _this_ but not have layer above
1296 flush this layer read-to-read
1297 */
1298 /* Not writeable - sync by attempting a seek */
1299 int err = errno;
1300 if (fseek(stdio,(Off_t) 0, SEEK_CUR) != 0)
1301 errno = err;
1302#endif
1303 }
1304 return 0;
9e353e3b 1305}
1306
1307IV
06da4f11 1308PerlIOStdio_fill(PerlIO *f)
1309{
1310 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1311 int c;
1312 if (fflush(stdio) != 0)
1313 return EOF;
1314 c = fgetc(stdio);
1315 if (c == EOF || ungetc(c,stdio) != c)
1316 return EOF;
1317 return 0;
1318}
1319
1320IV
9e353e3b 1321PerlIOStdio_eof(PerlIO *f)
1322{
1323 return feof(PerlIOSelf(f,PerlIOStdio)->stdio);
1324}
1325
1326IV
1327PerlIOStdio_error(PerlIO *f)
1328{
1329 return ferror(PerlIOSelf(f,PerlIOStdio)->stdio);
1330}
1331
1332void
1333PerlIOStdio_clearerr(PerlIO *f)
1334{
1335 clearerr(PerlIOSelf(f,PerlIOStdio)->stdio);
1336}
1337
1338void
1339PerlIOStdio_setlinebuf(PerlIO *f)
1340{
1341#ifdef HAS_SETLINEBUF
1342 setlinebuf(PerlIOSelf(f,PerlIOStdio)->stdio);
1343#else
1344 setvbuf(PerlIOSelf(f,PerlIOStdio)->stdio, Nullch, _IOLBF, 0);
1345#endif
1346}
1347
1348#ifdef FILE_base
1349STDCHAR *
1350PerlIOStdio_get_base(PerlIO *f)
1351{
1352 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1353 return FILE_base(stdio);
1354}
1355
1356Size_t
1357PerlIOStdio_get_bufsiz(PerlIO *f)
1358{
1359 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1360 return FILE_bufsiz(stdio);
1361}
1362#endif
1363
1364#ifdef USE_STDIO_PTR
1365STDCHAR *
1366PerlIOStdio_get_ptr(PerlIO *f)
1367{
1368 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1369 return FILE_ptr(stdio);
1370}
1371
1372SSize_t
1373PerlIOStdio_get_cnt(PerlIO *f)
1374{
1375 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1376 return FILE_cnt(stdio);
1377}
1378
1379void
1380PerlIOStdio_set_ptrcnt(PerlIO *f,STDCHAR *ptr,SSize_t cnt)
1381{
1382 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1383 if (ptr != NULL)
1384 {
1385#ifdef STDIO_PTR_LVALUE
1386 FILE_ptr(stdio) = ptr;
1387#ifdef STDIO_PTR_LVAL_SETS_CNT
1388 if (FILE_cnt(stdio) != (cnt))
1389 {
1390 dTHX;
1391 assert(FILE_cnt(stdio) == (cnt));
1392 }
1393#endif
1394#if (!defined(STDIO_PTR_LVAL_NOCHANGE_CNT))
1395 /* Setting ptr _does_ change cnt - we are done */
1396 return;
1397#endif
1398#else /* STDIO_PTR_LVALUE */
1399 abort();
1400#endif /* STDIO_PTR_LVALUE */
1401 }
1402/* Now (or only) set cnt */
1403#ifdef STDIO_CNT_LVALUE
1404 FILE_cnt(stdio) = cnt;
1405#else /* STDIO_CNT_LVALUE */
1406#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
1407 FILE_ptr(stdio) = FILE_ptr(stdio)+(FILE_cnt(stdio)-cnt);
1408#else /* STDIO_PTR_LVAL_SETS_CNT */
1409 abort();
1410#endif /* STDIO_PTR_LVAL_SETS_CNT */
1411#endif /* STDIO_CNT_LVALUE */
1412}
1413
1414#endif
1415
1416PerlIO_funcs PerlIO_stdio = {
1417 "stdio",
1418 sizeof(PerlIOStdio),
1419 0,
1420 PerlIOStdio_fileno,
1421 PerlIOStdio_fdopen,
1422 PerlIOStdio_open,
1423 PerlIOStdio_reopen,
06da4f11 1424 PerlIOBase_pushed,
1425 PerlIOBase_noop_ok,
9e353e3b 1426 PerlIOStdio_read,
1427 PerlIOStdio_unread,
1428 PerlIOStdio_write,
1429 PerlIOStdio_seek,
1430 PerlIOStdio_tell,
1431 PerlIOStdio_close,
1432 PerlIOStdio_flush,
06da4f11 1433 PerlIOStdio_fill,
9e353e3b 1434 PerlIOStdio_eof,
1435 PerlIOStdio_error,
1436 PerlIOStdio_clearerr,
1437 PerlIOStdio_setlinebuf,
1438#ifdef FILE_base
1439 PerlIOStdio_get_base,
1440 PerlIOStdio_get_bufsiz,
1441#else
1442 NULL,
1443 NULL,
1444#endif
1445#ifdef USE_STDIO_PTR
1446 PerlIOStdio_get_ptr,
1447 PerlIOStdio_get_cnt,
0eb1d8a4 1448#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
9e353e3b 1449 PerlIOStdio_set_ptrcnt
1450#else /* STDIO_PTR_LVALUE */
1451 NULL
1452#endif /* STDIO_PTR_LVALUE */
1453#else /* USE_STDIO_PTR */
1454 NULL,
1455 NULL,
1456 NULL
1457#endif /* USE_STDIO_PTR */
1458};
1459
1460#undef PerlIO_exportFILE
1461FILE *
1462PerlIO_exportFILE(PerlIO *f, int fl)
1463{
1464 PerlIO_flush(f);
1465 /* Should really push stdio discipline when we have them */
1466 return fdopen(PerlIO_fileno(f),"r+");
1467}
1468
1469#undef PerlIO_findFILE
1470FILE *
1471PerlIO_findFILE(PerlIO *f)
1472{
1473 return PerlIO_exportFILE(f,0);
1474}
1475
1476#undef PerlIO_releaseFILE
1477void
1478PerlIO_releaseFILE(PerlIO *p, FILE *f)
1479{
1480}
1481
1482/*--------------------------------------------------------------------------------------*/
1483/* perlio buffer layer */
1484
9e353e3b 1485PerlIO *
06da4f11 1486PerlIOBuf_fdopen(PerlIO_funcs *self, int fd, const char *mode)
9e353e3b 1487{
1488 PerlIO_funcs *tab = PerlIO_default_btm();
c7fc522f 1489 int init = 0;
1490 PerlIO *f;
1491 if (*mode == 'I')
1492 {
1493 init = 1;
1494 mode++;
1495 }
06da4f11 1496 f = (*tab->Fdopen)(tab,fd,mode);
6f9d8c32 1497 if (f)
1498 {
c7fc522f 1499 /* Initial stderr is unbuffered */
1500 if (!init || fd != 2)
1501 {
06da4f11 1502 PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,NULL),PerlIOBuf);
c7fc522f 1503 b->posn = PerlIO_tell(PerlIONext(f));
1504 }
6f9d8c32 1505 }
9e353e3b 1506 return f;
760ac839 1507}
1508
9e353e3b 1509PerlIO *
06da4f11 1510PerlIOBuf_open(PerlIO_funcs *self, const char *path, const char *mode)
8c86a920 1511{
9e353e3b 1512 PerlIO_funcs *tab = PerlIO_default_btm();
06da4f11 1513 PerlIO *f = (*tab->Open)(tab,path,mode);
9e353e3b 1514 if (f)
1515 {
06da4f11 1516 PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,NULL),PerlIOBuf);
c3d7c7c9 1517 b->posn = PerlIO_tell(PerlIONext(f));
9e353e3b 1518 }
1519 return f;
1520}
1521
1522int
c3d7c7c9 1523PerlIOBuf_reopen(const char *path, const char *mode, PerlIO *f)
9e353e3b 1524{
c3d7c7c9 1525 PerlIO *next = PerlIONext(f);
1526 int code = (*PerlIOBase(next)->tab->Reopen)(path,mode,next);
1527 if (code = 0)
1528 code = (*PerlIOBase(f)->tab->Pushed)(f,mode);
1529 if (code == 0)
1530 {
1531 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1532 b->posn = PerlIO_tell(PerlIONext(f));
1533 }
1534 return code;
9e353e3b 1535}
1536
9e353e3b 1537/* This "flush" is akin to sfio's sync in that it handles files in either
1538 read or write state
1539*/
1540IV
1541PerlIOBuf_flush(PerlIO *f)
6f9d8c32 1542{
9e353e3b 1543 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1544 int code = 0;
1545 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
1546 {
1547 /* write() the buffer */
1548 STDCHAR *p = b->buf;
1549 int count;
1550 while (p < b->ptr)
1551 {
1552 count = PerlIO_write(PerlIONext(f),p,b->ptr - p);
1553 if (count > 0)
1554 {
1555 p += count;
1556 }
1557 else if (count < 0)
1558 {
1559 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1560 code = -1;
1561 break;
1562 }
1563 }
1564 b->posn += (p - b->buf);
1565 }
1566 else if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
6f9d8c32 1567 {
9e353e3b 1568 /* Note position change */
1569 b->posn += (b->ptr - b->buf);
1570 if (b->ptr < b->end)
1571 {
1572 /* We did not consume all of it */
1573 if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) == 0)
1574 {
1575 b->posn = PerlIO_tell(PerlIONext(f));
1576 }
1577 }
6f9d8c32 1578 }
9e353e3b 1579 b->ptr = b->end = b->buf;
1580 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
88b61e10 1581 /* FIXME: Is this right for read case ? */
9e353e3b 1582 if (PerlIO_flush(PerlIONext(f)) != 0)
1583 code = -1;
1584 return code;
6f9d8c32 1585}
1586
06da4f11 1587IV
1588PerlIOBuf_fill(PerlIO *f)
1589{
1590 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
88b61e10 1591 PerlIO *n = PerlIONext(f);
06da4f11 1592 SSize_t avail;
88b61e10 1593 /* FIXME: doing the down-stream flush is a bad idea if it causes
1594 pre-read data in stdio buffer to be discarded
1595 but this is too simplistic - as it skips _our_ hosekeeping
1596 and breaks tell tests.
1597 if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
1598 {
1599 }
1600 */
06da4f11 1601 if (PerlIO_flush(f) != 0)
1602 return -1;
88b61e10 1603
06da4f11 1604 b->ptr = b->end = b->buf;
88b61e10 1605 if (PerlIO_fast_gets(n))
1606 {
1607 /* Layer below is also buffered
1608 * We do _NOT_ want to call its ->Read() because that will loop
1609 * till it gets what we asked for which may hang on a pipe etc.
1610 * Instead take anything it has to hand, or ask it to fill _once_.
1611 */
1612 avail = PerlIO_get_cnt(n);
1613 if (avail <= 0)
1614 {
1615 avail = PerlIO_fill(n);
1616 if (avail == 0)
1617 avail = PerlIO_get_cnt(n);
1618 else
1619 {
1620 if (!PerlIO_error(n) && PerlIO_eof(n))
1621 avail = 0;
1622 }
1623 }
1624 if (avail > 0)
1625 {
1626 STDCHAR *ptr = PerlIO_get_ptr(n);
1627 SSize_t cnt = avail;
1628 if (avail > b->bufsiz)
1629 avail = b->bufsiz;
1630 Copy(ptr,b->buf,avail,STDCHAR);
1631 PerlIO_set_ptrcnt(n,ptr+avail,cnt-avail);
1632 }
1633 }
1634 else
1635 {
1636 avail = PerlIO_read(n,b->ptr,b->bufsiz);
1637 }
06da4f11 1638 if (avail <= 0)
1639 {
1640 if (avail == 0)
1641 PerlIOBase(f)->flags |= PERLIO_F_EOF;
1642 else
1643 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1644 return -1;
1645 }
1646 b->end = b->buf+avail;
1647 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
1648 return 0;
1649}
1650
6f9d8c32 1651SSize_t
9e353e3b 1652PerlIOBuf_read(PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 1653{
9e353e3b 1654 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
6f9d8c32 1655 STDCHAR *buf = (STDCHAR *) vbuf;
1656 if (f)
1657 {
1658 Size_t got = 0;
9e353e3b 1659 if (!b->ptr)
06da4f11 1660 PerlIO_get_base(f);
9e353e3b 1661 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
f89522bf 1662 return 0;
6f9d8c32 1663 while (count > 0)
1664 {
9e353e3b 1665 SSize_t avail = (b->end - b->ptr);
6f9d8c32 1666 if ((SSize_t) count < avail)
1667 avail = count;
1668 if (avail > 0)
1669 {
88b61e10 1670 Copy(b->ptr,buf,avail,STDCHAR);
6f9d8c32 1671 got += avail;
9e353e3b 1672 b->ptr += avail;
6f9d8c32 1673 count -= avail;
1674 buf += avail;
1675 }
9e353e3b 1676 if (count && (b->ptr >= b->end))
6f9d8c32 1677 {
06da4f11 1678 if (PerlIO_fill(f) != 0)
1679 break;
6f9d8c32 1680 }
1681 }
1682 return got;
1683 }
1684 return 0;
1685}
1686
9e353e3b 1687SSize_t
1688PerlIOBuf_unread(PerlIO *f, const void *vbuf, Size_t count)
760ac839 1689{
9e353e3b 1690 const STDCHAR *buf = (const STDCHAR *) vbuf+count;
1691 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1692 SSize_t unread = 0;
1693 SSize_t avail;
9e353e3b 1694 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
1695 PerlIO_flush(f);
06da4f11 1696 if (!b->buf)
1697 PerlIO_get_base(f);
9e353e3b 1698 if (b->buf)
1699 {
1700 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
1701 {
1702 avail = (b->ptr - b->buf);
1703 if (avail > (SSize_t) count)
1704 avail = count;
1705 b->ptr -= avail;
1706 }
1707 else
1708 {
1709 avail = b->bufsiz;
1710 if (avail > (SSize_t) count)
1711 avail = count;
1712 b->end = b->ptr + avail;
1713 }
1714 if (avail > 0)
1715 {
1716 buf -= avail;
1717 if (buf != b->ptr)
1718 {
88b61e10 1719 Copy(buf,b->ptr,avail,STDCHAR);
9e353e3b 1720 }
1721 count -= avail;
1722 unread += avail;
1723 PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
1724 }
1725 }
1726 return unread;
760ac839 1727}
1728
9e353e3b 1729SSize_t
1730PerlIOBuf_write(PerlIO *f, const void *vbuf, Size_t count)
760ac839 1731{
9e353e3b 1732 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1733 const STDCHAR *buf = (const STDCHAR *) vbuf;
1734 Size_t written = 0;
1735 if (!b->buf)
06da4f11 1736 PerlIO_get_base(f);
9e353e3b 1737 if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
1738 return 0;
1739 while (count > 0)
1740 {
1741 SSize_t avail = b->bufsiz - (b->ptr - b->buf);
1742 if ((SSize_t) count < avail)
1743 avail = count;
1744 PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
1745 if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF)
1746 {
1747 while (avail > 0)
1748 {
1749 int ch = *buf++;
1750 *(b->ptr)++ = ch;
1751 count--;
1752 avail--;
1753 written++;
1754 if (ch == '\n')
1755 {
1756 PerlIO_flush(f);
1757 break;
1758 }
1759 }
1760 }
1761 else
1762 {
1763 if (avail)
1764 {
88b61e10 1765 Copy(buf,b->ptr,avail,STDCHAR);
9e353e3b 1766 count -= avail;
1767 buf += avail;
1768 written += avail;
1769 b->ptr += avail;
1770 }
1771 }
1772 if (b->ptr >= (b->buf + b->bufsiz))
1773 PerlIO_flush(f);
1774 }
1775 return written;
1776}
1777
1778IV
1779PerlIOBuf_seek(PerlIO *f, Off_t offset, int whence)
1780{
1781 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
06da4f11 1782 int code = PerlIO_flush(f);
9e353e3b 1783 if (code == 0)
1784 {
1785 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
1786 code = PerlIO_seek(PerlIONext(f),offset,whence);
1787 if (code == 0)
1788 {
1789 b->posn = PerlIO_tell(PerlIONext(f));
1790 }
1791 }
1792 return code;
1793}
1794
1795Off_t
1796PerlIOBuf_tell(PerlIO *f)
1797{
1798 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1799 Off_t posn = b->posn;
1800 if (b->buf)
1801 posn += (b->ptr - b->buf);
1802 return posn;
1803}
1804
1805IV
1806PerlIOBuf_close(PerlIO *f)
1807{
1808 IV code = PerlIOBase_close(f);
1809 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1810 if (b->buf && b->buf != (STDCHAR *) &b->oneword)
6f9d8c32 1811 {
9e353e3b 1812 Safefree(b->buf);
6f9d8c32 1813 }
9e353e3b 1814 b->buf = NULL;
1815 b->ptr = b->end = b->buf;
1816 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
1817 return code;
760ac839 1818}
1819
760ac839 1820void
9e353e3b 1821PerlIOBuf_setlinebuf(PerlIO *f)
760ac839 1822{
6f9d8c32 1823 if (f)
1824 {
9e353e3b 1825 PerlIOBase(f)->flags &= ~PERLIO_F_LINEBUF;
6f9d8c32 1826 }
760ac839 1827}
1828
9e353e3b 1829STDCHAR *
1830PerlIOBuf_get_ptr(PerlIO *f)
1831{
1832 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1833 if (!b->buf)
06da4f11 1834 PerlIO_get_base(f);
9e353e3b 1835 return b->ptr;
1836}
1837
05d1247b 1838SSize_t
9e353e3b 1839PerlIOBuf_get_cnt(PerlIO *f)
1840{
1841 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1842 if (!b->buf)
06da4f11 1843 PerlIO_get_base(f);
9e353e3b 1844 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
1845 return (b->end - b->ptr);
1846 return 0;
1847}
1848
1849STDCHAR *
1850PerlIOBuf_get_base(PerlIO *f)
1851{
1852 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1853 if (!b->buf)
06da4f11 1854 {
1855 if (!b->bufsiz)
1856 b->bufsiz = 4096;
1857 New('B',b->buf,b->bufsiz,STDCHAR);
1858 if (!b->buf)
1859 {
1860 b->buf = (STDCHAR *)&b->oneword;
1861 b->bufsiz = sizeof(b->oneword);
1862 }
1863 b->ptr = b->buf;
1864 b->end = b->ptr;
1865 }
9e353e3b 1866 return b->buf;
1867}
1868
1869Size_t
1870PerlIOBuf_bufsiz(PerlIO *f)
1871{
1872 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1873 if (!b->buf)
06da4f11 1874 PerlIO_get_base(f);
9e353e3b 1875 return (b->end - b->buf);
1876}
1877
1878void
05d1247b 1879PerlIOBuf_set_ptrcnt(PerlIO *f, STDCHAR *ptr, SSize_t cnt)
9e353e3b 1880{
1881 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1882 if (!b->buf)
06da4f11 1883 PerlIO_get_base(f);
9e353e3b 1884 b->ptr = ptr;
1885 if (PerlIO_get_cnt(f) != cnt || b->ptr < b->buf)
6f9d8c32 1886 {
9e353e3b 1887 dTHX;
1888 assert(PerlIO_get_cnt(f) == cnt);
1889 assert(b->ptr >= b->buf);
6f9d8c32 1890 }
9e353e3b 1891 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
760ac839 1892}
1893
9e353e3b 1894PerlIO_funcs PerlIO_perlio = {
1895 "perlio",
1896 sizeof(PerlIOBuf),
1897 0,
1898 PerlIOBase_fileno,
1899 PerlIOBuf_fdopen,
1900 PerlIOBuf_open,
c3d7c7c9 1901 PerlIOBuf_reopen,
06da4f11 1902 PerlIOBase_pushed,
1903 PerlIOBase_noop_ok,
9e353e3b 1904 PerlIOBuf_read,
1905 PerlIOBuf_unread,
1906 PerlIOBuf_write,
1907 PerlIOBuf_seek,
1908 PerlIOBuf_tell,
1909 PerlIOBuf_close,
1910 PerlIOBuf_flush,
06da4f11 1911 PerlIOBuf_fill,
9e353e3b 1912 PerlIOBase_eof,
1913 PerlIOBase_error,
1914 PerlIOBase_clearerr,
1915 PerlIOBuf_setlinebuf,
1916 PerlIOBuf_get_base,
1917 PerlIOBuf_bufsiz,
1918 PerlIOBuf_get_ptr,
1919 PerlIOBuf_get_cnt,
1920 PerlIOBuf_set_ptrcnt,
1921};
1922
66ecd56b 1923/*--------------------------------------------------------------------------------------*/
1924/* crlf - translation currently just a copy of perlio to prove
1925 that extra buffering which real one will do is not an issue.
1926 */
1927
1928PerlIO_funcs PerlIO_crlf = {
1929 "crlf",
1930 sizeof(PerlIOBuf),
1931 0,
1932 PerlIOBase_fileno,
1933 PerlIOBuf_fdopen,
1934 PerlIOBuf_open,
1935 PerlIOBuf_reopen,
1936 PerlIOBase_pushed,
1937 PerlIOBase_noop_ok,
1938 PerlIOBuf_read,
1939 PerlIOBuf_unread,
1940 PerlIOBuf_write,
1941 PerlIOBuf_seek,
1942 PerlIOBuf_tell,
1943 PerlIOBuf_close,
1944 PerlIOBuf_flush,
1945 PerlIOBuf_fill,
1946 PerlIOBase_eof,
1947 PerlIOBase_error,
1948 PerlIOBase_clearerr,
1949 PerlIOBuf_setlinebuf,
1950 PerlIOBuf_get_base,
1951 PerlIOBuf_bufsiz,
1952 PerlIOBuf_get_ptr,
1953 PerlIOBuf_get_cnt,
1954 PerlIOBuf_set_ptrcnt,
1955};
1956
06da4f11 1957#ifdef HAS_MMAP
1958/*--------------------------------------------------------------------------------------*/
1959/* mmap as "buffer" layer */
1960
1961typedef struct
1962{
1963 PerlIOBuf base; /* PerlIOBuf stuff */
c3d7c7c9 1964 Mmap_t mptr; /* Mapped address */
06da4f11 1965 Size_t len; /* mapped length */
1966 STDCHAR *bbuf; /* malloced buffer if map fails */
c3d7c7c9 1967
06da4f11 1968} PerlIOMmap;
1969
c3d7c7c9 1970static size_t page_size = 0;
1971
06da4f11 1972IV
1973PerlIOMmap_map(PerlIO *f)
1974{
68d873c6 1975 dTHX;
06da4f11 1976 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1977 PerlIOBuf *b = &m->base;
1978 IV flags = PerlIOBase(f)->flags;
1979 IV code = 0;
1980 if (m->len)
1981 abort();
1982 if (flags & PERLIO_F_CANREAD)
1983 {
1984 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1985 int fd = PerlIO_fileno(f);
1986 struct stat st;
1987 code = fstat(fd,&st);
1988 if (code == 0 && S_ISREG(st.st_mode))
1989 {
1990 SSize_t len = st.st_size - b->posn;
1991 if (len > 0)
1992 {
c3d7c7c9 1993 Off_t posn;
68d873c6 1994 if (!page_size) {
1995#if defined(HAS_SYSCONF) && (defined(_SC_PAGESIZE) || defined(_SC_PAGE_SIZE))
1996 {
1997 SETERRNO(0,SS$_NORMAL);
1998# ifdef _SC_PAGESIZE
1999 page_size = sysconf(_SC_PAGESIZE);
2000# else
2001 page_size = sysconf(_SC_PAGE_SIZE);
14aaf8e8 2002# endif
68d873c6 2003 if ((long)page_size < 0) {
2004 if (errno) {
2005 SV *error = ERRSV;
2006 char *msg;
2007 STRLEN n_a;
2008 (void)SvUPGRADE(error, SVt_PV);
2009 msg = SvPVx(error, n_a);
14aaf8e8 2010 Perl_croak(aTHX_ "panic: sysconf: %s", msg);
68d873c6 2011 }
2012 else
14aaf8e8 2013 Perl_croak(aTHX_ "panic: sysconf: pagesize unknown");
68d873c6 2014 }
2015 }
2016#else
2017# ifdef HAS_GETPAGESIZE
c3d7c7c9 2018 page_size = getpagesize();
68d873c6 2019# else
2020# if defined(I_SYS_PARAM) && defined(PAGESIZE)
2021 page_size = PAGESIZE; /* compiletime, bad */
2022# endif
2023# endif
2024#endif
2025 if ((IV)page_size <= 0)
14aaf8e8 2026 Perl_croak(aTHX_ "panic: bad pagesize %"IVdf, (IV)page_size);
68d873c6 2027 }
c3d7c7c9 2028 if (b->posn < 0)
2029 {
2030 /* This is a hack - should never happen - open should have set it ! */
2031 b->posn = PerlIO_tell(PerlIONext(f));
2032 }
2033 posn = (b->posn / page_size) * page_size;
2034 len = st.st_size - posn;
2035 m->mptr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, posn);
2036 if (m->mptr && m->mptr != (Mmap_t) -1)
06da4f11 2037 {
2038#if defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
c3d7c7c9 2039 madvise(m->mptr, len, MADV_SEQUENTIAL);
06da4f11 2040#endif
c3d7c7c9 2041 PerlIOBase(f)->flags = (flags & ~PERLIO_F_EOF) | PERLIO_F_RDBUF;
2042 b->end = ((STDCHAR *)m->mptr) + len;
2043 b->buf = ((STDCHAR *)m->mptr) + (b->posn - posn);
2044 b->ptr = b->buf;
2045 m->len = len;
06da4f11 2046 }
2047 else
2048 {
2049 b->buf = NULL;
2050 }
2051 }
2052 else
2053 {
2054 PerlIOBase(f)->flags = flags | PERLIO_F_EOF | PERLIO_F_RDBUF;
2055 b->buf = NULL;
2056 b->ptr = b->end = b->ptr;
2057 code = -1;
2058 }
2059 }
2060 }
2061 return code;
2062}
2063
2064IV
2065PerlIOMmap_unmap(PerlIO *f)
2066{
2067 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2068 PerlIOBuf *b = &m->base;
2069 IV code = 0;
2070 if (m->len)
2071 {
2072 if (b->buf)
2073 {
c3d7c7c9 2074 code = munmap(m->mptr, m->len);
2075 b->buf = NULL;
2076 m->len = 0;
2077 m->mptr = NULL;
06da4f11 2078 if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) != 0)
2079 code = -1;
06da4f11 2080 }
2081 b->ptr = b->end = b->buf;
2082 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
2083 }
2084 return code;
2085}
2086
2087STDCHAR *
2088PerlIOMmap_get_base(PerlIO *f)
2089{
2090 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2091 PerlIOBuf *b = &m->base;
2092 if (b->buf && (PerlIOBase(f)->flags & PERLIO_F_RDBUF))
2093 {
2094 /* Already have a readbuffer in progress */
2095 return b->buf;
2096 }
2097 if (b->buf)
2098 {
2099 /* We have a write buffer or flushed PerlIOBuf read buffer */
2100 m->bbuf = b->buf; /* save it in case we need it again */
2101 b->buf = NULL; /* Clear to trigger below */
2102 }
2103 if (!b->buf)
2104 {
2105 PerlIOMmap_map(f); /* Try and map it */
2106 if (!b->buf)
2107 {
2108 /* Map did not work - recover PerlIOBuf buffer if we have one */
2109 b->buf = m->bbuf;
2110 }
2111 }
2112 b->ptr = b->end = b->buf;
2113 if (b->buf)
2114 return b->buf;
2115 return PerlIOBuf_get_base(f);
2116}
2117
2118SSize_t
2119PerlIOMmap_unread(PerlIO *f, const void *vbuf, Size_t count)
2120{
2121 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2122 PerlIOBuf *b = &m->base;
2123 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
2124 PerlIO_flush(f);
2125 if (b->ptr && (b->ptr - count) >= b->buf && memEQ(b->ptr - count,vbuf,count))
2126 {
2127 b->ptr -= count;
2128 PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
2129 return count;
2130 }
2131 if (m->len)
2132 {
4a4a6116 2133 /* Loose the unwritable mapped buffer */
06da4f11 2134 PerlIO_flush(f);
c3d7c7c9 2135 /* If flush took the "buffer" see if we have one from before */
2136 if (!b->buf && m->bbuf)
2137 b->buf = m->bbuf;
2138 if (!b->buf)
2139 {
2140 PerlIOBuf_get_base(f);
2141 m->bbuf = b->buf;
2142 }
06da4f11 2143 }
2144 return PerlIOBuf_unread(f,vbuf,count);
2145}
2146
2147SSize_t
2148PerlIOMmap_write(PerlIO *f, const void *vbuf, Size_t count)
2149{
2150 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2151 PerlIOBuf *b = &m->base;
2152 if (!b->buf || !(PerlIOBase(f)->flags & PERLIO_F_WRBUF))
2153 {
2154 /* No, or wrong sort of, buffer */
2155 if (m->len)
2156 {
2157 if (PerlIOMmap_unmap(f) != 0)
2158 return 0;
2159 }
2160 /* If unmap took the "buffer" see if we have one from before */
2161 if (!b->buf && m->bbuf)
2162 b->buf = m->bbuf;
2163 if (!b->buf)
2164 {
2165 PerlIOBuf_get_base(f);
2166 m->bbuf = b->buf;
2167 }
2168 }
2169 return PerlIOBuf_write(f,vbuf,count);
2170}
2171
2172IV
2173PerlIOMmap_flush(PerlIO *f)
2174{
2175 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2176 PerlIOBuf *b = &m->base;
2177 IV code = PerlIOBuf_flush(f);
2178 /* Now we are "synced" at PerlIOBuf level */
2179 if (b->buf)
2180 {
2181 if (m->len)
2182 {
2183 /* Unmap the buffer */
2184 if (PerlIOMmap_unmap(f) != 0)
2185 code = -1;
2186 }
2187 else
2188 {
2189 /* We seem to have a PerlIOBuf buffer which was not mapped
2190 * remember it in case we need one later
2191 */
2192 m->bbuf = b->buf;
2193 }
2194 }
06da4f11 2195 return code;
2196}
2197
2198IV
2199PerlIOMmap_fill(PerlIO *f)
2200{
2201 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2202 IV code = PerlIO_flush(f);
06da4f11 2203 if (code == 0 && !b->buf)
2204 {
2205 code = PerlIOMmap_map(f);
06da4f11 2206 }
2207 if (code == 0 && !(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
2208 {
2209 code = PerlIOBuf_fill(f);
06da4f11 2210 }
2211 return code;
2212}
2213
2214IV
2215PerlIOMmap_close(PerlIO *f)
2216{
2217 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2218 PerlIOBuf *b = &m->base;
2219 IV code = PerlIO_flush(f);
2220 if (m->bbuf)
2221 {
2222 b->buf = m->bbuf;
2223 m->bbuf = NULL;
2224 b->ptr = b->end = b->buf;
2225 }
2226 if (PerlIOBuf_close(f) != 0)
2227 code = -1;
06da4f11 2228 return code;
2229}
2230
2231
2232PerlIO_funcs PerlIO_mmap = {
2233 "mmap",
2234 sizeof(PerlIOMmap),
2235 0,
2236 PerlIOBase_fileno,
2237 PerlIOBuf_fdopen,
2238 PerlIOBuf_open,
c3d7c7c9 2239 PerlIOBuf_reopen,
06da4f11 2240 PerlIOBase_pushed,
2241 PerlIOBase_noop_ok,
2242 PerlIOBuf_read,
2243 PerlIOMmap_unread,
2244 PerlIOMmap_write,
2245 PerlIOBuf_seek,
2246 PerlIOBuf_tell,
2247 PerlIOBuf_close,
2248 PerlIOMmap_flush,
2249 PerlIOMmap_fill,
2250 PerlIOBase_eof,
2251 PerlIOBase_error,
2252 PerlIOBase_clearerr,
2253 PerlIOBuf_setlinebuf,
2254 PerlIOMmap_get_base,
2255 PerlIOBuf_bufsiz,
2256 PerlIOBuf_get_ptr,
2257 PerlIOBuf_get_cnt,
2258 PerlIOBuf_set_ptrcnt,
2259};
2260
2261#endif /* HAS_MMAP */
2262
9e353e3b 2263void
2264PerlIO_init(void)
760ac839 2265{
9e353e3b 2266 if (!_perlio)
6f9d8c32 2267 {
9e353e3b 2268 atexit(&PerlIO_cleanup);
6f9d8c32 2269 }
760ac839 2270}
2271
9e353e3b 2272#undef PerlIO_stdin
2273PerlIO *
2274PerlIO_stdin(void)
2275{
2276 if (!_perlio)
f3862f8b 2277 PerlIO_stdstreams();
05d1247b 2278 return &_perlio[1];
9e353e3b 2279}
2280
2281#undef PerlIO_stdout
2282PerlIO *
2283PerlIO_stdout(void)
2284{
2285 if (!_perlio)
f3862f8b 2286 PerlIO_stdstreams();
05d1247b 2287 return &_perlio[2];
9e353e3b 2288}
2289
2290#undef PerlIO_stderr
2291PerlIO *
2292PerlIO_stderr(void)
2293{
2294 if (!_perlio)
f3862f8b 2295 PerlIO_stdstreams();
05d1247b 2296 return &_perlio[3];
9e353e3b 2297}
2298
2299/*--------------------------------------------------------------------------------------*/
2300
2301#undef PerlIO_getname
2302char *
2303PerlIO_getname(PerlIO *f, char *buf)
2304{
2305 dTHX;
2306 Perl_croak(aTHX_ "Don't know how to get file name");
2307 return NULL;
2308}
2309
2310
2311/*--------------------------------------------------------------------------------------*/
2312/* Functions which can be called on any kind of PerlIO implemented
2313 in terms of above
2314*/
2315
2316#undef PerlIO_getc
6f9d8c32 2317int
9e353e3b 2318PerlIO_getc(PerlIO *f)
760ac839 2319{
313ca112 2320 STDCHAR buf[1];
2321 SSize_t count = PerlIO_read(f,buf,1);
9e353e3b 2322 if (count == 1)
313ca112 2323 {
2324 return (unsigned char) buf[0];
2325 }
2326 return EOF;
2327}
2328
2329#undef PerlIO_ungetc
2330int
2331PerlIO_ungetc(PerlIO *f, int ch)
2332{
2333 if (ch != EOF)
2334 {
2335 STDCHAR buf = ch;
2336 if (PerlIO_unread(f,&buf,1) == 1)
2337 return ch;
2338 }
2339 return EOF;
760ac839 2340}
2341
9e353e3b 2342#undef PerlIO_putc
2343int
2344PerlIO_putc(PerlIO *f, int ch)
760ac839 2345{
9e353e3b 2346 STDCHAR buf = ch;
2347 return PerlIO_write(f,&buf,1);
760ac839 2348}
2349
9e353e3b 2350#undef PerlIO_puts
760ac839 2351int
9e353e3b 2352PerlIO_puts(PerlIO *f, const char *s)
760ac839 2353{
9e353e3b 2354 STRLEN len = strlen(s);
2355 return PerlIO_write(f,s,len);
760ac839 2356}
2357
2358#undef PerlIO_rewind
2359void
c78749f2 2360PerlIO_rewind(PerlIO *f)
760ac839 2361{
6f9d8c32 2362 PerlIO_seek(f,(Off_t)0,SEEK_SET);
9e353e3b 2363 PerlIO_clearerr(f);
6f9d8c32 2364}
2365
2366#undef PerlIO_vprintf
2367int
2368PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
2369{
2370 dTHX;
bb9950b7 2371 SV *sv = newSVpvn("",0);
6f9d8c32 2372 char *s;
2373 STRLEN len;
2cc61e15 2374#ifdef NEED_VA_COPY
2375 va_list apc;
2376 Perl_va_copy(ap, apc);
2377 sv_vcatpvf(sv, fmt, &apc);
2378#else
6f9d8c32 2379 sv_vcatpvf(sv, fmt, &ap);
2cc61e15 2380#endif
6f9d8c32 2381 s = SvPV(sv,len);
bb9950b7 2382 return PerlIO_write(f,s,len);
760ac839 2383}
2384
2385#undef PerlIO_printf
6f9d8c32 2386int
760ac839 2387PerlIO_printf(PerlIO *f,const char *fmt,...)
760ac839 2388{
2389 va_list ap;
2390 int result;
760ac839 2391 va_start(ap,fmt);
6f9d8c32 2392 result = PerlIO_vprintf(f,fmt,ap);
760ac839 2393 va_end(ap);
2394 return result;
2395}
2396
2397#undef PerlIO_stdoutf
6f9d8c32 2398int
760ac839 2399PerlIO_stdoutf(const char *fmt,...)
760ac839 2400{
2401 va_list ap;
2402 int result;
760ac839 2403 va_start(ap,fmt);
760ac839 2404 result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
2405 va_end(ap);
2406 return result;
2407}
2408
2409#undef PerlIO_tmpfile
2410PerlIO *
c78749f2 2411PerlIO_tmpfile(void)
760ac839 2412{
b1ef6e3b 2413 /* I have no idea how portable mkstemp() is ... */
83b075c3 2414#if defined(WIN32) || !defined(HAVE_MKSTEMP)
2415 PerlIO *f = NULL;
2416 FILE *stdio = tmpfile();
2417 if (stdio)
2418 {
2419 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),&PerlIO_stdio,"w+"),PerlIOStdio);
2420 s->stdio = stdio;
2421 }
2422 return f;
2423#else
2424 dTHX;
6f9d8c32 2425 SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
2426 int fd = mkstemp(SvPVX(sv));
2427 PerlIO *f = NULL;
2428 if (fd >= 0)
2429 {
b1ef6e3b 2430 f = PerlIO_fdopen(fd,"w+");
6f9d8c32 2431 if (f)
2432 {
9e353e3b 2433 PerlIOBase(f)->flags |= PERLIO_F_TEMP;
6f9d8c32 2434 }
00b02797 2435 PerlLIO_unlink(SvPVX(sv));
6f9d8c32 2436 SvREFCNT_dec(sv);
2437 }
2438 return f;
83b075c3 2439#endif
760ac839 2440}
2441
6f9d8c32 2442#undef HAS_FSETPOS
2443#undef HAS_FGETPOS
2444
760ac839 2445#endif /* USE_SFIO */
2446#endif /* PERLIO_IS_STDIO */
2447
9e353e3b 2448/*======================================================================================*/
2449/* Now some functions in terms of above which may be needed even if
2450 we are not in true PerlIO mode
2451 */
2452
760ac839 2453#ifndef HAS_FSETPOS
2454#undef PerlIO_setpos
2455int
c78749f2 2456PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
760ac839 2457{
6f9d8c32 2458 return PerlIO_seek(f,*pos,0);
760ac839 2459}
c411622e 2460#else
2461#ifndef PERLIO_IS_STDIO
2462#undef PerlIO_setpos
2463int
c78749f2 2464PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
c411622e 2465{
2d4389e4 2466#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
d9b3e12d 2467 return fsetpos64(f, pos);
2468#else
c411622e 2469 return fsetpos(f, pos);
d9b3e12d 2470#endif
c411622e 2471}
2472#endif
760ac839 2473#endif
2474
2475#ifndef HAS_FGETPOS
2476#undef PerlIO_getpos
2477int
c78749f2 2478PerlIO_getpos(PerlIO *f, Fpos_t *pos)
760ac839 2479{
2480 *pos = PerlIO_tell(f);
a17c7222 2481 return *pos == -1 ? -1 : 0;
760ac839 2482}
c411622e 2483#else
2484#ifndef PERLIO_IS_STDIO
2485#undef PerlIO_getpos
2486int
c78749f2 2487PerlIO_getpos(PerlIO *f, Fpos_t *pos)
c411622e 2488{
2d4389e4 2489#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
d9b3e12d 2490 return fgetpos64(f, pos);
2491#else
c411622e 2492 return fgetpos(f, pos);
d9b3e12d 2493#endif
c411622e 2494}
2495#endif
760ac839 2496#endif
2497
2498#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
2499
2500int
c78749f2 2501vprintf(char *pat, char *args)
662a7e3f 2502{
2503 _doprnt(pat, args, stdout);
2504 return 0; /* wrong, but perl doesn't use the return value */
2505}
2506
2507int
c78749f2 2508vfprintf(FILE *fd, char *pat, char *args)
760ac839 2509{
2510 _doprnt(pat, args, fd);
2511 return 0; /* wrong, but perl doesn't use the return value */
2512}
2513
2514#endif
2515
2516#ifndef PerlIO_vsprintf
6f9d8c32 2517int
8ac85365 2518PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
760ac839 2519{
2520 int val = vsprintf(s, fmt, ap);
2521 if (n >= 0)
2522 {
8c86a920 2523 if (strlen(s) >= (STRLEN)n)
760ac839 2524 {
bf49b057 2525 dTHX;
fb4a9925 2526 (void)PerlIO_puts(Perl_error_log,
2527 "panic: sprintf overflow - memory corrupted!\n");
bf49b057 2528 my_exit(1);
760ac839 2529 }
2530 }
2531 return val;
2532}
2533#endif
2534
2535#ifndef PerlIO_sprintf
6f9d8c32 2536int
760ac839 2537PerlIO_sprintf(char *s, int n, const char *fmt,...)
760ac839 2538{
2539 va_list ap;
2540 int result;
760ac839 2541 va_start(ap,fmt);
760ac839 2542 result = PerlIO_vsprintf(s, n, fmt, ap);
2543 va_end(ap);
2544 return result;
2545}
2546#endif
2547
c5be433b 2548#endif /* !PERL_IMPLICIT_SYS */
2549