3 * Copyright (c) 1996-2000, Nick Ing-Simmons
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.
18 #define PERLIO_NOT_STDIO 0
19 #if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
20 /* #define PerlIO FILE */
23 * This file provides those parts of PerlIO abstraction
24 * which are not #defined in iperlsys.h.
25 * Which these are depends on various Configure #ifdef's
29 #define PERL_IN_PERLIO_C
32 #if !defined(PERL_IMPLICIT_SYS)
34 #ifdef PERLIO_IS_STDIO
39 /* Does nothing (yet) except force this file to be included
40 in perl binary. That allows this file to force inclusion
41 of other functions that may be required by loadable
42 extensions e.g. for FileHandle::tmpfile
53 #else /* PERLIO_IS_STDIO */
60 /* This section is just to make sure these functions
61 get pulled in from libsfio.a
74 /* Force this file to be included in perl binary. Which allows
75 * this file to force inclusion of other functions that may be
76 * required by loadable extensions e.g. for FileHandle::tmpfile
80 * sfio does its own 'autoflush' on stdout in common cases.
81 * Flush results in a lot of lseek()s to regular files and
82 * lot of small writes to pipes.
84 sfset(sfstdout,SF_SHARE,0);
89 /*======================================================================================*/
91 /* Implement all the PerlIO interface ourselves.
95 void PerlIO_debug(char *fmt,...) __attribute__((format(printf,1,2)));
99 PerlIO_debug(char *fmt,...)
104 char *s = getenv("PERLIO_DEBUG");
106 dbg = open(s,O_WRONLY|O_CREAT|O_APPEND,0666);
114 SV *sv = newSVpvn("",0);
118 sv_vcatpvf(sv, fmt, &ap);
126 #define PERLIO_F_EOF 0x010000
127 #define PERLIO_F_ERROR 0x020000
128 #define PERLIO_F_LINEBUF 0x040000
129 #define PERLIO_F_TEMP 0x080000
130 #define PERLIO_F_RDBUF 0x100000
131 #define PERLIO_F_WRBUF 0x200000
132 #define PERLIO_F_OPEN 0x400000
133 #define PERLIO_F_USED 0x800000
138 IV fd; /* Maybe pointer on some OSes */
139 int oflags; /* open/fcntl flags */
140 STDCHAR *buf; /* Start of buffer */
141 STDCHAR *end; /* End of valid part of buffer */
142 STDCHAR *ptr; /* Current position in buffer */
143 Size_t bufsiz; /* Size of buffer */
148 int _perlio_size = 0;
149 PerlIO **_perlio = NULL;
152 PerlIO_alloc_buf(PerlIO *f)
156 New('B',f->buf,f->bufsiz,char);
159 f->buf = (STDCHAR *)&f->oneword;
160 f->bufsiz = sizeof(f->oneword);
164 PerlIO_debug(__FUNCTION__ " f=%p b=%p p=%p e=%p\n",
165 f,f->buf,f->ptr,f->end);
170 PerlIO_flush(PerlIO *f)
175 PerlIO_debug(__FUNCTION__ " f=%p flags=%08X c=%d buf=%p ptr=%p\n",
176 f,f->flags,(f->ptr-f->buf),f->buf,f->ptr);
177 if (f->flags & PERLIO_F_WRBUF)
183 count = write(f->fd,p,f->ptr - p);
188 else if (count < 0 && errno != EINTR)
194 f->posn += (p - f->buf);
196 else if (f->flags & PERLIO_F_RDBUF)
198 f->posn += (f->ptr - f->buf);
201 f->posn = lseek(f->fd,f->posn,SEEK_SET);
204 f->ptr = f->end = f->buf;
205 f->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
210 for (i=_perlio_size; i >= 0; i--)
212 if ((f = _perlio[i]))
214 if (PerlIO_flush(f) != 0)
223 PerlIO_oflags(const char *mode)
226 PerlIO_debug(__FUNCTION__ " %s = ",mode);
239 oflags = O_CREAT|O_TRUNC;
250 oflags = O_CREAT|O_TRUNC|O_APPEND;
260 if (*mode || oflags == -1)
265 PerlIO_debug(" %X '%s'\n",oflags,mode);
270 PerlIO_allocate(void)
276 PerlIO **table = _perlio;
277 while (i < _perlio_size)
280 PerlIO_debug(__FUNCTION__ " try %d %p\n",i,f);
283 Newz('F',f,1,PerlIO);
288 if (!(f->flags & PERLIO_F_USED))
291 f->flags = PERLIO_F_USED;
296 Newz('I',table,_perlio_size+16,PerlIO *);
299 Copy(_perlio,table,_perlio_size,PerlIO *);
309 PerlIO_fdopen(int fd, const char *mode)
314 if ((f = PerlIO_allocate()))
317 f->oflags = PerlIO_oflags(mode);
318 f->flags |= (PERLIO_F_OPEN|PERLIO_F_USED);
321 PerlIO_debug(__FUNCTION__ " fd=%d m=%s f=%p\n",fd,mode,f);
327 PerlIO_fileno(PerlIO *f)
329 if (f && (f->flags & PERLIO_F_OPEN))
338 PerlIO_close(PerlIO *f)
344 while ((code = close(f->fd)) && errno == EINTR);
345 f->flags &= ~PERLIO_F_OPEN;
347 if (f->buf && f->buf != (STDCHAR *) &f->oneword)
352 f->ptr = f->end = f->buf;
353 f->flags &= ~(PERLIO_F_USED|PERLIO_F_RDBUF|PERLIO_F_WRBUF);
362 PerlIO_debug(__FUNCTION__ "\n");
363 for (i=_perlio_size-1; i >= 0; i--)
365 PerlIO *f = _perlio[i];
380 PerlIO_open(const char *path, const char *mode)
383 int oflags = PerlIO_oflags(mode);
386 int fd = open(path,oflags,0666);
389 PerlIO_debug(__FUNCTION__ "fd=%d\n",fd);
390 f = PerlIO_fdopen(fd,mode);
395 PerlIO_debug(__FUNCTION__ " path=%s m=%s f=%p\n",path,mode,f);
401 PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
403 PerlIO_debug(__FUNCTION__ " n=%s m=%s f=%p\n",path,mode,f);
406 int oflags = PerlIO_oflags(mode);
410 int fd = open(path,oflags,0666);
413 PerlIO_debug(__FUNCTION__ "fd=%d\n",fd);
415 f->flags |= (PERLIO_F_OPEN|PERLIO_F_USED);
423 return PerlIO_open(path,mode);
431 atexit(&PerlIO_cleanup);
432 PerlIO_fdopen(0,"r");
433 PerlIO_fdopen(1,"w");
434 PerlIO_fdopen(2,"w");
436 PerlIO_debug(__FUNCTION__ "\n");
466 #undef PerlIO_fast_gets
468 PerlIO_fast_gets(PerlIO *f)
473 #undef PerlIO_has_cntptr
475 PerlIO_has_cntptr(PerlIO *f)
480 #undef PerlIO_canset_cnt
482 PerlIO_canset_cnt(PerlIO *f)
487 #undef PerlIO_set_cnt
489 PerlIO_set_cnt(PerlIO *f, int cnt)
496 f->ptr = f->end - cnt;
497 assert(f->ptr >= f->buf);
501 #undef PerlIO_get_cnt
503 PerlIO_get_cnt(PerlIO *f)
509 if (f->flags & PERLIO_F_RDBUF)
510 return (f->end - f->ptr);
515 #undef PerlIO_set_ptrcnt
517 PerlIO_set_ptrcnt(PerlIO *f, STDCHAR *ptr, int cnt)
525 assert(f->ptr >= f->buf);
526 if (PerlIO_get_cnt(f) != cnt)
529 assert(PerlIO_get_cnt(f) != cnt);
534 #undef PerlIO_get_bufsiz
536 PerlIO_get_bufsiz(PerlIO *f)
547 #undef PerlIO_get_ptr
549 PerlIO_get_ptr(PerlIO *f)
560 #undef PerlIO_get_base
562 PerlIO_get_base(PerlIO *f)
573 #undef PerlIO_has_base
575 PerlIO_has_base(PerlIO *f)
581 return f->buf != NULL;
587 PerlIO_puts(PerlIO *f, const char *s)
589 STRLEN len = strlen(s);
590 return PerlIO_write(f,s,len);
595 PerlIO_eof(PerlIO *f)
599 return (f->flags & PERLIO_F_EOF) != 0;
604 #undef PerlIO_getname
606 PerlIO_getname(PerlIO *f, char *buf)
609 return fgetname(f,buf);
612 Perl_croak(aTHX_ "Don't know how to get file name");
619 PerlIO_ungetc(PerlIO *f, int ch)
621 PerlIO_debug(__FUNCTION__ " f=%p c=%c\n",f,ch);
622 if (f->buf && (f->flags & PERLIO_F_RDBUF) && f->ptr > f->buf)
632 PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
634 STDCHAR *buf = (STDCHAR *) vbuf;
643 SSize_t avail = (f->end - f->ptr);
644 if ((SSize_t) count < avail)
648 Copy(f->ptr,buf,avail,char);
654 if (count && (f->ptr >= f->end))
656 f->ptr = f->end = f->buf;
657 avail = read(f->fd,f->ptr,f->bufsiz);
661 f->flags |= PERLIO_F_EOF;
662 else if (errno == EINTR)
665 f->flags |= PERLIO_F_ERROR;
668 f->end = f->buf+avail;
669 f->flags |= PERLIO_F_RDBUF;
679 PerlIO_getc(PerlIO *f)
682 int count = PerlIO_read(f,&buf,1);
690 PerlIO_error(PerlIO *f)
694 return f->flags & PERLIO_F_ERROR;
699 #undef PerlIO_clearerr
701 PerlIO_clearerr(PerlIO *f)
705 f->flags &= ~PERLIO_F_ERROR;
709 #undef PerlIO_setlinebuf
711 PerlIO_setlinebuf(PerlIO *f)
715 f->flags &= ~PERLIO_F_LINEBUF;
721 PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
723 const STDCHAR *buf = (const STDCHAR *) vbuf;
725 PerlIO_debug(__FUNCTION__ " f=%p c=%d\n",f,count);
732 Size_t avail = f->bufsiz - (f->ptr - f->buf);
735 f->flags |= PERLIO_F_WRBUF;
736 if (f->flags & PERLIO_F_LINEBUF)
753 Copy(buf,f->ptr,avail,char);
760 if (f->ptr >= (f->buf + f->bufsiz))
769 PerlIO_putc(PerlIO *f, int ch)
772 PerlIO_write(f,&ch,1);
777 PerlIO_tell(PerlIO *f)
779 Off_t posn = f->posn + (f->ptr - f->buf);
785 PerlIO_seek(PerlIO *f, Off_t offset, int whence)
787 int code = PerlIO_flush(f);
790 f->flags &= ~PERLIO_F_EOF;
791 f->posn = lseek(f->fd,offset,whence);
792 if (f->posn == (Off_t) -1)
803 PerlIO_rewind(PerlIO *f)
805 PerlIO_seek(f,(Off_t)0,SEEK_SET);
808 #undef PerlIO_vprintf
810 PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
813 SV *sv = newSV(strlen(fmt));
816 sv_vcatpvf(sv, fmt, &ap);
818 return (PerlIO_write(f,s,len) == len) ? 1 : 0;
823 PerlIO_printf(PerlIO *f,const char *fmt,...)
828 result = PerlIO_vprintf(f,fmt,ap);
833 #undef PerlIO_stdoutf
835 PerlIO_stdoutf(const char *fmt,...)
840 result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
845 #undef PerlIO_tmpfile
850 SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
851 int fd = mkstemp(SvPVX(sv));
855 PerlIO *f = PerlIO_fdopen(fd,"w+");
858 f->flags |= PERLIO_F_TEMP;
866 #undef PerlIO_importFILE
868 PerlIO_importFILE(FILE *f, int fl)
871 return PerlIO_fdopen(fd,"r+");
874 #undef PerlIO_exportFILE
876 PerlIO_exportFILE(PerlIO *f, int fl)
879 return fdopen(PerlIO_fileno(f),"r+");
882 #undef PerlIO_findFILE
884 PerlIO_findFILE(PerlIO *f)
886 return PerlIO_exportFILE(f,0);
889 #undef PerlIO_releaseFILE
891 PerlIO_releaseFILE(PerlIO *p, FILE *f)
898 /*======================================================================================*/
900 #endif /* USE_SFIO */
901 #endif /* PERLIO_IS_STDIO */
906 PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
908 return PerlIO_seek(f,*pos,0);
911 #ifndef PERLIO_IS_STDIO
914 PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
916 #if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
917 return fsetpos64(f, pos);
919 return fsetpos(f, pos);
928 PerlIO_getpos(PerlIO *f, Fpos_t *pos)
930 *pos = PerlIO_tell(f);
934 #ifndef PERLIO_IS_STDIO
937 PerlIO_getpos(PerlIO *f, Fpos_t *pos)
939 #if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
940 return fgetpos64(f, pos);
942 return fgetpos(f, pos);
948 #if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
951 vprintf(char *pat, char *args)
953 _doprnt(pat, args, stdout);
954 return 0; /* wrong, but perl doesn't use the return value */
958 vfprintf(FILE *fd, char *pat, char *args)
960 _doprnt(pat, args, fd);
961 return 0; /* wrong, but perl doesn't use the return value */
966 #ifndef PerlIO_vsprintf
968 PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
970 int val = vsprintf(s, fmt, ap);
973 if (strlen(s) >= (STRLEN)n)
976 PerlIO_puts(Perl_error_log,"panic: sprintf overflow - memory corrupted!\n");
984 #ifndef PerlIO_sprintf
986 PerlIO_sprintf(char *s, int n, const char *fmt,...)
991 result = PerlIO_vsprintf(s, n, fmt, ap);
997 #endif /* !PERL_IMPLICIT_SYS */