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