/* Implement all the PerlIO interface ourselves.
*/
+#include "perliol.h"
+
/* We _MUST_ have <unistd.h> if we are using lseek() and may have large files */
#ifdef I_UNISTD
#include <unistd.h>
#include "XSUB.h"
-#undef printf
-void PerlIO_debug(char *fmt,...) __attribute__((format(printf,1,2)));
+void PerlIO_debug(char *fmt,...) __attribute__((format(__printf__,1,2)));
void
PerlIO_debug(char *fmt,...)
static int dbg = 0;
if (!dbg)
{
- char *s = getenv("PERLIO_DEBUG");
+ char *s = PerlEnv_getenv("PERLIO_DEBUG");
if (s && *s)
- dbg = open(s,O_WRONLY|O_CREAT|O_APPEND,0666);
+ dbg = PerlLIO_open3(s,O_WRONLY|O_CREAT|O_APPEND,0666);
else
dbg = -1;
}
Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap);
s = SvPV(sv,len);
- write(dbg,s,len);
+ PerlLIO_write(dbg,s,len);
va_end(ap);
SvREFCNT_dec(sv);
}
/*--------------------------------------------------------------------------------------*/
-typedef struct _PerlIO_funcs PerlIO_funcs;
-struct _PerlIO_funcs
-{
- char * name;
- Size_t size;
- IV kind;
- IV (*Fileno)(PerlIO *f);
- PerlIO * (*Fdopen)(PerlIO_funcs *tab, int fd, const char *mode);
- PerlIO * (*Open)(PerlIO_funcs *tab, const char *path, const char *mode);
- int (*Reopen)(const char *path, const char *mode, PerlIO *f);
- IV (*Pushed)(PerlIO *f,const char *mode);
- IV (*Popped)(PerlIO *f);
- /* Unix-like functions - cf sfio line disciplines */
- SSize_t (*Read)(PerlIO *f, void *vbuf, Size_t count);
- SSize_t (*Unread)(PerlIO *f, const void *vbuf, Size_t count);
- SSize_t (*Write)(PerlIO *f, const void *vbuf, Size_t count);
- IV (*Seek)(PerlIO *f, Off_t offset, int whence);
- Off_t (*Tell)(PerlIO *f);
- IV (*Close)(PerlIO *f);
- /* Stdio-like buffered IO functions */
- IV (*Flush)(PerlIO *f);
- IV (*Fill)(PerlIO *f);
- IV (*Eof)(PerlIO *f);
- IV (*Error)(PerlIO *f);
- void (*Clearerr)(PerlIO *f);
- void (*Setlinebuf)(PerlIO *f);
- /* Perl's snooping functions */
- STDCHAR * (*Get_base)(PerlIO *f);
- Size_t (*Get_bufsiz)(PerlIO *f);
- STDCHAR * (*Get_ptr)(PerlIO *f);
- SSize_t (*Get_cnt)(PerlIO *f);
- void (*Set_ptrcnt)(PerlIO *f,STDCHAR *ptr,SSize_t cnt);
-};
-
-struct _PerlIO
-{
- PerlIOl * next; /* Lower layer */
- PerlIO_funcs * tab; /* Functions for this layer */
- IV flags; /* Various flags for state */
-};
-
-/*--------------------------------------------------------------------------------------*/
-
-/* Flag values */
-#define PERLIO_F_EOF 0x00010000
-#define PERLIO_F_CANWRITE 0x00020000
-#define PERLIO_F_CANREAD 0x00040000
-#define PERLIO_F_ERROR 0x00080000
-#define PERLIO_F_TRUNCATE 0x00100000
-#define PERLIO_F_APPEND 0x00200000
-#define PERLIO_F_BINARY 0x00400000
-#define PERLIO_F_UTF8 0x00800000
-#define PERLIO_F_LINEBUF 0x01000000
-#define PERLIO_F_WRBUF 0x02000000
-#define PERLIO_F_RDBUF 0x04000000
-#define PERLIO_F_TEMP 0x08000000
-#define PERLIO_F_OPEN 0x10000000
-
-#define PerlIOBase(f) (*(f))
-#define PerlIOSelf(f,type) ((type *)PerlIOBase(f))
-#define PerlIONext(f) (&(PerlIOBase(f)->next))
-
-/*--------------------------------------------------------------------------------------*/
/* Inner level routines */
/* Table of pointers to the PerlIO structs (malloc'ed) */
return (*PerlIOBase(f)->tab->Fileno)(f);
}
-
-extern PerlIO_funcs PerlIO_unix;
-extern PerlIO_funcs PerlIO_perlio;
-extern PerlIO_funcs PerlIO_stdio;
-#ifdef HAS_MMAP
-extern PerlIO_funcs PerlIO_mmap;
-#endif
-
XS(XS_perlio_import)
{
dXSARGS;
int len;
if (!PerlIO_layer_hv)
{
- char *s = getenv("PERLIO");
+ char *s = PerlEnv_getenv("PERLIO");
newXS("perlio::import",XS_perlio_import,__FILE__);
newXS("perlio::unimport",XS_perlio_unimport,__FILE__);
- PerlIO_layer_hv = get_hv("perlio::layers",GV_ADD|GV_ADDMULTI);
- PerlIO_layer_av = get_av("perlio::layers",GV_ADD|GV_ADDMULTI);
+ PerlIO_layer_hv = get_hv("open::layers",GV_ADD|GV_ADDMULTI);
+ PerlIO_layer_av = get_av("open::layers",GV_ADD|GV_ADDMULTI);
PerlIO_define_layer(&PerlIO_unix);
PerlIO_define_layer(&PerlIO_perlio);
PerlIO_define_layer(&PerlIO_stdio);
{
while (*s)
{
- while (*s && isspace((unsigned char)*s))
+ while (*s && isSPACE((unsigned char)*s))
s++;
if (*s)
{
char *e = s;
SV *layer;
- while (*e && !isspace((unsigned char)*e))
+ while (*e && !isSPACE((unsigned char)*e))
e++;
layer = PerlIO_find_layer(s,e-s);
if (layer)
}
}
+PerlIO *
+PerlIO_push(PerlIO *f,PerlIO_funcs *tab,const char *mode)
+{
+ PerlIOl *l = NULL;
+ Newc('L',l,tab->size,char,PerlIOl);
+ if (l)
+ {
+ Zero(l,tab->size,char);
+ l->next = *f;
+ l->tab = tab;
+ *f = l;
+ if ((*l->tab->Pushed)(f,mode) != 0)
+ {
+ PerlIO_pop(f);
+ return NULL;
+ }
+ }
+ return f;
+}
+
#undef PerlIO_fdopen
PerlIO *
PerlIO_fdopen(int fd, const char *mode)
return (*tab->Open)(tab,path,mode);
}
-IV
-PerlIOBase_pushed(PerlIO *f, const char *mode)
-{
- PerlIOl *l = PerlIOBase(f);
- l->flags &= ~(PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
- PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
- if (mode)
- {
- switch (*mode++)
- {
- case 'r':
- l->flags = PERLIO_F_CANREAD;
- break;
- case 'a':
- l->flags = PERLIO_F_APPEND|PERLIO_F_CANWRITE;
- break;
- case 'w':
- l->flags = PERLIO_F_TRUNCATE|PERLIO_F_CANWRITE;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
- while (*mode)
- {
- switch (*mode++)
- {
- case '+':
- l->flags |= PERLIO_F_CANREAD|PERLIO_F_CANWRITE;
- break;
- case 'b':
- l->flags |= PERLIO_F_BINARY;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
- }
- }
- else
- {
- if (l->next)
- {
- l->flags |= l->next->flags &
- (PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
- PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
- }
- }
- return 0;
-}
-
#undef PerlIO_reopen
PerlIO *
PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
return PerlIO_fileno(PerlIONext(f));
}
-PerlIO *
-PerlIO_push(PerlIO *f,PerlIO_funcs *tab,const char *mode)
+IV
+PerlIOBase_pushed(PerlIO *f, const char *mode)
{
- PerlIOl *l = NULL;
- Newc('L',l,tab->size,char,PerlIOl);
- if (l)
+ PerlIOl *l = PerlIOBase(f);
+ l->flags &= ~(PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
+ PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
+ if (mode)
{
- Zero(l,tab->size,char);
- l->next = *f;
- l->tab = tab;
- *f = l;
- if ((*l->tab->Pushed)(f,mode) != 0)
+ switch (*mode++)
{
- PerlIO_pop(f);
- return NULL;
+ case 'r':
+ l->flags = PERLIO_F_CANREAD;
+ break;
+ case 'a':
+ l->flags = PERLIO_F_APPEND|PERLIO_F_CANWRITE;
+ break;
+ case 'w':
+ l->flags = PERLIO_F_TRUNCATE|PERLIO_F_CANWRITE;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ while (*mode)
+ {
+ switch (*mode++)
+ {
+ case '+':
+ l->flags |= PERLIO_F_CANREAD|PERLIO_F_CANWRITE;
+ break;
+ case 'b':
+ l->flags |= PERLIO_F_BINARY;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
}
}
- return f;
+ else
+ {
+ if (l->next)
+ {
+ l->flags |= l->next->flags &
+ (PERLIO_F_CANREAD|PERLIO_F_CANWRITE|
+ PERLIO_F_TRUNCATE|PERLIO_F_APPEND|PERLIO_F_BINARY);
+ }
+ }
+ return 0;
+}
+
+IV
+PerlIOBase_popped(PerlIO *f)
+{
+ return 0;
}
SSize_t
}
-
-
/*--------------------------------------------------------------------------------------*/
/* Bottom-most level for UNIX-like case */
int oflags = PerlIOUnix_oflags(mode);
if (oflags != -1)
{
- int fd = open(path,oflags,0666);
+ int fd = PerlLIO_open3(path,oflags,0666);
if (fd >= 0)
{
PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix);
(*PerlIOBase(f)->tab->Close)(f);
if (oflags != -1)
{
- int fd = open(path,oflags,0666);
+ int fd = PerlLIO_open3(path,oflags,0666);
if (fd >= 0)
{
s->fd = fd;
return 0;
while (1)
{
- SSize_t len = read(fd,vbuf,count);
+ SSize_t len = PerlLIO_read(fd,vbuf,count);
if (len >= 0 || errno != EINTR)
{
if (len < 0)
int fd = PerlIOSelf(f,PerlIOUnix)->fd;
while (1)
{
- SSize_t len = write(fd,vbuf,count);
+ SSize_t len = PerlLIO_write(fd,vbuf,count);
if (len >= 0 || errno != EINTR)
{
if (len < 0)
IV
PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence)
{
- Off_t new = lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence);
+ Off_t new = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence);
PerlIOBase(f)->flags &= ~PERLIO_F_EOF;
return (new == (Off_t) -1) ? -1 : 0;
}
Off_t
PerlIOUnix_tell(PerlIO *f)
{
- return lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
+ return PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
}
IV
{
int fd = PerlIOSelf(f,PerlIOUnix)->fd;
int code = 0;
- while (close(fd) != 0)
+ while (PerlLIO_close(fd) != 0)
{
if (errno != EINTR)
{
PerlIOUnix_seek,
PerlIOUnix_tell,
PerlIOUnix_close,
- PerlIOBase_noop_ok,
- PerlIOBase_noop_fail,
+ PerlIOBase_noop_ok, /* flush */
+ PerlIOBase_noop_fail, /* fill */
PerlIOBase_eof,
PerlIOBase_error,
PerlIOBase_clearerr,
/*--------------------------------------------------------------------------------------*/
/* stdio as a layer */
-#if defined(USE_64_BIT_STDIO) && defined(HAS_FSEEKO) && !defined(USE_FSEEK64)
-#define fseek fseeko
-#endif
-
-#if defined(USE_64_BIT_STDIO) && defined(HAS_FTELLO) && !defined(USE_FTELL64)
-#define ftell ftello
-#endif
-
-
typedef struct
{
struct _PerlIO base;
/*--------------------------------------------------------------------------------------*/
/* perlio buffer layer */
-typedef struct
-{
- struct _PerlIO base;
- Off_t posn; /* Offset of buf into the file */
- STDCHAR * buf; /* Start of buffer */
- STDCHAR * end; /* End of valid part of buffer */
- STDCHAR * ptr; /* Current position in buffer */
- Size_t bufsiz; /* Size of buffer */
- IV oneword; /* Emergency buffer */
-} PerlIOBuf;
-
-
PerlIO *
PerlIOBuf_fdopen(PerlIO_funcs *self, int fd, const char *mode)
{
return f;
}
-
PerlIO *
PerlIOBuf_open(PerlIO_funcs *self, const char *path, const char *mode)
{
}
}
-void
-PerlIOBuf_set_cnt(PerlIO *f, int cnt)
-{
- PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
- dTHX;
- if (!b->buf)
- PerlIO_get_base(f);
- b->ptr = b->end - cnt;
- assert(b->ptr >= b->buf);
-}
-
STDCHAR *
PerlIOBuf_get_ptr(PerlIO *f)
{
#endif /* HAS_MMAP */
-
-
void
PerlIO_init(void)
{
{
PerlIOBase(f)->flags |= PERLIO_F_TEMP;
}
- unlink(SvPVX(sv));
+ PerlLIO_unlink(SvPVX(sv));
SvREFCNT_dec(sv);
}
return f;
PerlIO_getpos(PerlIO *f, Fpos_t *pos)
{
*pos = PerlIO_tell(f);
- return *pos != -1;
+ return *pos == -1 ? -1 : 0;
}
#else
#ifndef PERLIO_IS_STDIO