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.
17 #define PERLIO_NOT_STDIO 0
18 #if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
19 /* #define PerlIO FILE */
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
28 #define PERL_IN_PERLIO_C
31 #if !defined(PERL_IMPLICIT_SYS)
33 #ifdef PERLIO_IS_STDIO
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
52 #else /* PERLIO_IS_STDIO */
59 /* This section is just to make sure these functions
60 get pulled in from libsfio.a
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
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.
83 sfset(sfstdout,SF_SHARE,0);
88 /*======================================================================================*/
90 /* Implement all the PerlIO interface ourselves.
98 void PerlIO_debug(char *fmt,...) __attribute__((format(printf,1,2)));
102 PerlIO_debug(char *fmt,...)
107 char *s = getenv("PERLIO_DEBUG");
109 dbg = open(s,O_WRONLY|O_CREAT|O_APPEND,0666);
117 SV *sv = newSVpvn("",0);
121 sv_vcatpvf(sv, fmt, &ap);
129 #define PERLIO_F_EOF 0x010000
130 #define PERLIO_F_ERROR 0x020000
131 #define PERLIO_F_LINEBUF 0x040000
132 #define PERLIO_F_TEMP 0x080000
133 #define PERLIO_F_RDBUF 0x100000
134 #define PERLIO_F_WRBUF 0x200000
135 #define PERLIO_F_OPEN 0x400000
136 #define PERLIO_F_USED 0x800000
141 IV fd; /* Maybe pointer on some OSes */
142 int oflags; /* open/fcntl flags */
143 STDCHAR *buf; /* Start of buffer */
144 STDCHAR *end; /* End of valid part of buffer */
145 STDCHAR *ptr; /* Current position in buffer */
146 Size_t bufsiz; /* Size of buffer */
147 Off_t posn; /* Offset of f->buf into the file */
151 int _perlio_size = 0;
152 PerlIO **_perlio = NULL;
155 PerlIO_alloc_buf(PerlIO *f)
159 New('B',f->buf,f->bufsiz,char);
162 f->buf = (STDCHAR *)&f->oneword;
163 f->bufsiz = sizeof(f->oneword);
167 PerlIO_debug(__FUNCTION__ " f=%p b=%p p=%p e=%p\n",
168 f,f->buf,f->ptr,f->end);
173 PerlIO_flush(PerlIO *f)
178 PerlIO_debug(__FUNCTION__ " f=%p flags=%08X c=%d buf=%p ptr=%p\n",
179 f,f->flags,(f->ptr-f->buf),f->buf,f->ptr);
180 if (f->flags & PERLIO_F_WRBUF)
186 count = write(f->fd,p,f->ptr - p);
191 else if (count < 0 && errno != EINTR)
193 f->flags |= PERLIO_F_ERROR;
198 f->posn += (p - f->buf);
199 PerlIO_debug(__FUNCTION__ "(w) f=%p p=%ld\n",f,(long)f->posn);
201 else if (f->flags & PERLIO_F_RDBUF)
203 f->posn += (f->ptr - f->buf);
206 f->posn = lseek(f->fd,f->posn,SEEK_SET);
208 PerlIO_debug(__FUNCTION__ "(r+) f=%p p=%ld\n",f,(long)f->posn);
212 PerlIO_debug(__FUNCTION__ "(?) f=%p p=%ld\n",f,(long)f->posn);
214 f->ptr = f->end = f->buf;
215 f->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
220 for (i=_perlio_size; i >= 0; i--)
222 if ((f = _perlio[i]))
224 if (PerlIO_flush(f) != 0)
233 PerlIO_oflags(const char *mode)
236 PerlIO_debug(__FUNCTION__ " %s = ",mode);
249 oflags = O_CREAT|O_TRUNC;
260 oflags = O_CREAT|O_APPEND;
270 if (*mode || oflags == -1)
275 PerlIO_debug(" %X '%s'\n",oflags,mode);
280 PerlIO_allocate(void)
286 PerlIO **table = _perlio;
287 while (i < _perlio_size)
290 PerlIO_debug(__FUNCTION__ " try %d %p\n",i,f);
293 Newz('F',f,1,PerlIO);
298 if (!(f->flags & PERLIO_F_USED))
301 f->flags = PERLIO_F_USED;
306 Newz('I',table,_perlio_size+16,PerlIO *);
309 Copy(_perlio,table,_perlio_size,PerlIO *);
319 PerlIO_fdopen(int fd, const char *mode)
324 if ((f = PerlIO_allocate()))
327 f->oflags = PerlIO_oflags(mode);
328 f->flags |= (PERLIO_F_OPEN|PERLIO_F_USED);
331 PerlIO_debug(__FUNCTION__ " fd=%d m=%s f=%p\n",fd,mode,f);
337 PerlIO_fileno(PerlIO *f)
339 if (f && (f->flags & PERLIO_F_OPEN))
348 PerlIO_close(PerlIO *f)
353 if (PerlIO_flush(f) != 0)
355 while (close(f->fd) != 0)
363 f->flags &= ~PERLIO_F_OPEN;
365 if (f->buf && f->buf != (STDCHAR *) &f->oneword)
370 f->ptr = f->end = f->buf;
371 f->flags &= ~(PERLIO_F_USED|PERLIO_F_RDBUF|PERLIO_F_WRBUF);
380 PerlIO_debug(__FUNCTION__ "\n");
381 for (i=_perlio_size-1; i >= 0; i--)
383 PerlIO *f = _perlio[i];
398 PerlIO_open(const char *path, const char *mode)
401 int oflags = PerlIO_oflags(mode);
404 int fd = open(path,oflags,0666);
407 PerlIO_debug(__FUNCTION__ "fd=%d\n",fd);
408 f = PerlIO_fdopen(fd,mode);
413 PerlIO_debug(__FUNCTION__ " path=%s m=%s f=%p\n",path,mode,f);
419 PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
421 PerlIO_debug(__FUNCTION__ " n=%s m=%s f=%p\n",path,mode,f);
424 int oflags = PerlIO_oflags(mode);
428 int fd = open(path,oflags,0666);
431 PerlIO_debug(__FUNCTION__ "fd=%d\n",fd);
433 f->flags |= (PERLIO_F_OPEN|PERLIO_F_USED);
441 return PerlIO_open(path,mode);
449 atexit(&PerlIO_cleanup);
450 PerlIO_fdopen(0,"r");
451 PerlIO_fdopen(1,"w");
452 PerlIO_fdopen(2,"w");
454 PerlIO_debug(__FUNCTION__ "\n");
484 #undef PerlIO_fast_gets
486 PerlIO_fast_gets(PerlIO *f)
491 #undef PerlIO_has_cntptr
493 PerlIO_has_cntptr(PerlIO *f)
498 #undef PerlIO_canset_cnt
500 PerlIO_canset_cnt(PerlIO *f)
505 #undef PerlIO_set_cnt
507 PerlIO_set_cnt(PerlIO *f, int cnt)
514 f->ptr = f->end - cnt;
515 assert(f->ptr >= f->buf);
519 #undef PerlIO_get_cnt
521 PerlIO_get_cnt(PerlIO *f)
527 if (f->flags & PERLIO_F_RDBUF)
528 return (f->end - f->ptr);
533 #undef PerlIO_set_ptrcnt
535 PerlIO_set_ptrcnt(PerlIO *f, STDCHAR *ptr, int cnt)
543 assert(f->ptr >= f->buf);
544 if (PerlIO_get_cnt(f) != cnt)
547 assert(PerlIO_get_cnt(f) != cnt);
549 f->flags |= PERLIO_F_RDBUF;
553 #undef PerlIO_get_bufsiz
555 PerlIO_get_bufsiz(PerlIO *f)
566 #undef PerlIO_get_ptr
568 PerlIO_get_ptr(PerlIO *f)
579 #undef PerlIO_get_base
581 PerlIO_get_base(PerlIO *f)
592 #undef PerlIO_has_base
594 PerlIO_has_base(PerlIO *f)
600 return f->buf != NULL;
606 PerlIO_puts(PerlIO *f, const char *s)
608 STRLEN len = strlen(s);
609 return PerlIO_write(f,s,len);
614 PerlIO_eof(PerlIO *f)
618 return (f->flags & PERLIO_F_EOF) != 0;
623 #undef PerlIO_getname
625 PerlIO_getname(PerlIO *f, char *buf)
628 return fgetname(f,buf);
631 Perl_croak(aTHX_ "Don't know how to get file name");
638 PerlIO_ungetc(PerlIO *f, int ch)
640 if (f->buf && (f->flags & PERLIO_F_RDBUF) && f->ptr > f->buf)
643 PerlIO_debug(__FUNCTION__ " f=%p c=%c\n",f,ch);
646 PerlIO_debug(__FUNCTION__ " f=%p c=%c - cannot\n",f,ch);
652 PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
654 STDCHAR *buf = (STDCHAR *) vbuf;
663 SSize_t avail = (f->end - f->ptr);
664 if ((SSize_t) count < avail)
668 Copy(f->ptr,buf,avail,char);
674 if (count && (f->ptr >= f->end))
677 f->ptr = f->end = f->buf;
678 avail = read(f->fd,f->ptr,f->bufsiz);
682 f->flags |= PERLIO_F_EOF;
683 else if (errno == EINTR)
686 f->flags |= PERLIO_F_ERROR;
689 f->end = f->buf+avail;
690 f->flags |= PERLIO_F_RDBUF;
700 PerlIO_getc(PerlIO *f)
703 int count = PerlIO_read(f,&buf,1);
711 PerlIO_error(PerlIO *f)
715 return f->flags & PERLIO_F_ERROR;
720 #undef PerlIO_clearerr
722 PerlIO_clearerr(PerlIO *f)
726 f->flags &= ~PERLIO_F_ERROR;
730 #undef PerlIO_setlinebuf
732 PerlIO_setlinebuf(PerlIO *f)
736 f->flags &= ~PERLIO_F_LINEBUF;
742 PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
744 const STDCHAR *buf = (const STDCHAR *) vbuf;
746 PerlIO_debug(__FUNCTION__ " f=%p c=%d\n",f,count);
753 SSize_t avail = f->bufsiz - (f->ptr - f->buf);
754 if ((SSize_t) count < avail)
756 f->flags |= PERLIO_F_WRBUF;
757 if (1 || (f->flags & PERLIO_F_LINEBUF))
777 Copy(buf,f->ptr,avail,char);
784 if (f->ptr >= (f->buf + f->bufsiz))
793 PerlIO_putc(PerlIO *f, int ch)
796 PerlIO_write(f,&ch,1);
801 PerlIO_tell(PerlIO *f)
803 Off_t posn = f->posn;
805 posn += (f->ptr - f->buf);
806 PerlIO_debug(__FUNCTION__ " f=%p r=%ld b=%p p=%p e=%ld\n",
807 f,(long)f->posn,f->buf,f->ptr,(long)posn);
813 PerlIO_seek(PerlIO *f, Off_t offset, int whence)
816 PerlIO_debug(__FUNCTION__ " f=%p i=%ld+%d\n",f,(long)f->posn,(f->ptr-f->buf));
817 code = PerlIO_flush(f);
820 f->flags &= ~PERLIO_F_EOF;
821 f->posn = PerlLIO_lseek(f->fd,offset,whence);
822 PerlIO_debug(__FUNCTION__ " f=%p o=%ld w=%d p=%ld\n",
823 f,(long)offset,whence,(long)f->posn);
824 if (f->posn == (Off_t) -1)
835 PerlIO_rewind(PerlIO *f)
837 PerlIO_seek(f,(Off_t)0,SEEK_SET);
840 #undef PerlIO_vprintf
842 PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
845 SV *sv = newSVpvn("",0);
848 sv_vcatpvf(sv, fmt, &ap);
850 return PerlIO_write(f,s,len);
855 PerlIO_printf(PerlIO *f,const char *fmt,...)
860 result = PerlIO_vprintf(f,fmt,ap);
865 #undef PerlIO_stdoutf
867 PerlIO_stdoutf(const char *fmt,...)
872 result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
877 #undef PerlIO_tmpfile
882 SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
883 int fd = mkstemp(SvPVX(sv));
887 PerlIO *f = PerlIO_fdopen(fd,"w+");
890 f->flags |= PERLIO_F_TEMP;
898 #undef PerlIO_importFILE
900 PerlIO_importFILE(FILE *f, int fl)
903 return PerlIO_fdopen(fd,"r+");
906 #undef PerlIO_exportFILE
908 PerlIO_exportFILE(PerlIO *f, int fl)
911 return fdopen(PerlIO_fileno(f),"r+");
914 #undef PerlIO_findFILE
916 PerlIO_findFILE(PerlIO *f)
918 return PerlIO_exportFILE(f,0);
921 #undef PerlIO_releaseFILE
923 PerlIO_releaseFILE(PerlIO *p, FILE *f)
930 /*======================================================================================*/
932 #endif /* USE_SFIO */
933 #endif /* PERLIO_IS_STDIO */
938 PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
940 return PerlIO_seek(f,*pos,0);
943 #ifndef PERLIO_IS_STDIO
946 PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
948 #if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
949 return fsetpos64(f, pos);
951 return fsetpos(f, pos);
960 PerlIO_getpos(PerlIO *f, Fpos_t *pos)
962 *pos = PerlIO_tell(f);
966 #ifndef PERLIO_IS_STDIO
969 PerlIO_getpos(PerlIO *f, Fpos_t *pos)
971 #if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
972 return fgetpos64(f, pos);
974 return fgetpos(f, pos);
980 #if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
983 vprintf(char *pat, char *args)
985 _doprnt(pat, args, stdout);
986 return 0; /* wrong, but perl doesn't use the return value */
990 vfprintf(FILE *fd, char *pat, char *args)
992 _doprnt(pat, args, fd);
993 return 0; /* wrong, but perl doesn't use the return value */
998 #ifndef PerlIO_vsprintf
1000 PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
1002 int val = vsprintf(s, fmt, ap);
1005 if (strlen(s) >= (STRLEN)n)
1008 PerlIO_puts(Perl_error_log,"panic: sprintf overflow - memory corrupted!\n");
1016 #ifndef PerlIO_sprintf
1018 PerlIO_sprintf(char *s, int n, const char *fmt,...)
1023 result = PerlIO_vsprintf(s, n, fmt, ap);
1029 #endif /* !PERL_IMPLICIT_SYS */