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