55c6ad31482aac7107b7ecd125651cd020ea4410
[p5sagit/p5-mst-13.2.git] / perlio.c
1 /*    perlio.c
2  *
3  *    Copyright (c) 1996-2000, Nick Ing-Simmons
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
11 #ifdef PERL_MICRO
12 #   include "uconfig.h"
13 #else
14 #   include "config.h"
15 #endif
16
17 #define PERLIO_NOT_STDIO 0
18 #if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
19 /* #define PerlIO FILE */
20 #endif
21 /*
22  * This file provides those parts of PerlIO abstraction
23  * which are not #defined in iperlsys.h.
24  * Which these are depends on various Configure #ifdef's
25  */
26
27 #include "EXTERN.h"
28 #define PERL_IN_PERLIO_C
29 #include "perl.h"
30
31 #if !defined(PERL_IMPLICIT_SYS)
32
33 #ifdef PERLIO_IS_STDIO
34
35 void
36 PerlIO_init(void)
37 {
38  /* Does nothing (yet) except force this file to be included
39     in perl binary. That allows this file to force inclusion
40     of other functions that may be required by loadable
41     extensions e.g. for FileHandle::tmpfile
42  */
43 }
44
45 #undef PerlIO_tmpfile
46 PerlIO *
47 PerlIO_tmpfile(void)
48 {
49  return tmpfile();
50 }
51
52 #else /* PERLIO_IS_STDIO */
53
54 #ifdef USE_SFIO
55
56 #undef HAS_FSETPOS
57 #undef HAS_FGETPOS
58
59 /* This section is just to make sure these functions
60    get pulled in from libsfio.a
61 */
62
63 #undef PerlIO_tmpfile
64 PerlIO *
65 PerlIO_tmpfile(void)
66 {
67  return sftmp(0);
68 }
69
70 void
71 PerlIO_init(void)
72 {
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
76   */
77
78  /* Hack
79   * sfio does its own 'autoflush' on stdout in common cases.
80   * Flush results in a lot of lseek()s to regular files and
81   * lot of small writes to pipes.
82   */
83  sfset(sfstdout,SF_SHARE,0);
84 }
85
86 #else /* USE_SFIO */
87 /*======================================================================================*/
88 /* Implement all the PerlIO interface ourselves.
89  */
90
91 /* We _MUST_ have <unistd.h> if we are using lseek() and may have large files */
92 #ifdef I_UNISTD
93 #include <unistd.h>
94 #endif
95 #ifdef HAS_MMAP
96 #include <sys/mman.h>
97 #endif
98
99 #include "XSUB.h"
100
101 #undef printf
102 void PerlIO_debug(char *fmt,...) __attribute__((format(printf,1,2)));
103
104 void
105 PerlIO_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);
124    s = CopFILE(PL_curcop);
125    if (!s)
126     s = "(none)";
127    Perl_sv_catpvf(aTHX_ sv, "%s:%"IVdf" ", s, (IV)CopLINE(PL_curcop));
128    Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap);
129
130    s = SvPV(sv,len);
131    write(dbg,s,len);
132    va_end(ap);
133    SvREFCNT_dec(sv);
134   }
135 }
136
137 /*--------------------------------------------------------------------------------------*/
138
139 typedef struct _PerlIO_funcs PerlIO_funcs;
140 struct _PerlIO_funcs
141 {
142  char *         name;
143  Size_t         size;
144  IV             kind;
145  IV             (*Fileno)(PerlIO *f);
146  PerlIO *       (*Fdopen)(PerlIO_funcs *tab, int fd, const char *mode);
147  PerlIO *       (*Open)(PerlIO_funcs *tab, const char *path, const char *mode);
148  int            (*Reopen)(const char *path, const char *mode, PerlIO *f);
149  IV             (*Pushed)(PerlIO *f,const char *mode);
150  IV             (*Popped)(PerlIO *f);
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);
160  IV             (*Fill)(PerlIO *f);
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);
171 };
172
173 struct _PerlIO
174 {
175  PerlIOl *      next;       /* Lower layer */
176  PerlIO_funcs * tab;        /* Functions for this layer */
177  IV             flags;      /* Various flags for state */
178 };
179
180 /*--------------------------------------------------------------------------------------*/
181
182 /* Flag values */
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
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
204 /* Table of pointers to the PerlIO structs (malloc'ed) */
205 PerlIO *_perlio      = NULL;
206 #define PERLIO_TABLE_SIZE 64
207
208 PerlIO *
209 PerlIO_allocate(void)
210 {
211  /* Find a free slot in the table, allocating new table as necessary */
212  PerlIO **last = &_perlio;
213  PerlIO *f;
214  while ((f = *last))
215   {
216    int i;
217    last = (PerlIO **)(f);
218    for (i=1; i < PERLIO_TABLE_SIZE; i++)
219     {
220      if (!*++f)
221       {
222        return f;
223       }
224     }
225   }
226  Newz('I',f,PERLIO_TABLE_SIZE,PerlIO);
227  if (!f)
228   return NULL;
229  *last = f;
230  return f+1;
231 }
232
233 void
234 PerlIO_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
252 void
253 PerlIO_cleanup(void)
254 {
255  PerlIO_cleantable(&_perlio);
256 }
257
258 void
259 PerlIO_pop(PerlIO *f)
260 {
261  PerlIOl *l = *f;
262  if (l)
263   {
264    (*l->tab->Popped)(f);
265    *f = l->next;
266    Safefree(l);
267   }
268 }
269
270 #undef PerlIO_close
271 int
272 PerlIO_close(PerlIO *f)
273 {
274  int code = (*PerlIOBase(f)->tab->Close)(f);
275  while (*f)
276   {
277    PerlIO_pop(f);
278   }
279  return code;
280 }
281
282
283 /*--------------------------------------------------------------------------------------*/
284 /* Given the abstraction above the public API functions */
285
286 #undef PerlIO_fileno
287 int
288 PerlIO_fileno(PerlIO *f)
289 {
290  return (*PerlIOBase(f)->tab->Fileno)(f);
291 }
292
293
294 extern PerlIO_funcs PerlIO_unix;
295 extern PerlIO_funcs PerlIO_perlio;
296 extern PerlIO_funcs PerlIO_stdio;
297 #ifdef HAS_MMAP
298 extern PerlIO_funcs PerlIO_mmap;
299 #endif
300
301 XS(XS_perlio_import)
302 {
303  dXSARGS;
304  GV *gv = CvGV(cv);
305  char *s = GvNAME(gv);
306  STRLEN l = GvNAMELEN(gv);
307  PerlIO_debug("%.*s\n",(int) l,s);
308  XSRETURN_EMPTY;
309 }
310
311 XS(XS_perlio_unimport)
312 {
313  dXSARGS;
314  GV *gv = CvGV(cv);
315  char *s = GvNAME(gv);
316  STRLEN l = GvNAMELEN(gv);
317  PerlIO_debug("%.*s\n",(int) l,s);
318  XSRETURN_EMPTY;
319 }
320
321 HV *PerlIO_layer_hv;
322 AV *PerlIO_layer_av;
323
324 SV *
325 PerlIO_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
338 void
339 PerlIO_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
347 PerlIO_funcs *
348 PerlIO_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);
363    PerlIO_define_layer(&PerlIO_perlio);
364    PerlIO_define_layer(&PerlIO_stdio);
365 #ifdef HAS_MMAP
366    PerlIO_define_layer(&PerlIO_mmap);
367 #endif
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
388           Perl_warn(aTHX_ "Unknown layer %.*s",(e-s),s);
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
421 void
422 PerlIO_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 }
432
433 #undef PerlIO_fdopen
434 PerlIO *
435 PerlIO_fdopen(int fd, const char *mode)
436 {
437  PerlIO_funcs *tab = PerlIO_default_top();
438  if (!_perlio)
439   PerlIO_stdstreams();
440  return (*tab->Fdopen)(tab,fd,mode);
441 }
442
443 #undef PerlIO_open
444 PerlIO *
445 PerlIO_open(const char *path, const char *mode)
446 {
447  PerlIO_funcs *tab = PerlIO_default_top();
448  if (!_perlio)
449   PerlIO_stdstreams();
450  return (*tab->Open)(tab,path,mode);
451 }
452
453 IV
454 PerlIOBase_pushed(PerlIO *f, const char *mode)
455 {
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)
460   {
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)
477     {
478      switch (*mode++)
479       {
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;
489       }
490     }
491   }
492  else
493   {
494    if (l->next)
495     {
496      l->flags |= l->next->flags &
497                  (PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
498                    PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
499     }
500   }
501  return 0;
502 }
503
504 #undef PerlIO_reopen
505 PerlIO *
506 PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
507 {
508  if (f)
509   {
510    PerlIO_flush(f);
511    if ((*PerlIOBase(f)->tab->Reopen)(path,mode,f) == 0)
512     {
513      if ((*PerlIOBase(f)->tab->Pushed)(f,mode) == 0)
514       return f;
515     }
516    return NULL;
517   }
518  else
519   return PerlIO_open(path,mode);
520 }
521
522 #undef PerlIO_read
523 SSize_t
524 PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
525 {
526  return (*PerlIOBase(f)->tab->Read)(f,vbuf,count);
527 }
528
529 #undef PerlIO_unread
530 SSize_t
531 PerlIO_unread(PerlIO *f, const void *vbuf, Size_t count)
532 {
533  return (*PerlIOBase(f)->tab->Unread)(f,vbuf,count);
534 }
535
536 #undef PerlIO_write
537 SSize_t
538 PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
539 {
540  return (*PerlIOBase(f)->tab->Write)(f,vbuf,count);
541 }
542
543 #undef PerlIO_seek
544 int
545 PerlIO_seek(PerlIO *f, Off_t offset, int whence)
546 {
547  return (*PerlIOBase(f)->tab->Seek)(f,offset,whence);
548 }
549
550 #undef PerlIO_tell
551 Off_t
552 PerlIO_tell(PerlIO *f)
553 {
554  return (*PerlIOBase(f)->tab->Tell)(f);
555 }
556
557 #undef PerlIO_flush
558 int
559 PerlIO_flush(PerlIO *f)
560 {
561  if (f)
562   {
563    return (*PerlIOBase(f)->tab->Flush)(f);
564   }
565  else
566   {
567    PerlIO **table = &_perlio;
568    int code = 0;
569    while ((f = *table))
570     {
571      int i;
572      table = (PerlIO **)(f++);
573      for (i=1; i < PERLIO_TABLE_SIZE; i++)
574       {
575        if (*f && PerlIO_flush(f) != 0)
576         code = -1;
577        f++;
578       }
579     }
580    return code;
581   }
582 }
583
584 #undef PerlIO_fill
585 int
586 PerlIO_fill(PerlIO *f)
587 {
588  return (*PerlIOBase(f)->tab->Fill)(f);
589 }
590
591 #undef PerlIO_isutf8
592 int
593 PerlIO_isutf8(PerlIO *f)
594 {
595  return (PerlIOBase(f)->flags & PERLIO_F_UTF8) != 0;
596 }
597
598 #undef PerlIO_eof
599 int
600 PerlIO_eof(PerlIO *f)
601 {
602  return (*PerlIOBase(f)->tab->Eof)(f);
603 }
604
605 #undef PerlIO_error
606 int
607 PerlIO_error(PerlIO *f)
608 {
609  return (*PerlIOBase(f)->tab->Error)(f);
610 }
611
612 #undef PerlIO_clearerr
613 void
614 PerlIO_clearerr(PerlIO *f)
615 {
616  (*PerlIOBase(f)->tab->Clearerr)(f);
617 }
618
619 #undef PerlIO_setlinebuf
620 void
621 PerlIO_setlinebuf(PerlIO *f)
622 {
623  (*PerlIOBase(f)->tab->Setlinebuf)(f);
624 }
625
626 #undef PerlIO_has_base
627 int
628 PerlIO_has_base(PerlIO *f)
629 {
630  if (f && *f)
631   {
632    return (PerlIOBase(f)->tab->Get_base != NULL);
633   }
634  return 0;
635 }
636
637 #undef PerlIO_fast_gets
638 int
639 PerlIO_fast_gets(PerlIO *f)
640 {
641  if (f && *f)
642   {
643    PerlIOl *l = PerlIOBase(f);
644    return (l->tab->Set_ptrcnt != NULL);
645   }
646  return 0;
647 }
648
649 #undef PerlIO_has_cntptr
650 int
651 PerlIO_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
662 int
663 PerlIO_canset_cnt(PerlIO *f)
664 {
665  if (f && *f)
666   {
667    PerlIOl *l = PerlIOBase(f);
668    return (l->tab->Set_ptrcnt != NULL);
669   }
670  return 0;
671 }
672
673 #undef PerlIO_get_base
674 STDCHAR *
675 PerlIO_get_base(PerlIO *f)
676 {
677  return (*PerlIOBase(f)->tab->Get_base)(f);
678 }
679
680 #undef PerlIO_get_bufsiz
681 int
682 PerlIO_get_bufsiz(PerlIO *f)
683 {
684  return (*PerlIOBase(f)->tab->Get_bufsiz)(f);
685 }
686
687 #undef PerlIO_get_ptr
688 STDCHAR *
689 PerlIO_get_ptr(PerlIO *f)
690 {
691  return (*PerlIOBase(f)->tab->Get_ptr)(f);
692 }
693
694 #undef PerlIO_get_cnt
695 int
696 PerlIO_get_cnt(PerlIO *f)
697 {
698  return (*PerlIOBase(f)->tab->Get_cnt)(f);
699 }
700
701 #undef PerlIO_set_cnt
702 void
703 PerlIO_set_cnt(PerlIO *f,int cnt)
704 {
705  (*PerlIOBase(f)->tab->Set_ptrcnt)(f,NULL,cnt);
706 }
707
708 #undef PerlIO_set_ptrcnt
709 void
710 PerlIO_set_ptrcnt(PerlIO *f, STDCHAR *ptr, int cnt)
711 {
712  (*PerlIOBase(f)->tab->Set_ptrcnt)(f,ptr,cnt);
713 }
714
715 /*--------------------------------------------------------------------------------------*/
716 /* "Methods" of the "base class" */
717
718 IV
719 PerlIOBase_fileno(PerlIO *f)
720 {
721  return PerlIO_fileno(PerlIONext(f));
722 }
723
724 PerlIO *
725 PerlIO_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)
730   {
731    Zero(l,tab->size,char);
732    l->next = *f;
733    l->tab  = tab;
734    *f      = l;
735    if ((*l->tab->Pushed)(f,mode) != 0)
736     {
737      PerlIO_pop(f);
738      return NULL;
739     }
740   }
741  return f;
742 }
743
744 SSize_t
745 PerlIOBase_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
756 IV
757 PerlIOBase_noop_ok(PerlIO *f)
758 {
759  return 0;
760 }
761
762 IV
763 PerlIOBase_noop_fail(PerlIO *f)
764 {
765  return -1;
766 }
767
768 IV
769 PerlIOBase_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
780 IV
781 PerlIOBase_eof(PerlIO *f)
782 {
783  if (f && *f)
784   {
785    return (PerlIOBase(f)->flags & PERLIO_F_EOF) != 0;
786   }
787  return 1;
788 }
789
790 IV
791 PerlIOBase_error(PerlIO *f)
792 {
793  if (f && *f)
794   {
795    return (PerlIOBase(f)->flags & PERLIO_F_ERROR) != 0;
796   }
797  return 1;
798 }
799
800 void
801 PerlIOBase_clearerr(PerlIO *f)
802 {
803  if (f && *f)
804   {
805    PerlIOBase(f)->flags &= ~PERLIO_F_ERROR;
806   }
807 }
808
809 void
810 PerlIOBase_setlinebuf(PerlIO *f)
811 {
812
813 }
814
815
816
817 /*--------------------------------------------------------------------------------------*/
818 /* Bottom-most level for UNIX-like case */
819
820 typedef 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
827 int
828 PerlIOUnix_oflags(const char *mode)
829 {
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)
865   {
866    errno = EINVAL;
867    oflags = -1;
868   }
869  return oflags;
870 }
871
872 IV
873 PerlIOUnix_fileno(PerlIO *f)
874 {
875  return PerlIOSelf(f,PerlIOUnix)->fd;
876 }
877
878 PerlIO *
879 PerlIOUnix_fdopen(PerlIO_funcs *self, int fd,const char *mode)
880 {
881  PerlIO *f = NULL;
882  if (*mode == 'I')
883   mode++;
884  if (fd >= 0)
885   {
886    int oflags = PerlIOUnix_oflags(mode);
887    if (oflags != -1)
888     {
889      PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
890      s->fd     = fd;
891      s->oflags = oflags;
892      PerlIOBase(f)->flags |= PERLIO_F_OPEN;
893     }
894   }
895  return f;
896 }
897
898 PerlIO *
899 PerlIOUnix_open(PerlIO_funcs *self, const char *path,const char *mode)
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     {
908      PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
909      s->fd     = fd;
910      s->oflags = oflags;
911      PerlIOBase(f)->flags |= PERLIO_F_OPEN;
912     }
913   }
914  return f;
915 }
916
917 int
918 PerlIOUnix_reopen(const char *path, const char *mode, PerlIO *f)
919 {
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
938 SSize_t
939 PerlIOUnix_read(PerlIO *f, void *vbuf, Size_t count)
940 {
941  int fd = PerlIOSelf(f,PerlIOUnix)->fd;
942  if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
943   return 0;
944  while (1)
945   {
946    SSize_t len = read(fd,vbuf,count);
947    if (len >= 0 || errno != EINTR)
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     }
955   }
956 }
957
958 SSize_t
959 PerlIOUnix_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)
966     {
967      if (len < 0)
968       PerlIOBase(f)->flags |= PERLIO_F_ERROR;
969      return len;
970     }
971   }
972 }
973
974 IV
975 PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence)
976 {
977  Off_t new = lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence);
978  PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
979  return (new == (Off_t) -1) ? -1 : 0;
980 }
981
982 Off_t
983 PerlIOUnix_tell(PerlIO *f)
984 {
985  return lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
986 }
987
988 IV
989 PerlIOUnix_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
1008 PerlIO_funcs PerlIO_unix = {
1009  "unix",
1010  sizeof(PerlIOUnix),
1011  0,
1012  PerlIOUnix_fileno,
1013  PerlIOUnix_fdopen,
1014  PerlIOUnix_open,
1015  PerlIOUnix_reopen,
1016  PerlIOBase_pushed,
1017  PerlIOBase_noop_ok,
1018  PerlIOUnix_read,
1019  PerlIOBase_unread,
1020  PerlIOUnix_write,
1021  PerlIOUnix_seek,
1022  PerlIOUnix_tell,
1023  PerlIOUnix_close,
1024  PerlIOBase_noop_ok,
1025  PerlIOBase_noop_fail,
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
1040 typedef struct
1041 {
1042  struct _PerlIO base;
1043  FILE *         stdio;      /* The stream */
1044 } PerlIOStdio;
1045
1046 IV
1047 PerlIOStdio_fileno(PerlIO *f)
1048 {
1049  return fileno(PerlIOSelf(f,PerlIOStdio)->stdio);
1050 }
1051
1052
1053 PerlIO *
1054 PerlIOStdio_fdopen(PerlIO_funcs *self, int fd,const char *mode)
1055 {
1056  PerlIO *f = NULL;
1057  int init = 0;
1058  if (*mode == 'I')
1059   {
1060    init = 1;
1061    mode++;
1062   }
1063  if (fd >= 0)
1064   {
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);
1083    if (stdio)
1084     {
1085      PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOStdio);
1086      s->stdio  = stdio;
1087     }
1088   }
1089  return f;
1090 }
1091
1092 #undef PerlIO_importFILE
1093 PerlIO *
1094 PerlIO_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
1105 PerlIO *
1106 PerlIOStdio_open(PerlIO_funcs *self, const char *path,const char *mode)
1107 {
1108  PerlIO *f = NULL;
1109  FILE *stdio = fopen(path,mode);
1110  if (stdio)
1111   {
1112    PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOStdio);
1113    s->stdio  = stdio;
1114   }
1115  return f;
1116 }
1117
1118 int
1119 PerlIOStdio_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
1129 SSize_t
1130 PerlIOStdio_read(PerlIO *f, void *vbuf, Size_t count)
1131 {
1132  FILE *s = PerlIOSelf(f,PerlIOStdio)->stdio;
1133  SSize_t got = 0;
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;
1144      got = 1;
1145     }
1146   }
1147  else
1148   got = fread(vbuf,1,count,s);
1149  return got;
1150 }
1151
1152 SSize_t
1153 PerlIOStdio_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
1169 SSize_t
1170 PerlIOStdio_write(PerlIO *f, const void *vbuf, Size_t count)
1171 {
1172  return fwrite(vbuf,1,count,PerlIOSelf(f,PerlIOStdio)->stdio);
1173 }
1174
1175 IV
1176 PerlIOStdio_seek(PerlIO *f, Off_t offset, int whence)
1177 {
1178  FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1179  return fseek(stdio,offset,whence);
1180 }
1181
1182 Off_t
1183 PerlIOStdio_tell(PerlIO *f)
1184 {
1185  FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1186  return ftell(stdio);
1187 }
1188
1189 IV
1190 PerlIOStdio_close(PerlIO *f)
1191 {
1192  return fclose(PerlIOSelf(f,PerlIOStdio)->stdio);
1193 }
1194
1195 IV
1196 PerlIOStdio_flush(PerlIO *f)
1197 {
1198  FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1199  return fflush(stdio);
1200 }
1201
1202 IV
1203 PerlIOStdio_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
1215 IV
1216 PerlIOStdio_eof(PerlIO *f)
1217 {
1218  return feof(PerlIOSelf(f,PerlIOStdio)->stdio);
1219 }
1220
1221 IV
1222 PerlIOStdio_error(PerlIO *f)
1223 {
1224  return ferror(PerlIOSelf(f,PerlIOStdio)->stdio);
1225 }
1226
1227 void
1228 PerlIOStdio_clearerr(PerlIO *f)
1229 {
1230  clearerr(PerlIOSelf(f,PerlIOStdio)->stdio);
1231 }
1232
1233 void
1234 PerlIOStdio_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
1244 STDCHAR *
1245 PerlIOStdio_get_base(PerlIO *f)
1246 {
1247  FILE *stdio  = PerlIOSelf(f,PerlIOStdio)->stdio;
1248  return FILE_base(stdio);
1249 }
1250
1251 Size_t
1252 PerlIOStdio_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
1260 STDCHAR *
1261 PerlIOStdio_get_ptr(PerlIO *f)
1262 {
1263  FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1264  return FILE_ptr(stdio);
1265 }
1266
1267 SSize_t
1268 PerlIOStdio_get_cnt(PerlIO *f)
1269 {
1270  FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
1271  return FILE_cnt(stdio);
1272 }
1273
1274 void
1275 PerlIOStdio_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
1311 PerlIO_funcs PerlIO_stdio = {
1312  "stdio",
1313  sizeof(PerlIOStdio),
1314  0,
1315  PerlIOStdio_fileno,
1316  PerlIOStdio_fdopen,
1317  PerlIOStdio_open,
1318  PerlIOStdio_reopen,
1319  PerlIOBase_pushed,
1320  PerlIOBase_noop_ok,
1321  PerlIOStdio_read,
1322  PerlIOStdio_unread,
1323  PerlIOStdio_write,
1324  PerlIOStdio_seek,
1325  PerlIOStdio_tell,
1326  PerlIOStdio_close,
1327  PerlIOStdio_flush,
1328  PerlIOStdio_fill,
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,
1343 #if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
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
1356 FILE *
1357 PerlIO_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
1365 FILE *
1366 PerlIO_findFILE(PerlIO *f)
1367 {
1368  return PerlIO_exportFILE(f,0);
1369 }
1370
1371 #undef PerlIO_releaseFILE
1372 void
1373 PerlIO_releaseFILE(PerlIO *p, FILE *f)
1374 {
1375 }
1376
1377 /*--------------------------------------------------------------------------------------*/
1378 /* perlio buffer layer */
1379
1380 typedef struct
1381 {
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
1392 PerlIO *
1393 PerlIOBuf_fdopen(PerlIO_funcs *self, int fd, const char *mode)
1394 {
1395  PerlIO_funcs *tab = PerlIO_default_btm();
1396  int init = 0;
1397  PerlIO *f;
1398  if (*mode == 'I')
1399   {
1400    init = 1;
1401    mode++;
1402   }
1403  f = (*tab->Fdopen)(tab,fd,mode);
1404  if (f)
1405   {
1406    /* Initial stderr is unbuffered */
1407    if (!init || fd != 2)
1408     {
1409      PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,NULL),PerlIOBuf);
1410      b->posn = PerlIO_tell(PerlIONext(f));
1411     }
1412   }
1413  return f;
1414 }
1415
1416 PerlIO *
1417 PerlIOBuf_open(PerlIO_funcs *self, const char *path, const char *mode)
1418 {
1419  PerlIO_funcs *tab = PerlIO_default_btm();
1420  PerlIO *f = (*tab->Open)(tab,path,mode);
1421  if (f)
1422   {
1423    PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,NULL),PerlIOBuf);
1424    b->posn = 0;
1425   }
1426  return f;
1427 }
1428
1429 int
1430 PerlIOBase_reopen(const char *path, const char *mode, PerlIO *f)
1431 {
1432  return (*PerlIOBase(f)->tab->Reopen)(path,mode,PerlIONext(f));
1433 }
1434
1435 /* This "flush" is akin to sfio's sync in that it handles files in either
1436    read or write state
1437 */
1438 IV
1439 PerlIOBuf_flush(PerlIO *f)
1440 {
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)
1465   {
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     }
1476   }
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;
1482 }
1483
1484 IV
1485 PerlIOBuf_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
1506 SSize_t
1507 PerlIOBuf_read(PerlIO *f, void *vbuf, Size_t count)
1508 {
1509  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1510  STDCHAR *buf = (STDCHAR *) vbuf;
1511  if (f)
1512   {
1513    Size_t got = 0;
1514    if (!b->ptr)
1515     PerlIO_get_base(f);
1516    if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD))
1517     return 0;
1518    while (count > 0)
1519     {
1520      SSize_t avail = (b->end - b->ptr);
1521      if ((SSize_t) count < avail)
1522       avail = count;
1523      if (avail > 0)
1524       {
1525        Copy(b->ptr,buf,avail,char);
1526        got     += avail;
1527        b->ptr  += avail;
1528        count   -= avail;
1529        buf     += avail;
1530       }
1531      if (count && (b->ptr >= b->end))
1532       {
1533        if (PerlIO_fill(f) != 0)
1534         break;
1535       }
1536     }
1537    return got;
1538   }
1539  return 0;
1540 }
1541
1542 SSize_t
1543 PerlIOBuf_unread(PerlIO *f, const void *vbuf, Size_t count)
1544 {
1545  const STDCHAR *buf = (const STDCHAR *) vbuf+count;
1546  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1547  SSize_t unread = 0;
1548  SSize_t avail;
1549  if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
1550   PerlIO_flush(f);
1551  if (!b->buf)
1552   PerlIO_get_base(f);
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;
1582 }
1583
1584 SSize_t
1585 PerlIOBuf_write(PerlIO *f, const void *vbuf, Size_t count)
1586 {
1587  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1588  const STDCHAR *buf = (const STDCHAR *) vbuf;
1589  Size_t written = 0;
1590  if (!b->buf)
1591   PerlIO_get_base(f);
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
1633 IV
1634 PerlIOBuf_seek(PerlIO *f, Off_t offset, int whence)
1635 {
1636  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1637  int code = PerlIO_flush(f);
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      PerlIO_debug(__FUNCTION__ " f=%p posn=%ld\n",f,(long) b->posn);
1646     }
1647   }
1648  if (code)
1649   PerlIO_debug(__FUNCTION__ " f=%p code%d\n",f,code);
1650  return code;
1651 }
1652
1653 Off_t
1654 PerlIOBuf_tell(PerlIO *f)
1655 {
1656  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1657  Off_t posn = b->posn;
1658  if (b->buf)
1659   posn += (b->ptr - b->buf);
1660  PerlIO_debug(__FUNCTION__ " f=%p posn=%ld\n",f,(long) posn);
1661  return posn;
1662 }
1663
1664 IV
1665 PerlIOBuf_close(PerlIO *f)
1666 {
1667  IV code = PerlIOBase_close(f);
1668  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1669  if (b->buf && b->buf != (STDCHAR *) &b->oneword)
1670   {
1671    Safefree(b->buf);
1672   }
1673  b->buf = NULL;
1674  b->ptr = b->end = b->buf;
1675  PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
1676  return code;
1677 }
1678
1679 void
1680 PerlIOBuf_setlinebuf(PerlIO *f)
1681 {
1682  if (f)
1683   {
1684    PerlIOBase(f)->flags &= ~PERLIO_F_LINEBUF;
1685   }
1686 }
1687
1688 void
1689 PerlIOBuf_set_cnt(PerlIO *f, int cnt)
1690 {
1691  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1692  dTHX;
1693  if (!b->buf)
1694   PerlIO_get_base(f);
1695  b->ptr = b->end - cnt;
1696  assert(b->ptr >= b->buf);
1697 }
1698
1699 STDCHAR *
1700 PerlIOBuf_get_ptr(PerlIO *f)
1701 {
1702  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1703  if (!b->buf)
1704   PerlIO_get_base(f);
1705  return b->ptr;
1706 }
1707
1708 SSize_t
1709 PerlIOBuf_get_cnt(PerlIO *f)
1710 {
1711  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1712  if (!b->buf)
1713   PerlIO_get_base(f);
1714  if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
1715   return (b->end - b->ptr);
1716  return 0;
1717 }
1718
1719 STDCHAR *
1720 PerlIOBuf_get_base(PerlIO *f)
1721 {
1722  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1723  if (!b->buf)
1724   {
1725    if (!b->bufsiz)
1726     b->bufsiz = 4096;
1727    New('B',b->buf,b->bufsiz,STDCHAR);
1728    if (!b->buf)
1729     {
1730      b->buf = (STDCHAR *)&b->oneword;
1731      b->bufsiz = sizeof(b->oneword);
1732     }
1733    b->ptr = b->buf;
1734    b->end = b->ptr;
1735   }
1736  return b->buf;
1737 }
1738
1739 Size_t
1740 PerlIOBuf_bufsiz(PerlIO *f)
1741 {
1742  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1743  if (!b->buf)
1744   PerlIO_get_base(f);
1745  return (b->end - b->buf);
1746 }
1747
1748 void
1749 PerlIOBuf_set_ptrcnt(PerlIO *f, STDCHAR *ptr, SSize_t cnt)
1750 {
1751  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1752  if (!b->buf)
1753   PerlIO_get_base(f);
1754  b->ptr = ptr;
1755  if (PerlIO_get_cnt(f) != cnt || b->ptr < b->buf)
1756   {
1757    dTHX;
1758    assert(PerlIO_get_cnt(f) == cnt);
1759    assert(b->ptr >= b->buf);
1760   }
1761  PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
1762 }
1763
1764 PerlIO_funcs PerlIO_perlio = {
1765  "perlio",
1766  sizeof(PerlIOBuf),
1767  0,
1768  PerlIOBase_fileno,
1769  PerlIOBuf_fdopen,
1770  PerlIOBuf_open,
1771  PerlIOBase_reopen,
1772  PerlIOBase_pushed,
1773  PerlIOBase_noop_ok,
1774  PerlIOBuf_read,
1775  PerlIOBuf_unread,
1776  PerlIOBuf_write,
1777  PerlIOBuf_seek,
1778  PerlIOBuf_tell,
1779  PerlIOBuf_close,
1780  PerlIOBuf_flush,
1781  PerlIOBuf_fill,
1782  PerlIOBase_eof,
1783  PerlIOBase_error,
1784  PerlIOBase_clearerr,
1785  PerlIOBuf_setlinebuf,
1786  PerlIOBuf_get_base,
1787  PerlIOBuf_bufsiz,
1788  PerlIOBuf_get_ptr,
1789  PerlIOBuf_get_cnt,
1790  PerlIOBuf_set_ptrcnt,
1791 };
1792
1793 #ifdef HAS_MMAP
1794 /*--------------------------------------------------------------------------------------*/
1795 /* mmap as "buffer" layer */
1796
1797 typedef struct
1798 {
1799  PerlIOBuf      base;         /* PerlIOBuf stuff */
1800  Size_t         len;          /* mapped length */
1801  STDCHAR        *bbuf;        /* malloced buffer if map fails */
1802 } PerlIOMmap;
1803
1804 IV
1805 PerlIOMmap_map(PerlIO *f)
1806 {
1807  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1808  PerlIOBuf  *b = &m->base;
1809  IV flags = PerlIOBase(f)->flags;
1810  IV code  = 0;
1811  if (m->len)
1812   abort();
1813  if (flags & PERLIO_F_CANREAD)
1814   {
1815    PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1816    int fd   = PerlIO_fileno(f);
1817    struct stat st;
1818    code = fstat(fd,&st);
1819    if (code == 0 && S_ISREG(st.st_mode))
1820     {
1821      SSize_t len = st.st_size - b->posn;
1822      if (len > 0)
1823       {
1824        b->buf = (STDCHAR *) mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, b->posn);
1825        PerlIO_debug(__FUNCTION__ " f=%p b=%p for %ld @ %ld\n",
1826                     f, b->buf, (long) len, (long) b->posn);
1827        if (b->buf && b->buf != (STDCHAR *) -1)
1828         {
1829 #if defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
1830          madvise(b->buf, len, MADV_SEQUENTIAL);
1831 #endif
1832          PerlIOBase(f)->flags = flags | PERLIO_F_RDBUF;
1833          b->end = b->buf+len;
1834          b->ptr = b->buf;
1835          m->len = len;
1836         }
1837        else
1838         {
1839          b->buf = NULL;
1840         }
1841       }
1842      else
1843       {
1844        PerlIOBase(f)->flags = flags | PERLIO_F_EOF | PERLIO_F_RDBUF;
1845        b->buf = NULL;
1846        b->ptr = b->end = b->ptr;
1847        code = -1;
1848       }
1849     }
1850   }
1851  return code;
1852 }
1853
1854 IV
1855 PerlIOMmap_unmap(PerlIO *f)
1856 {
1857  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1858  PerlIOBuf  *b = &m->base;
1859  IV code = 0;
1860  if (m->len)
1861   {
1862    if (b->buf)
1863     {
1864      code = munmap((Mmap_t) b->buf, m->len);
1865      b->buf = NULL;
1866      m->len = 0;
1867      if (PerlIO_seek(PerlIONext(f),b->posn,SEEK_SET) != 0)
1868       code = -1;
1869      PerlIO_debug(__FUNCTION__ " f=%p b=%p c=%ld posn=%ld\n",
1870                   f,b->buf,(long)m->len,(long) b->posn);
1871     }
1872    b->ptr = b->end = b->buf;
1873    PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
1874   }
1875  return code;
1876 }
1877
1878 STDCHAR *
1879 PerlIOMmap_get_base(PerlIO *f)
1880 {
1881  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1882  PerlIOBuf  *b = &m->base;
1883  if (b->buf && (PerlIOBase(f)->flags & PERLIO_F_RDBUF))
1884   {
1885    /* Already have a readbuffer in progress */
1886    return b->buf;
1887   }
1888  if (b->buf)
1889   {
1890    /* We have a write buffer or flushed PerlIOBuf read buffer */
1891    m->bbuf = b->buf;  /* save it in case we need it again */
1892    b->buf  = NULL;    /* Clear to trigger below */
1893   }
1894  if (!b->buf)
1895   {
1896    PerlIOMmap_map(f);     /* Try and map it */
1897    if (!b->buf)
1898     {
1899      /* Map did not work - recover PerlIOBuf buffer if we have one */
1900      b->buf = m->bbuf;
1901     }
1902   }
1903  b->ptr  = b->end = b->buf;
1904  if (b->buf)
1905   return b->buf;
1906  return PerlIOBuf_get_base(f);
1907 }
1908
1909 SSize_t
1910 PerlIOMmap_unread(PerlIO *f, const void *vbuf, Size_t count)
1911 {
1912  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1913  PerlIOBuf  *b = &m->base;
1914  if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
1915   PerlIO_flush(f);
1916  if (b->ptr && (b->ptr - count) >= b->buf && memEQ(b->ptr - count,vbuf,count))
1917   {
1918    b->ptr -= count;
1919    PerlIOBase(f)->flags &= ~ PERLIO_F_EOF;
1920    return count;
1921   }
1922  if (m->len)
1923   {
1924    PerlIO_debug(__FUNCTION__ " f=%p %d '%.*s'\n",f,count,count,(char *)vbuf);
1925    PerlIO_flush(f);
1926   }
1927  return PerlIOBuf_unread(f,vbuf,count);
1928 }
1929
1930 SSize_t
1931 PerlIOMmap_write(PerlIO *f, const void *vbuf, Size_t count)
1932 {
1933  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1934  PerlIOBuf  *b = &m->base;
1935  if (!b->buf || !(PerlIOBase(f)->flags & PERLIO_F_WRBUF))
1936   {
1937    /* No, or wrong sort of, buffer */
1938    if (m->len)
1939     {
1940      if (PerlIOMmap_unmap(f) != 0)
1941       return 0;
1942     }
1943    /* If unmap took the "buffer" see if we have one from before */
1944    if (!b->buf && m->bbuf)
1945     b->buf = m->bbuf;
1946    if (!b->buf)
1947     {
1948      PerlIOBuf_get_base(f);
1949      m->bbuf = b->buf;
1950     }
1951   }
1952  return PerlIOBuf_write(f,vbuf,count);
1953 }
1954
1955 IV
1956 PerlIOMmap_flush(PerlIO *f)
1957 {
1958  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
1959  PerlIOBuf  *b = &m->base;
1960  IV code = PerlIOBuf_flush(f);
1961  /* Now we are "synced" at PerlIOBuf level */
1962  if (b->buf)
1963   {
1964    if (m->len)
1965     {
1966      /* Unmap the buffer */
1967      if (PerlIOMmap_unmap(f) != 0)
1968       code = -1;
1969     }
1970    else
1971     {
1972      /* We seem to have a PerlIOBuf buffer which was not mapped
1973       * remember it in case we need one later
1974       */
1975      m->bbuf = b->buf;
1976     }
1977   }
1978  if (code)
1979   PerlIO_debug(__FUNCTION__ " f=%p %d\n",f,code);
1980  return code;
1981 }
1982
1983 IV
1984 PerlIOMmap_fill(PerlIO *f)
1985 {
1986  PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
1987  IV code = PerlIO_flush(f);
1988  PerlIO_debug(__FUNCTION__ " f=%p flush posn=%ld\n",f,(long)b->posn);
1989  if (code == 0 && !b->buf)
1990   {
1991    code = PerlIOMmap_map(f);
1992    PerlIO_debug(__FUNCTION__ " f=%p mmap code=%d posn=%ld\n",f,code,(long)b->posn);
1993   }
1994  if (code == 0 && !(PerlIOBase(f)->flags & PERLIO_F_RDBUF))
1995   {
1996    code = PerlIOBuf_fill(f);
1997    PerlIO_debug(__FUNCTION__ " f=%p fill code=%d posn=%ld\n",f,code,(long)b->posn);
1998   }
1999  return code;
2000 }
2001
2002 IV
2003 PerlIOMmap_close(PerlIO *f)
2004 {
2005  PerlIOMmap *m = PerlIOSelf(f,PerlIOMmap);
2006  PerlIOBuf  *b = &m->base;
2007  IV code = PerlIO_flush(f);
2008  if (m->bbuf)
2009   {
2010    b->buf  = m->bbuf;
2011    m->bbuf = NULL;
2012    b->ptr  = b->end = b->buf;
2013   }
2014  if (PerlIOBuf_close(f) != 0)
2015   code = -1;
2016  PerlIO_debug(__FUNCTION__ " f=%p %d\n",f,code);
2017  return code;
2018 }
2019
2020
2021 PerlIO_funcs PerlIO_mmap = {
2022  "mmap",
2023  sizeof(PerlIOMmap),
2024  0,
2025  PerlIOBase_fileno,
2026  PerlIOBuf_fdopen,
2027  PerlIOBuf_open,
2028  PerlIOBase_reopen,
2029  PerlIOBase_pushed,
2030  PerlIOBase_noop_ok,
2031  PerlIOBuf_read,
2032  PerlIOMmap_unread,
2033  PerlIOMmap_write,
2034  PerlIOBuf_seek,
2035  PerlIOBuf_tell,
2036  PerlIOBuf_close,
2037  PerlIOMmap_flush,
2038  PerlIOMmap_fill,
2039  PerlIOBase_eof,
2040  PerlIOBase_error,
2041  PerlIOBase_clearerr,
2042  PerlIOBuf_setlinebuf,
2043  PerlIOMmap_get_base,
2044  PerlIOBuf_bufsiz,
2045  PerlIOBuf_get_ptr,
2046  PerlIOBuf_get_cnt,
2047  PerlIOBuf_set_ptrcnt,
2048 };
2049
2050 #endif /* HAS_MMAP */
2051
2052
2053
2054 void
2055 PerlIO_init(void)
2056 {
2057  if (!_perlio)
2058   {
2059    atexit(&PerlIO_cleanup);
2060   }
2061 }
2062
2063 #undef PerlIO_stdin
2064 PerlIO *
2065 PerlIO_stdin(void)
2066 {
2067  if (!_perlio)
2068   PerlIO_stdstreams();
2069  return &_perlio[1];
2070 }
2071
2072 #undef PerlIO_stdout
2073 PerlIO *
2074 PerlIO_stdout(void)
2075 {
2076  if (!_perlio)
2077   PerlIO_stdstreams();
2078  return &_perlio[2];
2079 }
2080
2081 #undef PerlIO_stderr
2082 PerlIO *
2083 PerlIO_stderr(void)
2084 {
2085  if (!_perlio)
2086   PerlIO_stdstreams();
2087  return &_perlio[3];
2088 }
2089
2090 /*--------------------------------------------------------------------------------------*/
2091
2092 #undef PerlIO_getname
2093 char *
2094 PerlIO_getname(PerlIO *f, char *buf)
2095 {
2096  dTHX;
2097  Perl_croak(aTHX_ "Don't know how to get file name");
2098  return NULL;
2099 }
2100
2101
2102 /*--------------------------------------------------------------------------------------*/
2103 /* Functions which can be called on any kind of PerlIO implemented
2104    in terms of above
2105 */
2106
2107 #undef PerlIO_getc
2108 int
2109 PerlIO_getc(PerlIO *f)
2110 {
2111  STDCHAR buf[1];
2112  SSize_t count = PerlIO_read(f,buf,1);
2113  if (count == 1)
2114   {
2115    return (unsigned char) buf[0];
2116   }
2117  return EOF;
2118 }
2119
2120 #undef PerlIO_ungetc
2121 int
2122 PerlIO_ungetc(PerlIO *f, int ch)
2123 {
2124  if (ch != EOF)
2125   {
2126    STDCHAR buf = ch;
2127    if (PerlIO_unread(f,&buf,1) == 1)
2128     return ch;
2129   }
2130  return EOF;
2131 }
2132
2133 #undef PerlIO_putc
2134 int
2135 PerlIO_putc(PerlIO *f, int ch)
2136 {
2137  STDCHAR buf = ch;
2138  return PerlIO_write(f,&buf,1);
2139 }
2140
2141 #undef PerlIO_puts
2142 int
2143 PerlIO_puts(PerlIO *f, const char *s)
2144 {
2145  STRLEN len = strlen(s);
2146  return PerlIO_write(f,s,len);
2147 }
2148
2149 #undef PerlIO_rewind
2150 void
2151 PerlIO_rewind(PerlIO *f)
2152 {
2153  PerlIO_seek(f,(Off_t)0,SEEK_SET);
2154  PerlIO_clearerr(f);
2155 }
2156
2157 #undef PerlIO_vprintf
2158 int
2159 PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
2160 {
2161  dTHX;
2162  SV *sv = newSVpvn("",0);
2163  char *s;
2164  STRLEN len;
2165  sv_vcatpvf(sv, fmt, &ap);
2166  s = SvPV(sv,len);
2167  return PerlIO_write(f,s,len);
2168 }
2169
2170 #undef PerlIO_printf
2171 int
2172 PerlIO_printf(PerlIO *f,const char *fmt,...)
2173 {
2174  va_list ap;
2175  int result;
2176  va_start(ap,fmt);
2177  result = PerlIO_vprintf(f,fmt,ap);
2178  va_end(ap);
2179  return result;
2180 }
2181
2182 #undef PerlIO_stdoutf
2183 int
2184 PerlIO_stdoutf(const char *fmt,...)
2185 {
2186  va_list ap;
2187  int result;
2188  va_start(ap,fmt);
2189  result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
2190  va_end(ap);
2191  return result;
2192 }
2193
2194 #undef PerlIO_tmpfile
2195 PerlIO *
2196 PerlIO_tmpfile(void)
2197 {
2198  dTHX;
2199  /* I have no idea how portable mkstemp() is ... */
2200  SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
2201  int fd = mkstemp(SvPVX(sv));
2202  PerlIO *f = NULL;
2203  if (fd >= 0)
2204   {
2205    f = PerlIO_fdopen(fd,"w+");
2206    if (f)
2207     {
2208      PerlIOBase(f)->flags |= PERLIO_F_TEMP;
2209     }
2210    unlink(SvPVX(sv));
2211    SvREFCNT_dec(sv);
2212   }
2213  return f;
2214 }
2215
2216 #undef HAS_FSETPOS
2217 #undef HAS_FGETPOS
2218
2219 #endif /* USE_SFIO */
2220 #endif /* PERLIO_IS_STDIO */
2221
2222 /*======================================================================================*/
2223 /* Now some functions in terms of above which may be needed even if
2224    we are not in true PerlIO mode
2225  */
2226
2227 #ifndef HAS_FSETPOS
2228 #undef PerlIO_setpos
2229 int
2230 PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
2231 {
2232  return PerlIO_seek(f,*pos,0);
2233 }
2234 #else
2235 #ifndef PERLIO_IS_STDIO
2236 #undef PerlIO_setpos
2237 int
2238 PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
2239 {
2240 #if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
2241  return fsetpos64(f, pos);
2242 #else
2243  return fsetpos(f, pos);
2244 #endif
2245 }
2246 #endif
2247 #endif
2248
2249 #ifndef HAS_FGETPOS
2250 #undef PerlIO_getpos
2251 int
2252 PerlIO_getpos(PerlIO *f, Fpos_t *pos)
2253 {
2254  *pos = PerlIO_tell(f);
2255  return 0;
2256 }
2257 #else
2258 #ifndef PERLIO_IS_STDIO
2259 #undef PerlIO_getpos
2260 int
2261 PerlIO_getpos(PerlIO *f, Fpos_t *pos)
2262 {
2263 #if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
2264  return fgetpos64(f, pos);
2265 #else
2266  return fgetpos(f, pos);
2267 #endif
2268 }
2269 #endif
2270 #endif
2271
2272 #if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
2273
2274 int
2275 vprintf(char *pat, char *args)
2276 {
2277     _doprnt(pat, args, stdout);
2278     return 0;           /* wrong, but perl doesn't use the return value */
2279 }
2280
2281 int
2282 vfprintf(FILE *fd, char *pat, char *args)
2283 {
2284     _doprnt(pat, args, fd);
2285     return 0;           /* wrong, but perl doesn't use the return value */
2286 }
2287
2288 #endif
2289
2290 #ifndef PerlIO_vsprintf
2291 int
2292 PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
2293 {
2294  int val = vsprintf(s, fmt, ap);
2295  if (n >= 0)
2296   {
2297    if (strlen(s) >= (STRLEN)n)
2298     {
2299      dTHX;
2300      PerlIO_puts(Perl_error_log,"panic: sprintf overflow - memory corrupted!\n");
2301      my_exit(1);
2302     }
2303   }
2304  return val;
2305 }
2306 #endif
2307
2308 #ifndef PerlIO_sprintf
2309 int
2310 PerlIO_sprintf(char *s, int n, const char *fmt,...)
2311 {
2312  va_list ap;
2313  int result;
2314  va_start(ap,fmt);
2315  result = PerlIO_vsprintf(s, n, fmt, ap);
2316  va_end(ap);
2317  return result;
2318 }
2319 #endif
2320
2321 #endif /* !PERL_IMPLICIT_SYS */
2322