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