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