Make extra buffer layer work (dummy crlf layer)
[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 }
946 if (*mode || oflags == -1)
6f9d8c32 947 {
9e353e3b 948 errno = EINVAL;
949 oflags = -1;
6f9d8c32 950 }
9e353e3b 951 return oflags;
952}
953
954IV
955PerlIOUnix_fileno(PerlIO *f)
956{
957 return PerlIOSelf(f,PerlIOUnix)->fd;
958}
959
960PerlIO *
06da4f11 961PerlIOUnix_fdopen(PerlIO_funcs *self, int fd,const char *mode)
9e353e3b 962{
963 PerlIO *f = NULL;
c7fc522f 964 if (*mode == 'I')
965 mode++;
9e353e3b 966 if (fd >= 0)
967 {
968 int oflags = PerlIOUnix_oflags(mode);
969 if (oflags != -1)
970 {
06da4f11 971 PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
9e353e3b 972 s->fd = fd;
973 s->oflags = oflags;
974 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
975 }
976 }
977 return f;
978}
979
980PerlIO *
06da4f11 981PerlIOUnix_open(PerlIO_funcs *self, const char *path,const char *mode)
9e353e3b 982{
983 PerlIO *f = NULL;
984 int oflags = PerlIOUnix_oflags(mode);
985 if (oflags != -1)
986 {
00b02797 987 int fd = PerlLIO_open3(path,oflags,0666);
9e353e3b 988 if (fd >= 0)
989 {
06da4f11 990 PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
9e353e3b 991 s->fd = fd;
992 s->oflags = oflags;
993 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
994 }
995 }
996 return f;
760ac839 997}
998
760ac839 999int
9e353e3b 1000PerlIOUnix_reopen(const char *path, const char *mode, PerlIO *f)
760ac839 1001{
9e353e3b 1002 PerlIOUnix *s = PerlIOSelf(f,PerlIOUnix);
1003 int oflags = PerlIOUnix_oflags(mode);
1004 if (PerlIOBase(f)->flags & PERLIO_F_OPEN)
1005 (*PerlIOBase(f)->tab->Close)(f);
1006 if (oflags != -1)
1007 {
00b02797 1008 int fd = PerlLIO_open3(path,oflags,0666);
9e353e3b 1009 if (fd >= 0)
1010 {
1011 s->fd = fd;
1012 s->oflags = oflags;
1013 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
1014 return 0;
1015 }
1016 }
1017 return -1;
1018}
1019
1020SSize_t
1021PerlIOUnix_read(PerlIO *f, void *vbuf, Size_t count)
1022{
1023 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
8f24bd79 1024 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
1025 return 0;
9e353e3b 1026 while (1)
1027 {
00b02797 1028 SSize_t len = PerlLIO_read(fd,vbuf,count);
9e353e3b 1029 if (len >= 0 || errno != EINTR)
06da4f11 1030 {
1031 if (len < 0)
1032 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1033 else if (len == 0 && count != 0)
1034 PerlIOBase(f)->flags |= PERLIO_F_EOF;
1035 return len;
1036 }
9e353e3b 1037 }
1038}
1039
1040SSize_t
1041PerlIOUnix_write(PerlIO *f, const void *vbuf, Size_t count)
1042{
1043 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
1044 while (1)
1045 {
00b02797 1046 SSize_t len = PerlLIO_write(fd,vbuf,count);
9e353e3b 1047 if (len >= 0 || errno != EINTR)
06da4f11 1048 {
1049 if (len < 0)
1050 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1051 return len;
1052 }
9e353e3b 1053 }
1054}
1055
1056IV
1057PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence)
1058{
00b02797 1059 Off_t new = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence);
06da4f11 1060 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
9e353e3b 1061 return (new == (Off_t) -1) ? -1 : 0;
1062}
1063
1064Off_t
1065PerlIOUnix_tell(PerlIO *f)
1066{
00b02797 1067 return PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
9e353e3b 1068}
1069
1070IV
1071PerlIOUnix_close(PerlIO *f)
1072{
1073 int fd = PerlIOSelf(f,PerlIOUnix)->fd;
1074 int code = 0;
00b02797 1075 while (PerlLIO_close(fd) != 0)
9e353e3b 1076 {
1077 if (errno != EINTR)
1078 {
1079 code = -1;
1080 break;
1081 }
1082 }
1083 if (code == 0)
1084 {
1085 PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
1086 }
1087 return code;
1088}
1089
1090PerlIO_funcs PerlIO_unix = {
1091 "unix",
1092 sizeof(PerlIOUnix),
1093 0,
1094 PerlIOUnix_fileno,
1095 PerlIOUnix_fdopen,
1096 PerlIOUnix_open,
1097 PerlIOUnix_reopen,
06da4f11 1098 PerlIOBase_pushed,
1099 PerlIOBase_noop_ok,
9e353e3b 1100 PerlIOUnix_read,
1101 PerlIOBase_unread,
1102 PerlIOUnix_write,
1103 PerlIOUnix_seek,
1104 PerlIOUnix_tell,
1105 PerlIOUnix_close,
76ced9ad 1106 PerlIOBase_noop_ok, /* flush */
1107 PerlIOBase_noop_fail, /* fill */
9e353e3b 1108 PerlIOBase_eof,
1109 PerlIOBase_error,
1110 PerlIOBase_clearerr,
1111 PerlIOBase_setlinebuf,
1112 NULL, /* get_base */
1113 NULL, /* get_bufsiz */
1114 NULL, /* get_ptr */
1115 NULL, /* get_cnt */
1116 NULL, /* set_ptrcnt */
1117};
1118
1119/*--------------------------------------------------------------------------------------*/
1120/* stdio as a layer */
1121
1122typedef struct
1123{
1124 struct _PerlIO base;
1125 FILE * stdio; /* The stream */
1126} PerlIOStdio;
1127
1128IV
1129PerlIOStdio_fileno(PerlIO *f)
1130{
1131 return fileno(PerlIOSelf(f,PerlIOStdio)->stdio);
1132}
1133
1134
1135PerlIO *
06da4f11 1136PerlIOStdio_fdopen(PerlIO_funcs *self, int fd,const char *mode)
9e353e3b 1137{
1138 PerlIO *f = NULL;
c7fc522f 1139 int init = 0;
1140 if (*mode == 'I')
1141 {
1142 init = 1;
1143 mode++;
1144 }
9e353e3b 1145 if (fd >= 0)
1146 {
c7fc522f 1147 FILE *stdio = NULL;
1148 if (init)
1149 {
1150 switch(fd)
1151 {
1152 case 0:
1153 stdio = stdin;
1154 break;
1155 case 1:
1156 stdio = stdout;
1157 break;
1158 case 2:
1159 stdio = stderr;
1160 break;
1161 }
1162 }
1163 else
1164 stdio = fdopen(fd,mode);
9e353e3b 1165 if (stdio)
1166 {
06da4f11 1167 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOStdio);
9e353e3b 1168 s->stdio = stdio;
1169 }
1170 }
1171 return f;
1172}
1173
1174#undef PerlIO_importFILE
1175PerlIO *
1176PerlIO_importFILE(FILE *stdio, int fl)
1177{
1178 PerlIO *f = NULL;
1179 if (stdio)
1180 {
1181 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),&PerlIO_stdio,"r+"),PerlIOStdio);
1182 s->stdio = stdio;
1183 }
1184 return f;
1185}
1186
1187PerlIO *
06da4f11 1188PerlIOStdio_open(PerlIO_funcs *self, const char *path,const char *mode)
9e353e3b 1189{
1190 PerlIO *f = NULL;
1191 FILE *stdio = fopen(path,mode);
1192 if (stdio)
1193 {
06da4f11 1194 PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOStdio);
9e353e3b 1195 s->stdio = stdio;
1196 }
1197 return f;
760ac839 1198}
1199
6f9d8c32 1200int
9e353e3b 1201PerlIOStdio_reopen(const char *path, const char *mode, PerlIO *f)
1202{
1203 PerlIOStdio *s = PerlIOSelf(f,PerlIOStdio);
1204 FILE *stdio = freopen(path,mode,s->stdio);
1205 if (!s->stdio)
1206 return -1;
1207 s->stdio = stdio;
1208 return 0;
1209}
1210
1211SSize_t
1212PerlIOStdio_read(PerlIO *f, void *vbuf, Size_t count)
1213{
1214 FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
c7fc522f 1215 SSize_t got = 0;
9e353e3b 1216 if (count == 1)
1217 {
1218 STDCHAR *buf = (STDCHAR *) vbuf;
1219 /* Perl is expecting PerlIO_getc() to fill the buffer
1220 * Linux's stdio does not do that for fread()
1221 */
1222 int ch = fgetc(s);
1223 if (ch != EOF)
1224 {
1225 *buf = ch;
c7fc522f 1226 got = 1;
9e353e3b 1227 }
9e353e3b 1228 }
c7fc522f 1229 else
1230 got = fread(vbuf,1,count,s);
1231 return got;
9e353e3b 1232}
1233
1234SSize_t
1235PerlIOStdio_unread(PerlIO *f, const void *vbuf, Size_t count)
1236{
1237 FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
1238 STDCHAR *buf = ((STDCHAR *)vbuf)+count-1;
1239 SSize_t unread = 0;
1240 while (count > 0)
1241 {
1242 int ch = *buf-- & 0xff;
1243 if (ungetc(ch,s) != ch)
1244 break;
1245 unread++;
1246 count--;
1247 }
1248 return unread;
1249}
1250
1251SSize_t
1252PerlIOStdio_write(PerlIO *f, const void *vbuf, Size_t count)
1253{
1254 return fwrite(vbuf,1,count,PerlIOSelf(f,PerlIOStdio)->stdio);
1255}
1256
1257IV
1258PerlIOStdio_seek(PerlIO *f, Off_t offset, int whence)
1259{
c7fc522f 1260 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1261 return fseek(stdio,offset,whence);
9e353e3b 1262}
1263
1264Off_t
1265PerlIOStdio_tell(PerlIO *f)
1266{
c7fc522f 1267 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1268 return ftell(stdio);
9e353e3b 1269}
1270
1271IV
1272PerlIOStdio_close(PerlIO *f)
1273{
1274 return fclose(PerlIOSelf(f,PerlIOStdio)->stdio);
1275}
1276
1277IV
1278PerlIOStdio_flush(PerlIO *f)
1279{
1280 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
88b61e10 1281 if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE)
1282 {
1283 return fflush(stdio);
1284 }
1285 else
1286 {
1287#if 0
1288 /* FIXME: This discards ungetc() and pre-read stuff which is
1289 not right if this is just a "sync" from a layer above
1290 Suspect right design is to do _this_ but not have layer above
1291 flush this layer read-to-read
1292 */
1293 /* Not writeable - sync by attempting a seek */
1294 int err = errno;
1295 if (fseek(stdio,(Off_t) 0, SEEK_CUR) != 0)
1296 errno = err;
1297#endif
1298 }
1299 return 0;
9e353e3b 1300}
1301
1302IV
06da4f11 1303PerlIOStdio_fill(PerlIO *f)
1304{
1305 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1306 int c;
1307 if (fflush(stdio) != 0)
1308 return EOF;
1309 c = fgetc(stdio);
1310 if (c == EOF || ungetc(c,stdio) != c)
1311 return EOF;
1312 return 0;
1313}
1314
1315IV
9e353e3b 1316PerlIOStdio_eof(PerlIO *f)
1317{
1318 return feof(PerlIOSelf(f,PerlIOStdio)->stdio);
1319}
1320
1321IV
1322PerlIOStdio_error(PerlIO *f)
1323{
1324 return ferror(PerlIOSelf(f,PerlIOStdio)->stdio);
1325}
1326
1327void
1328PerlIOStdio_clearerr(PerlIO *f)
1329{
1330 clearerr(PerlIOSelf(f,PerlIOStdio)->stdio);
1331}
1332
1333void
1334PerlIOStdio_setlinebuf(PerlIO *f)
1335{
1336#ifdef HAS_SETLINEBUF
1337 setlinebuf(PerlIOSelf(f,PerlIOStdio)->stdio);
1338#else
1339 setvbuf(PerlIOSelf(f,PerlIOStdio)->stdio, Nullch, _IOLBF, 0);
1340#endif
1341}
1342
1343#ifdef FILE_base
1344STDCHAR *
1345PerlIOStdio_get_base(PerlIO *f)
1346{
1347 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1348 return FILE_base(stdio);
1349}
1350
1351Size_t
1352PerlIOStdio_get_bufsiz(PerlIO *f)
1353{
1354 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1355 return FILE_bufsiz(stdio);
1356}
1357#endif
1358
1359#ifdef USE_STDIO_PTR
1360STDCHAR *
1361PerlIOStdio_get_ptr(PerlIO *f)
1362{
1363 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1364 return FILE_ptr(stdio);
1365}
1366
1367SSize_t
1368PerlIOStdio_get_cnt(PerlIO *f)
1369{
1370 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1371 return FILE_cnt(stdio);
1372}
1373
1374void
1375PerlIOStdio_set_ptrcnt(PerlIO *f,STDCHAR *ptr,SSize_t cnt)
1376{
1377 FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1378 if (ptr != NULL)
1379 {
1380#ifdef STDIO_PTR_LVALUE
1381 FILE_ptr(stdio) = ptr;
1382#ifdef STDIO_PTR_LVAL_SETS_CNT
1383 if (FILE_cnt(stdio) != (cnt))
1384 {
1385 dTHX;
1386 assert(FILE_cnt(stdio) == (cnt));
1387 }
1388#endif
1389#if (!defined(STDIO_PTR_LVAL_NOCHANGE_CNT))
1390 /* Setting ptr _does_ change cnt - we are done */
1391 return;
1392#endif
1393#else /* STDIO_PTR_LVALUE */
1394 abort();
1395#endif /* STDIO_PTR_LVALUE */
1396 }
1397/* Now (or only) set cnt */
1398#ifdef STDIO_CNT_LVALUE
1399 FILE_cnt(stdio) = cnt;
1400#else /* STDIO_CNT_LVALUE */
1401#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
1402 FILE_ptr(stdio) = FILE_ptr(stdio)+(FILE_cnt(stdio)-cnt);
1403#else /* STDIO_PTR_LVAL_SETS_CNT */
1404 abort();
1405#endif /* STDIO_PTR_LVAL_SETS_CNT */
1406#endif /* STDIO_CNT_LVALUE */
1407}
1408
1409#endif
1410
1411PerlIO_funcs PerlIO_stdio = {
1412 "stdio",
1413 sizeof(PerlIOStdio),
1414 0,
1415 PerlIOStdio_fileno,
1416 PerlIOStdio_fdopen,
1417 PerlIOStdio_open,
1418 PerlIOStdio_reopen,
06da4f11 1419 PerlIOBase_pushed,
1420 PerlIOBase_noop_ok,
9e353e3b 1421 PerlIOStdio_read,
1422 PerlIOStdio_unread,
1423 PerlIOStdio_write,
1424 PerlIOStdio_seek,
1425 PerlIOStdio_tell,
1426 PerlIOStdio_close,
1427 PerlIOStdio_flush,
06da4f11 1428 PerlIOStdio_fill,
9e353e3b 1429 PerlIOStdio_eof,
1430 PerlIOStdio_error,
1431 PerlIOStdio_clearerr,
1432 PerlIOStdio_setlinebuf,
1433#ifdef FILE_base
1434 PerlIOStdio_get_base,
1435 PerlIOStdio_get_bufsiz,
1436#else
1437 NULL,
1438 NULL,
1439#endif
1440#ifdef USE_STDIO_PTR
1441 PerlIOStdio_get_ptr,
1442 PerlIOStdio_get_cnt,
0eb1d8a4 1443#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
9e353e3b 1444 PerlIOStdio_set_ptrcnt
1445#else /* STDIO_PTR_LVALUE */
1446 NULL
1447#endif /* STDIO_PTR_LVALUE */
1448#else /* USE_STDIO_PTR */
1449 NULL,
1450 NULL,
1451 NULL
1452#endif /* USE_STDIO_PTR */
1453};
1454
1455#undef PerlIO_exportFILE
1456FILE *
1457PerlIO_exportFILE(PerlIO *f, int fl)
1458{
1459 PerlIO_flush(f);
1460 /* Should really push stdio discipline when we have them */
1461 return fdopen(PerlIO_fileno(f),"r+");
1462}
1463
1464#undef PerlIO_findFILE
1465FILE *
1466PerlIO_findFILE(PerlIO *f)
1467{
1468 return PerlIO_exportFILE(f,0);
1469}
1470
1471#undef PerlIO_releaseFILE
1472void
1473PerlIO_releaseFILE(PerlIO *p, FILE *f)
1474{
1475}
1476
1477/*--------------------------------------------------------------------------------------*/
1478/* perlio buffer layer */
1479
9e353e3b 1480PerlIO *
06da4f11 1481PerlIOBuf_fdopen(PerlIO_funcs *self, int fd, const char *mode)
9e353e3b 1482{
1483 PerlIO_funcs *tab = PerlIO_default_btm();
c7fc522f 1484 int init = 0;
1485 PerlIO *f;
1486 if (*mode == 'I')
1487 {
1488 init = 1;
1489 mode++;
1490 }
06da4f11 1491 f = (*tab->Fdopen)(tab,fd,mode);
6f9d8c32 1492 if (f)
1493 {
c7fc522f 1494 /* Initial stderr is unbuffered */
1495 if (!init || fd != 2)
1496 {
06da4f11 1497 PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,NULL),PerlIOBuf);
c7fc522f 1498 b->posn = PerlIO_tell(PerlIONext(f));
1499 }
6f9d8c32 1500 }
9e353e3b 1501 return f;
760ac839 1502}
1503
9e353e3b 1504PerlIO *
06da4f11 1505PerlIOBuf_open(PerlIO_funcs *self, const char *path, const char *mode)
8c86a920 1506{
9e353e3b 1507 PerlIO_funcs *tab = PerlIO_default_btm();
06da4f11 1508 PerlIO *f = (*tab->Open)(tab,path,mode);
9e353e3b 1509 if (f)
1510 {
06da4f11 1511 PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,NULL),PerlIOBuf);
c3d7c7c9 1512 b->posn = PerlIO_tell(PerlIONext(f));
9e353e3b 1513 }
1514 return f;
1515}
1516
1517int
c3d7c7c9 1518PerlIOBuf_reopen(const char *path, const char *mode, PerlIO *f)
9e353e3b 1519{
c3d7c7c9 1520 PerlIO *next = PerlIONext(f);
1521 int code = (*PerlIOBase(next)->tab->Reopen)(path,mode,next);
1522 if (code = 0)
1523 code = (*PerlIOBase(f)->tab->Pushed)(f,mode);
1524 if (code == 0)
1525 {
1526 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1527 b->posn = PerlIO_tell(PerlIONext(f));
1528 }
1529 return code;
9e353e3b 1530}
1531
9e353e3b 1532/* This "flush" is akin to sfio's sync in that it handles files in either
1533 read or write state
1534*/
1535IV
1536PerlIOBuf_flush(PerlIO *f)
6f9d8c32 1537{
9e353e3b 1538 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1539 int code = 0;
1540 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
1541 {
1542 /* write() the buffer */
1543 STDCHAR *p = b->buf;
1544 int count;
1545 while (p < b->ptr)
1546 {
1547 count = PerlIO_write(PerlIONext(f),p,b->ptr - p);
1548 if (count > 0)
1549 {
1550 p += count;
1551 }
1552 else if (count < 0)
1553 {
1554 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1555 code = -1;
1556 break;
1557 }
1558 }
1559 b->posn += (p - b->buf);
1560 }
1561 else if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
6f9d8c32 1562 {
9e353e3b 1563 /* Note position change */
1564 b->posn += (b->ptr - b->buf);
1565 if (b->ptr < b->end)
1566 {
1567 /* We did not consume all of it */
1568 if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) == 0)
1569 {
1570 b->posn = PerlIO_tell(PerlIONext(f));
1571 }
1572 }
6f9d8c32 1573 }
9e353e3b 1574 b->ptr = b->end = b->buf;
1575 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
88b61e10 1576 /* FIXME: Is this right for read case ? */
9e353e3b 1577 if (PerlIO_flush(PerlIONext(f)) != 0)
1578 code = -1;
1579 return code;
6f9d8c32 1580}
1581
06da4f11 1582IV
1583PerlIOBuf_fill(PerlIO *f)
1584{
1585 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
88b61e10 1586 PerlIO *n = PerlIONext(f);
06da4f11 1587 SSize_t avail;
88b61e10 1588 /* FIXME: doing the down-stream flush is a bad idea if it causes
1589 pre-read data in stdio buffer to be discarded
1590 but this is too simplistic - as it skips _our_ hosekeeping
1591 and breaks tell tests.
1592 if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
1593 {
1594 }
1595 */
06da4f11 1596 if (PerlIO_flush(f) != 0)
1597 return -1;
88b61e10 1598
06da4f11 1599 b->ptr = b->end = b->buf;
88b61e10 1600 if (PerlIO_fast_gets(n))
1601 {
1602 /* Layer below is also buffered
1603 * We do _NOT_ want to call its ->Read() because that will loop
1604 * till it gets what we asked for which may hang on a pipe etc.
1605 * Instead take anything it has to hand, or ask it to fill _once_.
1606 */
1607 avail = PerlIO_get_cnt(n);
1608 if (avail <= 0)
1609 {
1610 avail = PerlIO_fill(n);
1611 if (avail == 0)
1612 avail = PerlIO_get_cnt(n);
1613 else
1614 {
1615 if (!PerlIO_error(n) && PerlIO_eof(n))
1616 avail = 0;
1617 }
1618 }
1619 if (avail > 0)
1620 {
1621 STDCHAR *ptr = PerlIO_get_ptr(n);
1622 SSize_t cnt = avail;
1623 if (avail > b->bufsiz)
1624 avail = b->bufsiz;
1625 Copy(ptr,b->buf,avail,STDCHAR);
1626 PerlIO_set_ptrcnt(n,ptr+avail,cnt-avail);
1627 }
1628 }
1629 else
1630 {
1631 avail = PerlIO_read(n,b->ptr,b->bufsiz);
1632 }
06da4f11 1633 if (avail <= 0)
1634 {
1635 if (avail == 0)
1636 PerlIOBase(f)->flags |= PERLIO_F_EOF;
1637 else
1638 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
1639 return -1;
1640 }
1641 b->end = b->buf+avail;
1642 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
1643 return 0;
1644}
1645
6f9d8c32 1646SSize_t
9e353e3b 1647PerlIOBuf_read(PerlIO *f, void *vbuf, Size_t count)
6f9d8c32 1648{
9e353e3b 1649 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
6f9d8c32 1650 STDCHAR *buf = (STDCHAR *) vbuf;
1651 if (f)
1652 {
1653 Size_t got = 0;
9e353e3b 1654 if (!b->ptr)
06da4f11 1655 PerlIO_get_base(f);
9e353e3b 1656 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
f89522bf 1657 return 0;
6f9d8c32 1658 while (count > 0)
1659 {
9e353e3b 1660 SSize_t avail = (b->end - b->ptr);
6f9d8c32 1661 if ((SSize_t) count < avail)
1662 avail = count;
1663 if (avail > 0)
1664 {
88b61e10 1665 Copy(b->ptr,buf,avail,STDCHAR);
6f9d8c32 1666 got += avail;
9e353e3b 1667 b->ptr += avail;
6f9d8c32 1668 count -= avail;
1669 buf += avail;
1670 }
9e353e3b 1671 if (count && (b->ptr >= b->end))
6f9d8c32 1672 {
06da4f11 1673 if (PerlIO_fill(f) != 0)
1674 break;
6f9d8c32 1675 }
1676 }
1677 return got;
1678 }
1679 return 0;
1680}
1681
9e353e3b 1682SSize_t
1683PerlIOBuf_unread(PerlIO *f, const void *vbuf, Size_t count)
760ac839 1684{
9e353e3b 1685 const STDCHAR *buf = (const STDCHAR *) vbuf+count;
1686 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1687 SSize_t unread = 0;
1688 SSize_t avail;
9e353e3b 1689 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
1690 PerlIO_flush(f);
06da4f11 1691 if (!b->buf)
1692 PerlIO_get_base(f);
9e353e3b 1693 if (b->buf)
1694 {
1695 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
1696 {
1697 avail = (b->ptr - b->buf);
1698 if (avail > (SSize_t) count)
1699 avail = count;
1700 b->ptr -= avail;
1701 }
1702 else
1703 {
1704 avail = b->bufsiz;
1705 if (avail > (SSize_t) count)
1706 avail = count;
1707 b->end = b->ptr + avail;
1708 }
1709 if (avail > 0)
1710 {
1711 buf -= avail;
1712 if (buf != b->ptr)
1713 {
88b61e10 1714 Copy(buf,b->ptr,avail,STDCHAR);
9e353e3b 1715 }
1716 count -= avail;
1717 unread += avail;
1718 PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
1719 }
1720 }
1721 return unread;
760ac839 1722}
1723
9e353e3b 1724SSize_t
1725PerlIOBuf_write(PerlIO *f, const void *vbuf, Size_t count)
760ac839 1726{
9e353e3b 1727 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1728 const STDCHAR *buf = (const STDCHAR *) vbuf;
1729 Size_t written = 0;
1730 if (!b->buf)
06da4f11 1731 PerlIO_get_base(f);
9e353e3b 1732 if (!(PerlIOBase(f)->flags & PERLIO_F_CANWRITE))
1733 return 0;
1734 while (count > 0)
1735 {
1736 SSize_t avail = b->bufsiz - (b->ptr - b->buf);
1737 if ((SSize_t) count < avail)
1738 avail = count;
1739 PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
1740 if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF)
1741 {
1742 while (avail > 0)
1743 {
1744 int ch = *buf++;
1745 *(b->ptr)++ = ch;
1746 count--;
1747 avail--;
1748 written++;
1749 if (ch == '\n')
1750 {
1751 PerlIO_flush(f);
1752 break;
1753 }
1754 }
1755 }
1756 else
1757 {
1758 if (avail)
1759 {
88b61e10 1760 Copy(buf,b->ptr,avail,STDCHAR);
9e353e3b 1761 count -= avail;
1762 buf += avail;
1763 written += avail;
1764 b->ptr += avail;
1765 }
1766 }
1767 if (b->ptr >= (b->buf + b->bufsiz))
1768 PerlIO_flush(f);
1769 }
1770 return written;
1771}
1772
1773IV
1774PerlIOBuf_seek(PerlIO *f, Off_t offset, int whence)
1775{
1776 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
06da4f11 1777 int code = PerlIO_flush(f);
9e353e3b 1778 if (code == 0)
1779 {
1780 PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
1781 code = PerlIO_seek(PerlIONext(f),offset,whence);
1782 if (code == 0)
1783 {
1784 b->posn = PerlIO_tell(PerlIONext(f));
1785 }
1786 }
1787 return code;
1788}
1789
1790Off_t
1791PerlIOBuf_tell(PerlIO *f)
1792{
1793 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1794 Off_t posn = b->posn;
1795 if (b->buf)
1796 posn += (b->ptr - b->buf);
1797 return posn;
1798}
1799
1800IV
1801PerlIOBuf_close(PerlIO *f)
1802{
1803 IV code = PerlIOBase_close(f);
1804 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1805 if (b->buf && b->buf != (STDCHAR *) &b->oneword)
6f9d8c32 1806 {
9e353e3b 1807 Safefree(b->buf);
6f9d8c32 1808 }
9e353e3b 1809 b->buf = NULL;
1810 b->ptr = b->end = b->buf;
1811 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
1812 return code;
760ac839 1813}
1814
760ac839 1815void
9e353e3b 1816PerlIOBuf_setlinebuf(PerlIO *f)
760ac839 1817{
6f9d8c32 1818 if (f)
1819 {
9e353e3b 1820 PerlIOBase(f)->flags &= ~PERLIO_F_LINEBUF;
6f9d8c32 1821 }
760ac839 1822}
1823
9e353e3b 1824STDCHAR *
1825PerlIOBuf_get_ptr(PerlIO *f)
1826{
1827 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1828 if (!b->buf)
06da4f11 1829 PerlIO_get_base(f);
9e353e3b 1830 return b->ptr;
1831}
1832
05d1247b 1833SSize_t
9e353e3b 1834PerlIOBuf_get_cnt(PerlIO *f)
1835{
1836 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1837 if (!b->buf)
06da4f11 1838 PerlIO_get_base(f);
9e353e3b 1839 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
1840 return (b->end - b->ptr);
1841 return 0;
1842}
1843
1844STDCHAR *
1845PerlIOBuf_get_base(PerlIO *f)
1846{
1847 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1848 if (!b->buf)
06da4f11 1849 {
1850 if (!b->bufsiz)
1851 b->bufsiz = 4096;
1852 New('B',b->buf,b->bufsiz,STDCHAR);
1853 if (!b->buf)
1854 {
1855 b->buf = (STDCHAR *)&b->oneword;
1856 b->bufsiz = sizeof(b->oneword);
1857 }
1858 b->ptr = b->buf;
1859 b->end = b->ptr;
1860 }
9e353e3b 1861 return b->buf;
1862}
1863
1864Size_t
1865PerlIOBuf_bufsiz(PerlIO *f)
1866{
1867 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1868 if (!b->buf)
06da4f11 1869 PerlIO_get_base(f);
9e353e3b 1870 return (b->end - b->buf);
1871}
1872
1873void
05d1247b 1874PerlIOBuf_set_ptrcnt(PerlIO *f, STDCHAR *ptr, SSize_t cnt)
9e353e3b 1875{
1876 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1877 if (!b->buf)
06da4f11 1878 PerlIO_get_base(f);
9e353e3b 1879 b->ptr = ptr;
1880 if (PerlIO_get_cnt(f) != cnt || b->ptr < b->buf)
6f9d8c32 1881 {
9e353e3b 1882 dTHX;
1883 assert(PerlIO_get_cnt(f) == cnt);
1884 assert(b->ptr >= b->buf);
6f9d8c32 1885 }
9e353e3b 1886 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
760ac839 1887}
1888
9e353e3b 1889PerlIO_funcs PerlIO_perlio = {
1890 "perlio",
1891 sizeof(PerlIOBuf),
1892 0,
1893 PerlIOBase_fileno,
1894 PerlIOBuf_fdopen,
1895 PerlIOBuf_open,
c3d7c7c9 1896 PerlIOBuf_reopen,
06da4f11 1897 PerlIOBase_pushed,
1898 PerlIOBase_noop_ok,
9e353e3b 1899 PerlIOBuf_read,
1900 PerlIOBuf_unread,
1901 PerlIOBuf_write,
1902 PerlIOBuf_seek,
1903 PerlIOBuf_tell,
1904 PerlIOBuf_close,
1905 PerlIOBuf_flush,
06da4f11 1906 PerlIOBuf_fill,
9e353e3b 1907 PerlIOBase_eof,
1908 PerlIOBase_error,
1909 PerlIOBase_clearerr,
1910 PerlIOBuf_setlinebuf,
1911 PerlIOBuf_get_base,
1912 PerlIOBuf_bufsiz,
1913 PerlIOBuf_get_ptr,
1914 PerlIOBuf_get_cnt,
1915 PerlIOBuf_set_ptrcnt,
1916};
1917
66ecd56b 1918/*--------------------------------------------------------------------------------------*/
1919/* crlf - translation currently just a copy of perlio to prove
1920 that extra buffering which real one will do is not an issue.
1921 */
1922
1923PerlIO_funcs PerlIO_crlf = {
1924 "crlf",
1925 sizeof(PerlIOBuf),
1926 0,
1927 PerlIOBase_fileno,
1928 PerlIOBuf_fdopen,
1929 PerlIOBuf_open,
1930 PerlIOBuf_reopen,
1931 PerlIOBase_pushed,
1932 PerlIOBase_noop_ok,
1933 PerlIOBuf_read,
1934 PerlIOBuf_unread,
1935 PerlIOBuf_write,
1936 PerlIOBuf_seek,
1937 PerlIOBuf_tell,
1938 PerlIOBuf_close,
1939 PerlIOBuf_flush,
1940 PerlIOBuf_fill,
1941 PerlIOBase_eof,
1942 PerlIOBase_error,
1943 PerlIOBase_clearerr,
1944 PerlIOBuf_setlinebuf,
1945 PerlIOBuf_get_base,
1946 PerlIOBuf_bufsiz,
1947 PerlIOBuf_get_ptr,
1948 PerlIOBuf_get_cnt,
1949 PerlIOBuf_set_ptrcnt,
1950};
1951
06da4f11 1952#ifdef HAS_MMAP
1953/*--------------------------------------------------------------------------------------*/
1954/* mmap as "buffer" layer */
1955
1956typedef struct
1957{
1958 PerlIOBuf base; /* PerlIOBuf stuff */
c3d7c7c9 1959 Mmap_t mptr; /* Mapped address */
06da4f11 1960 Size_t len; /* mapped length */
1961 STDCHAR *bbuf; /* malloced buffer if map fails */
c3d7c7c9 1962
06da4f11 1963} PerlIOMmap;
1964
c3d7c7c9 1965static size_t page_size = 0;
1966
06da4f11 1967IV
1968PerlIOMmap_map(PerlIO *f)
1969{
68d873c6 1970 dTHX;
06da4f11 1971 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1972 PerlIOBuf *b = &m->base;
1973 IV flags = PerlIOBase(f)->flags;
1974 IV code = 0;
1975 if (m->len)
1976 abort();
1977 if (flags & PERLIO_F_CANREAD)
1978 {
1979 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1980 int fd = PerlIO_fileno(f);
1981 struct stat st;
1982 code = fstat(fd,&st);
1983 if (code == 0 && S_ISREG(st.st_mode))
1984 {
1985 SSize_t len = st.st_size - b->posn;
1986 if (len > 0)
1987 {
c3d7c7c9 1988 Off_t posn;
68d873c6 1989 if (!page_size) {
1990#if defined(HAS_SYSCONF) && (defined(_SC_PAGESIZE) || defined(_SC_PAGE_SIZE))
1991 {
1992 SETERRNO(0,SS$_NORMAL);
1993# ifdef _SC_PAGESIZE
1994 page_size = sysconf(_SC_PAGESIZE);
1995# else
1996 page_size = sysconf(_SC_PAGE_SIZE);
14aaf8e8 1997# endif
68d873c6 1998 if ((long)page_size < 0) {
1999 if (errno) {
2000 SV *error = ERRSV;
2001 char *msg;
2002 STRLEN n_a;
2003 (void)SvUPGRADE(error, SVt_PV);
2004 msg = SvPVx(error, n_a);
14aaf8e8 2005 Perl_croak(aTHX_ "panic: sysconf: %s", msg);
68d873c6 2006 }
2007 else
14aaf8e8 2008 Perl_croak(aTHX_ "panic: sysconf: pagesize unknown");
68d873c6 2009 }
2010 }
2011#else
2012# ifdef HAS_GETPAGESIZE
c3d7c7c9 2013 page_size = getpagesize();
68d873c6 2014# else
2015# if defined(I_SYS_PARAM) && defined(PAGESIZE)
2016 page_size = PAGESIZE; /* compiletime, bad */
2017# endif
2018# endif
2019#endif
2020 if ((IV)page_size <= 0)
14aaf8e8 2021 Perl_croak(aTHX_ "panic: bad pagesize %"IVdf, (IV)page_size);
68d873c6 2022 }
c3d7c7c9 2023 if (b->posn < 0)
2024 {
2025 /* This is a hack - should never happen - open should have set it ! */
2026 b->posn = PerlIO_tell(PerlIONext(f));
2027 }
2028 posn = (b->posn / page_size) * page_size;
2029 len = st.st_size - posn;
2030 m->mptr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, posn);
2031 if (m->mptr && m->mptr != (Mmap_t) -1)
06da4f11 2032 {
2033#if defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
c3d7c7c9 2034 madvise(m->mptr, len, MADV_SEQUENTIAL);
06da4f11 2035#endif
c3d7c7c9 2036 PerlIOBase(f)->flags = (flags & ~PERLIO_F_EOF) | PERLIO_F_RDBUF;
2037 b->end = ((STDCHAR *)m->mptr) + len;
2038 b->buf = ((STDCHAR *)m->mptr) + (b->posn - posn);
2039 b->ptr = b->buf;
2040 m->len = len;
06da4f11 2041 }
2042 else
2043 {
2044 b->buf = NULL;
2045 }
2046 }
2047 else
2048 {
2049 PerlIOBase(f)->flags = flags | PERLIO_F_EOF | PERLIO_F_RDBUF;
2050 b->buf = NULL;
2051 b->ptr = b->end = b->ptr;
2052 code = -1;
2053 }
2054 }
2055 }
2056 return code;
2057}
2058
2059IV
2060PerlIOMmap_unmap(PerlIO *f)
2061{
2062 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2063 PerlIOBuf *b = &m->base;
2064 IV code = 0;
2065 if (m->len)
2066 {
2067 if (b->buf)
2068 {
c3d7c7c9 2069 code = munmap(m->mptr, m->len);
2070 b->buf = NULL;
2071 m->len = 0;
2072 m->mptr = NULL;
06da4f11 2073 if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) != 0)
2074 code = -1;
06da4f11 2075 }
2076 b->ptr = b->end = b->buf;
2077 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
2078 }
2079 return code;
2080}
2081
2082STDCHAR *
2083PerlIOMmap_get_base(PerlIO *f)
2084{
2085 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2086 PerlIOBuf *b = &m->base;
2087 if (b->buf && (PerlIOBase(f)->flags & PERLIO_F_RDBUF))
2088 {
2089 /* Already have a readbuffer in progress */
2090 return b->buf;
2091 }
2092 if (b->buf)
2093 {
2094 /* We have a write buffer or flushed PerlIOBuf read buffer */
2095 m->bbuf = b->buf; /* save it in case we need it again */
2096 b->buf = NULL; /* Clear to trigger below */
2097 }
2098 if (!b->buf)
2099 {
2100 PerlIOMmap_map(f); /* Try and map it */
2101 if (!b->buf)
2102 {
2103 /* Map did not work - recover PerlIOBuf buffer if we have one */
2104 b->buf = m->bbuf;
2105 }
2106 }
2107 b->ptr = b->end = b->buf;
2108 if (b->buf)
2109 return b->buf;
2110 return PerlIOBuf_get_base(f);
2111}
2112
2113SSize_t
2114PerlIOMmap_unread(PerlIO *f, const void *vbuf, Size_t count)
2115{
2116 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2117 PerlIOBuf *b = &m->base;
2118 if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
2119 PerlIO_flush(f);
2120 if (b->ptr && (b->ptr - count) >= b->buf && memEQ(b->ptr - count,vbuf,count))
2121 {
2122 b->ptr -= count;
2123 PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
2124 return count;
2125 }
2126 if (m->len)
2127 {
4a4a6116 2128 /* Loose the unwritable mapped buffer */
06da4f11 2129 PerlIO_flush(f);
c3d7c7c9 2130 /* If flush took the "buffer" see if we have one from before */
2131 if (!b->buf && m->bbuf)
2132 b->buf = m->bbuf;
2133 if (!b->buf)
2134 {
2135 PerlIOBuf_get_base(f);
2136 m->bbuf = b->buf;
2137 }
06da4f11 2138 }
2139 return PerlIOBuf_unread(f,vbuf,count);
2140}
2141
2142SSize_t
2143PerlIOMmap_write(PerlIO *f, const void *vbuf, Size_t count)
2144{
2145 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2146 PerlIOBuf *b = &m->base;
2147 if (!b->buf || !(PerlIOBase(f)->flags & PERLIO_F_WRBUF))
2148 {
2149 /* No, or wrong sort of, buffer */
2150 if (m->len)
2151 {
2152 if (PerlIOMmap_unmap(f) != 0)
2153 return 0;
2154 }
2155 /* If unmap took the "buffer" see if we have one from before */
2156 if (!b->buf && m->bbuf)
2157 b->buf = m->bbuf;
2158 if (!b->buf)
2159 {
2160 PerlIOBuf_get_base(f);
2161 m->bbuf = b->buf;
2162 }
2163 }
2164 return PerlIOBuf_write(f,vbuf,count);
2165}
2166
2167IV
2168PerlIOMmap_flush(PerlIO *f)
2169{
2170 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2171 PerlIOBuf *b = &m->base;
2172 IV code = PerlIOBuf_flush(f);
2173 /* Now we are "synced" at PerlIOBuf level */
2174 if (b->buf)
2175 {
2176 if (m->len)
2177 {
2178 /* Unmap the buffer */
2179 if (PerlIOMmap_unmap(f) != 0)
2180 code = -1;
2181 }
2182 else
2183 {
2184 /* We seem to have a PerlIOBuf buffer which was not mapped
2185 * remember it in case we need one later
2186 */
2187 m->bbuf = b->buf;
2188 }
2189 }
06da4f11 2190 return code;
2191}
2192
2193IV
2194PerlIOMmap_fill(PerlIO *f)
2195{
2196 PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
2197 IV code = PerlIO_flush(f);
06da4f11 2198 if (code == 0 && !b->buf)
2199 {
2200 code = PerlIOMmap_map(f);
06da4f11 2201 }
2202 if (code == 0 && !(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
2203 {
2204 code = PerlIOBuf_fill(f);
06da4f11 2205 }
2206 return code;
2207}
2208
2209IV
2210PerlIOMmap_close(PerlIO *f)
2211{
2212 PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2213 PerlIOBuf *b = &m->base;
2214 IV code = PerlIO_flush(f);
2215 if (m->bbuf)
2216 {
2217 b->buf = m->bbuf;
2218 m->bbuf = NULL;
2219 b->ptr = b->end = b->buf;
2220 }
2221 if (PerlIOBuf_close(f) != 0)
2222 code = -1;
06da4f11 2223 return code;
2224}
2225
2226
2227PerlIO_funcs PerlIO_mmap = {
2228 "mmap",
2229 sizeof(PerlIOMmap),
2230 0,
2231 PerlIOBase_fileno,
2232 PerlIOBuf_fdopen,
2233 PerlIOBuf_open,
c3d7c7c9 2234 PerlIOBuf_reopen,
06da4f11 2235 PerlIOBase_pushed,
2236 PerlIOBase_noop_ok,
2237 PerlIOBuf_read,
2238 PerlIOMmap_unread,
2239 PerlIOMmap_write,
2240 PerlIOBuf_seek,
2241 PerlIOBuf_tell,
2242 PerlIOBuf_close,
2243 PerlIOMmap_flush,
2244 PerlIOMmap_fill,
2245 PerlIOBase_eof,
2246 PerlIOBase_error,
2247 PerlIOBase_clearerr,
2248 PerlIOBuf_setlinebuf,
2249 PerlIOMmap_get_base,
2250 PerlIOBuf_bufsiz,
2251 PerlIOBuf_get_ptr,
2252 PerlIOBuf_get_cnt,
2253 PerlIOBuf_set_ptrcnt,
2254};
2255
2256#endif /* HAS_MMAP */
2257
9e353e3b 2258void
2259PerlIO_init(void)
760ac839 2260{
9e353e3b 2261 if (!_perlio)
6f9d8c32 2262 {
9e353e3b 2263 atexit(&PerlIO_cleanup);
6f9d8c32 2264 }
760ac839 2265}
2266
9e353e3b 2267#undef PerlIO_stdin
2268PerlIO *
2269PerlIO_stdin(void)
2270{
2271 if (!_perlio)
f3862f8b 2272 PerlIO_stdstreams();
05d1247b 2273 return &_perlio[1];
9e353e3b 2274}
2275
2276#undef PerlIO_stdout
2277PerlIO *
2278PerlIO_stdout(void)
2279{
2280 if (!_perlio)
f3862f8b 2281 PerlIO_stdstreams();
05d1247b 2282 return &_perlio[2];
9e353e3b 2283}
2284
2285#undef PerlIO_stderr
2286PerlIO *
2287PerlIO_stderr(void)
2288{
2289 if (!_perlio)
f3862f8b 2290 PerlIO_stdstreams();
05d1247b 2291 return &_perlio[3];
9e353e3b 2292}
2293
2294/*--------------------------------------------------------------------------------------*/
2295
2296#undef PerlIO_getname
2297char *
2298PerlIO_getname(PerlIO *f, char *buf)
2299{
2300 dTHX;
2301 Perl_croak(aTHX_ "Don't know how to get file name");
2302 return NULL;
2303}
2304
2305
2306/*--------------------------------------------------------------------------------------*/
2307/* Functions which can be called on any kind of PerlIO implemented
2308 in terms of above
2309*/
2310
2311#undef PerlIO_getc
6f9d8c32 2312int
9e353e3b 2313PerlIO_getc(PerlIO *f)
760ac839 2314{
313ca112 2315 STDCHAR buf[1];
2316 SSize_t count = PerlIO_read(f,buf,1);
9e353e3b 2317 if (count == 1)
313ca112 2318 {
2319 return (unsigned char) buf[0];
2320 }
2321 return EOF;
2322}
2323
2324#undef PerlIO_ungetc
2325int
2326PerlIO_ungetc(PerlIO *f, int ch)
2327{
2328 if (ch != EOF)
2329 {
2330 STDCHAR buf = ch;
2331 if (PerlIO_unread(f,&buf,1) == 1)
2332 return ch;
2333 }
2334 return EOF;
760ac839 2335}
2336
9e353e3b 2337#undef PerlIO_putc
2338int
2339PerlIO_putc(PerlIO *f, int ch)
760ac839 2340{
9e353e3b 2341 STDCHAR buf = ch;
2342 return PerlIO_write(f,&buf,1);
760ac839 2343}
2344
9e353e3b 2345#undef PerlIO_puts
760ac839 2346int
9e353e3b 2347PerlIO_puts(PerlIO *f, const char *s)
760ac839 2348{
9e353e3b 2349 STRLEN len = strlen(s);
2350 return PerlIO_write(f,s,len);
760ac839 2351}
2352
2353#undef PerlIO_rewind
2354void
c78749f2 2355PerlIO_rewind(PerlIO *f)
760ac839 2356{
6f9d8c32 2357 PerlIO_seek(f,(Off_t)0,SEEK_SET);
9e353e3b 2358 PerlIO_clearerr(f);
6f9d8c32 2359}
2360
2361#undef PerlIO_vprintf
2362int
2363PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
2364{
2365 dTHX;
bb9950b7 2366 SV *sv = newSVpvn("",0);
6f9d8c32 2367 char *s;
2368 STRLEN len;
2369 sv_vcatpvf(sv, fmt, &ap);
2370 s = SvPV(sv,len);
bb9950b7 2371 return PerlIO_write(f,s,len);
760ac839 2372}
2373
2374#undef PerlIO_printf
6f9d8c32 2375int
760ac839 2376PerlIO_printf(PerlIO *f,const char *fmt,...)
760ac839 2377{
2378 va_list ap;
2379 int result;
760ac839 2380 va_start(ap,fmt);
6f9d8c32 2381 result = PerlIO_vprintf(f,fmt,ap);
760ac839 2382 va_end(ap);
2383 return result;
2384}
2385
2386#undef PerlIO_stdoutf
6f9d8c32 2387int
760ac839 2388PerlIO_stdoutf(const char *fmt,...)
760ac839 2389{
2390 va_list ap;
2391 int result;
760ac839 2392 va_start(ap,fmt);
760ac839 2393 result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
2394 va_end(ap);
2395 return result;
2396}
2397
2398#undef PerlIO_tmpfile
2399PerlIO *
c78749f2 2400PerlIO_tmpfile(void)
760ac839 2401{
6f9d8c32 2402 dTHX;
b1ef6e3b 2403 /* I have no idea how portable mkstemp() is ... */
6f9d8c32 2404 SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
2405 int fd = mkstemp(SvPVX(sv));
2406 PerlIO *f = NULL;
2407 if (fd >= 0)
2408 {
b1ef6e3b 2409 f = PerlIO_fdopen(fd,"w+");
6f9d8c32 2410 if (f)
2411 {
9e353e3b 2412 PerlIOBase(f)->flags |= PERLIO_F_TEMP;
6f9d8c32 2413 }
00b02797 2414 PerlLIO_unlink(SvPVX(sv));
6f9d8c32 2415 SvREFCNT_dec(sv);
2416 }
2417 return f;
760ac839 2418}
2419
6f9d8c32 2420#undef HAS_FSETPOS
2421#undef HAS_FGETPOS
2422
760ac839 2423#endif /* USE_SFIO */
2424#endif /* PERLIO_IS_STDIO */
2425
9e353e3b 2426/*======================================================================================*/
2427/* Now some functions in terms of above which may be needed even if
2428 we are not in true PerlIO mode
2429 */
2430
760ac839 2431#ifndef HAS_FSETPOS
2432#undef PerlIO_setpos
2433int
c78749f2 2434PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
760ac839 2435{
6f9d8c32 2436 return PerlIO_seek(f,*pos,0);
760ac839 2437}
c411622e 2438#else
2439#ifndef PERLIO_IS_STDIO
2440#undef PerlIO_setpos
2441int
c78749f2 2442PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
c411622e 2443{
2d4389e4 2444#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
d9b3e12d 2445 return fsetpos64(f, pos);
2446#else
c411622e 2447 return fsetpos(f, pos);
d9b3e12d 2448#endif
c411622e 2449}
2450#endif
760ac839 2451#endif
2452
2453#ifndef HAS_FGETPOS
2454#undef PerlIO_getpos
2455int
c78749f2 2456PerlIO_getpos(PerlIO *f, Fpos_t *pos)
760ac839 2457{
2458 *pos = PerlIO_tell(f);
a17c7222 2459 return *pos == -1 ? -1 : 0;
760ac839 2460}
c411622e 2461#else
2462#ifndef PERLIO_IS_STDIO
2463#undef PerlIO_getpos
2464int
c78749f2 2465PerlIO_getpos(PerlIO *f, Fpos_t *pos)
c411622e 2466{
2d4389e4 2467#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
d9b3e12d 2468 return fgetpos64(f, pos);
2469#else
c411622e 2470 return fgetpos(f, pos);
d9b3e12d 2471#endif
c411622e 2472}
2473#endif
760ac839 2474#endif
2475
2476#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
2477
2478int
c78749f2 2479vprintf(char *pat, char *args)
662a7e3f 2480{
2481 _doprnt(pat, args, stdout);
2482 return 0; /* wrong, but perl doesn't use the return value */
2483}
2484
2485int
c78749f2 2486vfprintf(FILE *fd, char *pat, char *args)
760ac839 2487{
2488 _doprnt(pat, args, fd);
2489 return 0; /* wrong, but perl doesn't use the return value */
2490}
2491
2492#endif
2493
2494#ifndef PerlIO_vsprintf
6f9d8c32 2495int
8ac85365 2496PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
760ac839 2497{
2498 int val = vsprintf(s, fmt, ap);
2499 if (n >= 0)
2500 {
8c86a920 2501 if (strlen(s) >= (STRLEN)n)
760ac839 2502 {
bf49b057 2503 dTHX;
fb4a9925 2504 (void)PerlIO_puts(Perl_error_log,
2505 "panic: sprintf overflow - memory corrupted!\n");
bf49b057 2506 my_exit(1);
760ac839 2507 }
2508 }
2509 return val;
2510}
2511#endif
2512
2513#ifndef PerlIO_sprintf
6f9d8c32 2514int
760ac839 2515PerlIO_sprintf(char *s, int n, const char *fmt,...)
760ac839 2516{
2517 va_list ap;
2518 int result;
760ac839 2519 va_start(ap,fmt);
760ac839 2520 result = PerlIO_vsprintf(s, n, fmt, ap);
2521 va_end(ap);
2522 return result;
2523}
2524#endif
2525
c5be433b 2526#endif /* !PERL_IMPLICIT_SYS */
2527