if (!f)
{
return NULL;
- }
+ }
*last = f;
return f+1;
}
dTHX;
SV **svp;
SV *sv;
- if (len <= 0)
+ if ((SSize_t) len <= 0)
len = strlen(name);
svp = hv_fetch(PerlIO_layer_hv,name,len,0);
if (svp && (sv = *svp) && SvROK(sv))
}
PerlIO *
-PerlIO_push(PerlIO *f,PerlIO_funcs *tab,const char *mode)
+PerlIO_push(PerlIO *f,PerlIO_funcs *tab,const char *mode,const char *arg,STRLEN len)
{
dTHX;
PerlIOl *l = NULL;
l->tab = tab;
*f = l;
PerlIO_debug("PerlIO_push f=%p %s %s\n",f,tab->name,(mode) ? mode : "(Null)");
- if ((*l->tab->Pushed)(f,mode) != 0)
+ if ((*l->tab->Pushed)(f,mode,arg,len) != 0)
{
PerlIO_pop(f);
return NULL;
if (*s)
{
const char *e = s;
+ const char *as = Nullch;
+ const char *ae = Nullch;
+ int count = 0;
while (*e && *e != ':' && !isSPACE(*e))
- e++;
+ {
+ if (*e == '(')
+ {
+ if (!as)
+ as = e;
+ count++;
+ }
+ else if (*e == ')')
+ {
+ if (as && --count == 0)
+ ae = e;
+ }
+ e++;
+ }
if (e > s)
{
if ((e - s) == 3 && strncmp(s,"raw",3) == 0)
}
}
}
+ else if ((e - s) == 4 && strncmp(s,"utf8",4) == 0)
+ {
+ PerlIOBase(f)->flags |= PERLIO_F_UTF8;
+ }
+ else if ((e - s) == 5 && strncmp(s,"bytes",5) == 0)
+ {
+ PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
+ }
else
{
- SV *layer = PerlIO_find_layer(s,e-s);
+ STRLEN len = ((as) ? as : e)-s;
+ SV *layer = PerlIO_find_layer(s,len);
if (layer)
{
PerlIO_funcs *tab = INT2PTR(PerlIO_funcs *, SvIV(SvRV(layer)));
if (tab)
{
- PerlIO *new = PerlIO_push(f,tab,mode);
- if (!new)
+ len = (as) ? (ae-(as++)-1) : 0;
+ if (!PerlIO_push(f,tab,mode,as,len))
return -1;
}
}
else
- Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",(int)(e-s),s);
+ Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",(int)len,s);
}
}
s = e;
{
PerlIO_debug("PerlIO_binmode f=%p %s %c %x %s\n",
f,PerlIOBase(f)->tab->name,iotype,mode, (names) ? names : "(Null)");
- if (!names || (O_TEXT != O_BINARY && mode & O_BINARY))
+ if (!names && (O_TEXT != O_BINARY && (mode & O_BINARY)))
{
PerlIO *top = f;
PerlIOl *l;
Off_t posn = PerlIO_tell(f);
PerlIO_seek(new,posn,SEEK_SET);
}
- return new;
+ return new;
}
#undef PerlIO_close
PerlIO_flush(f);
if ((*PerlIOBase(f)->tab->Reopen)(path,mode,f) == 0)
{
- if ((*PerlIOBase(f)->tab->Pushed)(f,mode) == 0)
+ if ((*PerlIOBase(f)->tab->Pushed)(f,mode,Nullch,0) == 0)
return f;
}
return NULL;
{
*s++ = '+';
}
- }
+ }
else if (flags & PERLIO_F_CANREAD)
{
*s++ = 'r';
}
IV
-PerlIOBase_pushed(PerlIO *f, const char *mode)
+PerlIOBase_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
{
PerlIOl *l = PerlIOBase(f);
const char *omode = mode;
return 0;
}
#else
- PerlIO_push(f,&PerlIO_pending,"r");
+ PerlIO_push(f,&PerlIO_pending,"r",Nullch,0);
return PerlIOBuf_unread(f,vbuf,count);
#endif
}
int oflags = PerlIOUnix_oflags(mode);
if (oflags != -1)
{
- PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode),PerlIOUnix);
+ PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode,Nullch,0),PerlIOUnix);
s->fd = fd;
s->oflags = oflags;
PerlIOBase(f)->flags |= PERLIO_F_OPEN;
int fd = PerlLIO_open3(path,oflags,0666);
if (fd >= 0)
{
- PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode),PerlIOUnix);
+ PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode,Nullch,0),PerlIOUnix);
s->fd = fd;
s->oflags = oflags;
PerlIOBase(f)->flags |= PERLIO_F_OPEN;
PerlIOUnix_tell(PerlIO *f)
{
dTHX;
+ Off_t posn = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
return PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR);
}
return PerlSIO_fileno(PerlIOSelf(f,PerlIOStdio)->stdio);
}
-const char *
+char *
PerlIOStdio_mode(const char *mode,char *tmode)
{
- const char *ret = mode;
+ char *ret = tmode;
+ while (*mode)
+ {
+ *tmode++ = *mode++;
+ }
if (O_BINARY != O_TEXT)
{
- ret = (const char *) tmode;
- while (*mode)
- {
- *tmode++ = *mode++;
- }
*tmode++ = 'b';
- *tmode = '\0';
}
+ *tmode = '\0';
return ret;
}
}
if (stdio)
{
- PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode),PerlIOStdio);
+ PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),self,mode,Nullch,0),PerlIOStdio);
s->stdio = stdio;
}
}
PerlIO *f = NULL;
if (stdio)
{
- PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),&PerlIO_stdio,"r+"),PerlIOStdio);
+ PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),&PerlIO_stdio,"r+",Nullch,0),PerlIOStdio);
s->stdio = stdio;
}
return f;
{
char tmode[8];
PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX), self,
- (mode = PerlIOStdio_mode(mode,tmode))),
+ (mode = PerlIOStdio_mode(mode,tmode)),Nullch,0),
PerlIOStdio);
s->stdio = stdio;
}
PerlIOStdio_close(PerlIO *f)
{
dTHX;
+#ifdef HAS_SOCKET
int optval, optlen = sizeof(int);
+#endif
FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
return(
+#ifdef HAS_SOCKET
(getsockopt(PerlIO_fileno(f), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0) ?
PerlSIO_fclose(stdio) :
- close(PerlIO_fileno(f)));
+ close(PerlIO_fileno(f))
+#else
+ PerlSIO_fclose(stdio)
+#endif
+ );
+
}
IV
/* perlio buffer layer */
IV
-PerlIOBuf_pushed(PerlIO *f, const char *mode)
+PerlIOBuf_pushed(PerlIO *f, const char *mode, const char *arg, STRLEN len)
{
PerlIOBuf *b = PerlIOSelf(f,PerlIOBuf);
b->posn = PerlIO_tell(PerlIONext(f));
- return PerlIOBase_pushed(f,mode);
+ return PerlIOBase_pushed(f,mode,arg,len);
}
PerlIO *
f = (*tab->Fdopen)(tab,fd,mode);
if (f)
{
- PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,mode),PerlIOBuf);
+ PerlIOBuf *b = PerlIOSelf(PerlIO_push(f,self,mode,Nullch,0),PerlIOBuf);
if (init && fd == 2)
{
/* Initial stderr is unbuffered */
PerlIO *f = (*tab->Open)(tab,path,mode);
if (f)
{
- PerlIO_push(f,self,mode);
+ PerlIO_push(f,self,mode,Nullch,0);
}
return f;
}
PerlIO *next = PerlIONext(f);
int code = (*PerlIOBase(next)->tab->Reopen)(path,mode,next);
if (code = 0)
- code = (*PerlIOBase(f)->tab->Pushed)(f,mode);
+ code = (*PerlIOBase(f)->tab->Pushed)(f,mode,Nullch,0);
return code;
}
if (PerlIOBase(f)->flags & PERLIO_F_WRBUF)
{
/* write() the buffer */
- STDCHAR *p = b->buf;
+ STDCHAR *buf = b->buf;
+ STDCHAR *p = buf;
int count;
PerlIO *n = PerlIONext(f);
while (p < b->ptr)
break;
}
}
- b->posn += (p - b->buf);
+ b->posn += (p - buf);
}
else if (PerlIOBase(f)->flags & PERLIO_F_RDBUF)
{
+ STDCHAR *buf = PerlIO_get_base(f);
/* Note position change */
- b->posn += (b->ptr - b->buf);
+ b->posn += (b->ptr - buf);
if (b->ptr < b->end)
{
/* We did not consume all of it */
if (PerlIO_flush(f) != 0)
return -1;
+ if (!b->buf)
+ PerlIO_get_base(f); /* allocate via vtable */
+
b->ptr = b->end = b->buf;
if (PerlIO_fast_gets(n))
{
}
IV
-PerlIOPending_pushed(PerlIO *f,const char *mode)
+PerlIOPending_pushed(PerlIO *f,const char *mode,const char *arg,STRLEN len)
{
- IV code = PerlIOBuf_pushed(f,mode);
+ IV code = PerlIOBuf_pushed(f,mode,arg,len);
PerlIOl *l = PerlIOBase(f);
/* Our PerlIO_fast_gets must match what we are pushed on,
or sv_gets() etc. get muddled when it changes mid-string
} PerlIOCrlf;
IV
-PerlIOCrlf_pushed(PerlIO *f, const char *mode)
+PerlIOCrlf_pushed(PerlIO *f, const char *mode,const char *arg,STRLEN len)
{
IV code;
PerlIOBase(f)->flags |= PERLIO_F_CRLF;
- code = PerlIOBuf_pushed(f,mode);
+ code = PerlIOBuf_pushed(f,mode,arg,len);
#if 0
PerlIO_debug("PerlIOCrlf_pushed f=%p %s %s fl=%08"UVxf"\n",
f,PerlIOBase(f)->tab->name,(mode) ? mode : "(Null)",
}
posn = (b->posn / page_size) * page_size;
len = st.st_size - posn;
- m->mptr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, posn);
+ m->mptr = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, posn);
if (m->mptr && m->mptr != (Mmap_t) -1)
{
-#if defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
+#if 0 && defined(HAS_MADVISE) && defined(MADV_SEQUENTIAL)
madvise(m->mptr, len, MADV_SEQUENTIAL);
#endif
+#if 0 && defined(HAS_MADVISE) && defined(MADV_WILLNEED)
+ madvise(m->mptr, len, MADV_WILLNEED);
+#endif
PerlIOBase(f)->flags = (flags & ~PERLIO_F_EOF) | PERLIO_F_RDBUF;
b->end = ((STDCHAR *)m->mptr) + len;
b->buf = ((STDCHAR *)m->mptr) + (b->posn - posn);
{
if (!_perlio)
{
+#ifndef WIN32
atexit(&PerlIO_cleanup);
+#endif
}
}
FILE *stdio = PerlSIO_tmpfile();
if (stdio)
{
- PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),&PerlIO_stdio,"w+"),PerlIOStdio);
+ PerlIOStdio *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(aTHX),&PerlIO_stdio,"w+",Nullch,0),PerlIOStdio);
s->stdio = stdio;
}
return f;
#ifndef HAS_FSETPOS
#undef PerlIO_setpos
int
-PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
+PerlIO_setpos(PerlIO *f, SV *pos)
{
- return PerlIO_seek(f,*pos,0);
+ dTHX;
+ if (SvOK(pos))
+ {
+ STRLEN len;
+ Off_t *posn = (Off_t *) SvPV(pos,len);
+ if (f && len == sizeof(Off_t))
+ return PerlIO_seek(f,*posn,SEEK_SET);
+ }
+ errno = EINVAL;
+ return -1;
}
#else
-#ifndef PERLIO_IS_STDIO
#undef PerlIO_setpos
int
-PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
+PerlIO_setpos(PerlIO *f, SV *pos)
{
+ dTHX;
+ if (SvOK(pos))
+ {
+ STRLEN len;
+ Fpos_t *fpos = (Fpos_t *) SvPV(pos,len);
+ if (f && len == sizeof(Fpos_t))
+ {
#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
- return fsetpos64(f, pos);
+ return fsetpos64(f, fpos);
#else
- return fsetpos(f, pos);
+ return fsetpos(f, fpos);
#endif
+ }
+ }
+ errno = EINVAL;
+ return -1;
}
#endif
-#endif
#ifndef HAS_FGETPOS
#undef PerlIO_getpos
int
-PerlIO_getpos(PerlIO *f, Fpos_t *pos)
+PerlIO_getpos(PerlIO *f, SV *pos)
{
- *pos = PerlIO_tell(f);
- return *pos == -1 ? -1 : 0;
+ dTHX;
+ Off_t posn = PerlIO_tell(f);
+ sv_setpvn(pos,(char *)&posn,sizeof(posn));
+ return (posn == (Off_t)-1) ? -1 : 0;
}
#else
-#ifndef PERLIO_IS_STDIO
#undef PerlIO_getpos
int
-PerlIO_getpos(PerlIO *f, Fpos_t *pos)
+PerlIO_getpos(PerlIO *f, SV *pos)
{
+ dTHX;
+ Fpos_t fpos;
+ int code;
#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
- return fgetpos64(f, pos);
+ code = fgetpos64(f, &fpos);
#else
- return fgetpos(f, pos);
+ code = fgetpos(f, &fpos);
#endif
+ sv_setpvn(pos,(char *)&fpos,sizeof(fpos));
+ return code;
}
#endif
-#endif
#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)