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