/*
- * perlio.c Copyright (c) 1996-2001, Nick Ing-Simmons You may distribute
+ * perlio.c Copyright (c) 1996-2002, Nick Ing-Simmons You may distribute
* under the terms of either the GNU General Public License or the
* Artistic License, as specified in the README file.
*/
/*
+ * Hour after hour for nearly three weary days he had jogged up and down,
+ * over passes, and through long dales, and across many streams.
+ */
+
+/*
* If we have ActivePerl-like PERL_IMPLICIT_SYS then we need a dTHX to get
* at the dispatch tables, even when we do not need it for other reasons.
* Invent a dSYS macro to abstract this out
# endif
#else
# if defined(USEMYBINMODE)
+ dTHX;
if (my_binmode(fp, iotype, mode) != FALSE)
return 1;
else
if (fd >= 0) {
char mode[8];
int omode = fcntl(fd, F_GETFL);
+#ifdef DJGPP
+ omode = djgpp_get_stream_mode(f);
+#endif
PerlIO_intmode2str(omode,mode,NULL);
/* the r+ is a hack */
return PerlIO_fdopen(fd, mode);
PerlIO *
PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
PerlIO_funcs *tab = PerlIOBase(f)->tab;
PerlIO *new;
PerlIO_debug("fdupopen f=%p param=%p\n",(void*)f,(void*)param);
* seen as an invalid separator character.
*/
char q = ((*s == '\'') ? '"' : '\'');
- Perl_warn(aTHX_
+ if (ckWARN(WARN_LAYER))
+ Perl_warner(aTHX_ packWARN(WARN_LAYER),
"perlio: invalid separator character %c%c%c in layer specification list %s",
q, *s, q, s);
return -1;
*/
case '\0':
e--;
- Perl_warn(aTHX_
+ if (ckWARN(WARN_LAYER))
+ Perl_warner(aTHX_ packWARN(WARN_LAYER),
"perlio: argument list not closed for layer \"%.*s\"",
(int) (e - s), s);
return -1;
}
}
if (e > s) {
+ bool warn_layer = ckWARN(WARN_LAYER);
PerlIO_funcs *layer =
PerlIO_find_layer(aTHX_ s, llen, 1);
if (layer) {
&PL_sv_undef);
}
else {
- Perl_warn(aTHX_ "perlio: unknown layer \"%.*s\"",
+ if (warn_layer)
+ Perl_warner(aTHX_ packWARN(WARN_LAYER), "perlio: unknown layer \"%.*s\"",
(int) llen, s);
return -1;
}
/*
* Pop back to bottom layer
*/
- if (f && *f) {
+ if (PerlIOValid(f)) {
PerlIO_flush(f);
while (!(PerlIOBase(f)->tab->kind & PERLIO_K_RAW)) {
if (*PerlIONext(f)) {
PerlIO_debug("PerlIO_binmode f=%p %s %c %x %s\n",
(void*)f, PerlIOBase(f)->tab->name, iotype, mode,
(names) ? names : "(Null)");
- /* Can't flush if switching encodings. */
- if (!(names && memEQ(names, ":encoding(", 10))) {
- PerlIO_flush(f);
+ if (names) {
+ /* Do not flush etc. if (e.g.) switching encodings.
+ if a pushed layer knows it needs to flush lower layers
+ (for example :unix which is never going to call them)
+ it can do the flush when it is pushed.
+ */
+ return PerlIO_apply_layers(aTHX_ f, NULL, names) == 0 ? TRUE : FALSE;
+ }
+ else {
+ /* FIXME?: Looking down the layer stack seems wrong,
+ but is a way of reaching past (say) an encoding layer
+ to flip CRLF-ness of the layer(s) below
+ */
#ifdef PERLIO_USING_CRLF
- if (!names && (mode & O_BINARY)) {
- PerlIO *top = f;
- while (*top) {
- if (PerlIOBase(top)->tab == &PerlIO_crlf) {
- PerlIOBase(top)->flags &= ~PERLIO_F_CRLF;
- break;
+ /* Legacy binmode only has meaning if O_TEXT has a value distinct from
+ O_BINARY so we can look for it in mode.
+ */
+ if (!(mode & O_BINARY)) {
+ /* Text mode */
+ while (*f) {
+ /* Perhaps we should turn on bottom-most aware layer
+ e.g. Ilya's idea that UNIX TTY could serve
+ */
+ if (PerlIOBase(f)->tab->kind & PERLIO_K_CANCRLF) {
+ if (!(PerlIOBase(f)->flags & PERLIO_F_CRLF)) {
+ /* Not in text mode - flush any pending stuff and flip it */
+ PerlIO_flush(f);
+ PerlIOBase(f)->flags |= PERLIO_F_CRLF;
+ }
+ /* Only need to turn it on in one layer so we are done */
+ return TRUE;
}
- top = PerlIONext(top);
- PerlIO_flush(top);
+ f = PerlIONext(f);
}
+ /* Not finding a CRLF aware layer presumably means we are binary
+ which is not what was requested - so we failed
+ We _could_ push :crlf layer but so could caller
+ */
+ return FALSE;
}
#endif
+ /* Either asked for BINMODE or that is normal on this platform
+ see if any CRLF aware layers are present and turn off the flag
+ and possibly remove layer.
+ */
+ while (*f) {
+ if (PerlIOBase(f)->tab->kind & PERLIO_K_CANCRLF) {
+ if ((PerlIOBase(f)->flags & PERLIO_F_CRLF)) {
+ /* In text mode - flush any pending stuff and flip it */
+ PerlIO_flush(f);
+ PerlIOBase(f)->flags &= ~PERLIO_F_CRLF;
+#ifndef PERLIO_USING_CRLF
+ /* CRLF is unusual case - if this is just the :crlf layer pop it */
+ if (PerlIOBase(f)->tab == &PerlIO_crlf) {
+ PerlIO_pop(aTHX_ f);
+ }
+#endif
+ /* Normal case is only one layer doing this, so exit on first
+ abnormal case can always do multiple binmode calls
+ */
+ return TRUE;
+ }
+ }
+ f = PerlIONext(f);
+ }
+ return TRUE;
}
- return PerlIO_apply_layers(aTHX_ f, NULL, names) == 0 ? TRUE : FALSE;
}
-#undef PerlIO__close
int
-PerlIO__close(PerlIO *f)
+PerlIO__close(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Close) (aTHX_ f);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_close
int
-PerlIO_close(PerlIO *f)
+Perl_PerlIO_close(pTHX_ PerlIO *f)
{
- dTHX;
int code = -1;
- if (f && *f) {
+ if (PerlIOValid(f)) {
code = (*PerlIOBase(f)->tab->Close) (aTHX_ f);
while (*f) {
PerlIO_pop(aTHX_ f);
return code;
}
-#undef PerlIO_fileno
int
-PerlIO_fileno(PerlIO *f)
+Perl_PerlIO_fileno(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Fileno) (aTHX_ f);
else {
SETERRNO(EBADF, SS$_IVCHAN);
PerlIO_list_t *layera = NULL;
IV n;
PerlIO_funcs *tab = NULL;
- if (f && *f) {
+ if (PerlIOValid(f)) {
/*
* This is "reopen" - it is not tested as perl does not use it
* yet
PerlIOl *l = *f;
layera = PerlIO_list_alloc(aTHX);
while (l) {
- SV *arg =
- (l->tab->Getarg) ? (*l->tab->
- Getarg) (aTHX_ &l, NULL, 0) : &PL_sv_undef;
+ SV *arg = (l->tab->Getarg)
+ ? (*l->tab->Getarg) (aTHX_ &l, NULL, 0)
+ : &PL_sv_undef;
PerlIO_list_push(aTHX_ layera, l->tab, arg);
l = *PerlIONext(&l);
}
}
-#undef PerlIO_fdopen
-PerlIO *
-PerlIO_fdopen(int fd, const char *mode)
-{
- dTHX;
- return PerlIO_openn(aTHX_ Nullch, mode, fd, 0, 0, NULL, 0, NULL);
-}
-
-#undef PerlIO_open
-PerlIO *
-PerlIO_open(const char *path, const char *mode)
-{
- dTHX;
- SV *name = sv_2mortal(newSVpvn(path, strlen(path)));
- return PerlIO_openn(aTHX_ Nullch, mode, -1, 0, 0, NULL, 1, &name);
-}
-
-#undef PerlIO_reopen
-PerlIO *
-PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
-{
- dTHX;
- SV *name = sv_2mortal(newSVpvn(path, strlen(path)));
- return PerlIO_openn(aTHX_ Nullch, mode, -1, 0, 0, f, 1, &name);
-}
-
-#undef PerlIO_read
SSize_t
-PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
+Perl_PerlIO_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Read) (aTHX_ f, vbuf, count);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_unread
SSize_t
-PerlIO_unread(PerlIO *f, const void *vbuf, Size_t count)
+Perl_PerlIO_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Unread) (aTHX_ f, vbuf, count);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_write
SSize_t
-PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
+Perl_PerlIO_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Write) (aTHX_ f, vbuf, count);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_seek
int
-PerlIO_seek(PerlIO *f, Off_t offset, int whence)
+Perl_PerlIO_seek(pTHX_ PerlIO *f, Off_t offset, int whence)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Seek) (aTHX_ f, offset, whence);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_tell
Off_t
-PerlIO_tell(PerlIO *f)
+Perl_PerlIO_tell(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Tell) (aTHX_ f);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_flush
int
-PerlIO_flush(PerlIO *f)
+Perl_PerlIO_flush(pTHX_ PerlIO *f)
{
- dTHX;
if (f) {
if (*f) {
PerlIO_funcs *tab = PerlIOBase(f)->tab;
}
}
-#undef PerlIO_fill
int
-PerlIO_fill(PerlIO *f)
+Perl_PerlIO_fill(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Fill) (aTHX_ f);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_isutf8
int
PerlIO_isutf8(PerlIO *f)
{
- if (f && *f)
+ if (PerlIOValid(f))
return (PerlIOBase(f)->flags & PERLIO_F_UTF8) != 0;
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_eof
int
-PerlIO_eof(PerlIO *f)
+Perl_PerlIO_eof(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Eof) (aTHX_ f);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_error
int
-PerlIO_error(PerlIO *f)
+Perl_PerlIO_error(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Error) (aTHX_ f);
else {
SETERRNO(EBADF, SS$_IVCHAN);
}
}
-#undef PerlIO_clearerr
void
-PerlIO_clearerr(PerlIO *f)
+Perl_PerlIO_clearerr(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
(*PerlIOBase(f)->tab->Clearerr) (aTHX_ f);
else
SETERRNO(EBADF, SS$_IVCHAN);
}
-#undef PerlIO_setlinebuf
void
-PerlIO_setlinebuf(PerlIO *f)
+Perl_PerlIO_setlinebuf(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
(*PerlIOBase(f)->tab->Setlinebuf) (aTHX_ f);
else
SETERRNO(EBADF, SS$_IVCHAN);
}
-#undef PerlIO_has_base
int
PerlIO_has_base(PerlIO *f)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
return (PerlIOBase(f)->tab->Get_base != NULL);
}
return 0;
}
-#undef PerlIO_fast_gets
int
PerlIO_fast_gets(PerlIO *f)
{
- if (f && *f && (PerlIOBase(f)->flags & PERLIO_F_FASTGETS)) {
+ if (PerlIOValid(f) && (PerlIOBase(f)->flags & PERLIO_F_FASTGETS)) {
PerlIO_funcs *tab = PerlIOBase(f)->tab;
return (tab->Set_ptrcnt != NULL);
}
return 0;
}
-#undef PerlIO_has_cntptr
int
PerlIO_has_cntptr(PerlIO *f)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
PerlIO_funcs *tab = PerlIOBase(f)->tab;
return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
}
return 0;
}
-#undef PerlIO_canset_cnt
int
PerlIO_canset_cnt(PerlIO *f)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
PerlIOl *l = PerlIOBase(f);
return (l->tab->Set_ptrcnt != NULL);
}
return 0;
}
-#undef PerlIO_get_base
STDCHAR *
-PerlIO_get_base(PerlIO *f)
+Perl_PerlIO_get_base(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Get_base) (aTHX_ f);
return NULL;
}
-#undef PerlIO_get_bufsiz
int
-PerlIO_get_bufsiz(PerlIO *f)
+Perl_PerlIO_get_bufsiz(pTHX_ PerlIO *f)
{
- dTHX;
- if (f && *f)
+ if (PerlIOValid(f))
return (*PerlIOBase(f)->tab->Get_bufsiz) (aTHX_ f);
return 0;
}
-#undef PerlIO_get_ptr
STDCHAR *
-PerlIO_get_ptr(PerlIO *f)
+Perl_PerlIO_get_ptr(pTHX_ PerlIO *f)
{
- dTHX;
- PerlIO_funcs *tab = PerlIOBase(f)->tab;
- if (tab->Get_ptr == NULL)
- return NULL;
- return (*tab->Get_ptr) (aTHX_ f);
+ if (PerlIOValid(f)) {
+ PerlIO_funcs *tab = PerlIOBase(f)->tab;
+ if (tab->Get_ptr == NULL)
+ return NULL;
+ return (*tab->Get_ptr) (aTHX_ f);
+ }
+ return NULL;
}
-#undef PerlIO_get_cnt
int
-PerlIO_get_cnt(PerlIO *f)
+Perl_PerlIO_get_cnt(pTHX_ PerlIO *f)
{
- dTHX;
- PerlIO_funcs *tab = PerlIOBase(f)->tab;
- if (tab->Get_cnt == NULL)
- return 0;
- return (*tab->Get_cnt) (aTHX_ f);
+ if (PerlIOValid(f)) {
+ PerlIO_funcs *tab = PerlIOBase(f)->tab;
+ if (tab->Get_cnt == NULL)
+ return 0;
+ return (*tab->Get_cnt) (aTHX_ f);
+ }
+ return 0;
}
-#undef PerlIO_set_cnt
void
-PerlIO_set_cnt(PerlIO *f, int cnt)
+Perl_PerlIO_set_cnt(pTHX_ PerlIO *f, int cnt)
{
- dTHX;
- (*PerlIOBase(f)->tab->Set_ptrcnt) (aTHX_ f, NULL, cnt);
+ if (PerlIOValid(f)) {
+ (*PerlIOBase(f)->tab->Set_ptrcnt) (aTHX_ f, NULL, cnt);
+ }
}
-#undef PerlIO_set_ptrcnt
void
-PerlIO_set_ptrcnt(PerlIO *f, STDCHAR * ptr, int cnt)
+Perl_PerlIO_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, int cnt)
{
- dTHX;
- PerlIO_funcs *tab = PerlIOBase(f)->tab;
- if (tab->Set_ptrcnt == NULL) {
- Perl_croak(aTHX_ "PerlIO buffer snooping abuse");
+ if (PerlIOValid(f)) {
+ PerlIO_funcs *tab = PerlIOBase(f)->tab;
+ if (tab->Set_ptrcnt == NULL) {
+ Perl_croak(aTHX_ "PerlIO buffer snooping abuse");
+ }
+ (*PerlIOBase(f)->tab->Set_ptrcnt) (aTHX_ f, ptr, cnt);
}
- (*PerlIOBase(f)->tab->Set_ptrcnt) (aTHX_ f, ptr, cnt);
}
/*--------------------------------------------------------------------------------------*/
IV
PerlIOUtf8_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg)
{
- if (PerlIONext(f)) {
+ if (*PerlIONext(f)) {
PerlIO_funcs *tab = PerlIOBase(f)->tab;
PerlIO_pop(aTHX_ f);
if (tab->kind & PERLIO_K_UTF8)
IV
PerlIOBase_fileno(pTHX_ PerlIO *f)
{
- return PerlIO_fileno(PerlIONext(f));
+ return PerlIOValid(f) ? PerlIO_fileno(PerlIONext(f)) : -1;
}
char *
PerlIO *n = PerlIONext(f);
if (PerlIO_flush(f) != 0)
code = -1;
- if (n && *n && (*PerlIOBase(n)->tab->Close)(aTHX_ n) != 0)
+ if (PerlIOValid(n) && (*PerlIOBase(n)->tab->Close)(aTHX_ n) != 0)
code = -1;
PerlIOBase(f)->flags &=
~(PERLIO_F_CANREAD | PERLIO_F_CANWRITE | PERLIO_F_OPEN);
IV
PerlIOBase_eof(pTHX_ PerlIO *f)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
return (PerlIOBase(f)->flags & PERLIO_F_EOF) != 0;
}
return 1;
IV
PerlIOBase_error(pTHX_ PerlIO *f)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
return (PerlIOBase(f)->flags & PERLIO_F_ERROR) != 0;
}
return 1;
void
PerlIOBase_clearerr(pTHX_ PerlIO *f)
{
- if (f && *f) {
+ if (PerlIOValid(f)) {
PerlIO *n = PerlIONext(f);
PerlIOBase(f)->flags &= ~(PERLIO_F_ERROR | PERLIO_F_EOF);
- if (n)
+ if (PerlIOValid(n))
PerlIO_clearerr(n);
}
}
void
PerlIOBase_setlinebuf(pTHX_ PerlIO *f)
{
- if (f) {
+ if (PerlIOValid(f)) {
PerlIOBase(f)->flags |= PERLIO_F_LINEBUF;
}
}
PerlIOBase_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
{
PerlIO *nexto = PerlIONext(o);
- if (*nexto) {
+ if (PerlIOValid(nexto)) {
PerlIO_funcs *tab = PerlIOBase(nexto)->tab;
f = (*tab->Dup)(aTHX_ f, nexto, param, flags);
}
IV code = PerlIOBase_pushed(aTHX_ f, mode, arg);
PerlIOUnix *s = PerlIOSelf(f, PerlIOUnix);
if (*PerlIONext(f)) {
+ /* We never call down so any pending stuff now */
+ PerlIO_flush(PerlIONext(f));
s->fd = PerlIO_fileno(PerlIONext(f));
/*
* XXX could (or should) we retrieve the oflags from the open file
FILE *stdio =
PerlSIO_fdopen(PerlIO_fileno(PerlIONext(f)), mode =
PerlIOStdio_mode(mode, tmode));
- if (stdio)
+ if (stdio) {
s->stdio = stdio;
+ /* We never call down so any pending stuff now */
+ PerlIO_flush(PerlIONext(f));
+ }
else
return -1;
}
return PerlIOBase_pushed(aTHX_ f, mode, arg);
}
-#undef PerlIO_importFILE
PerlIO *
PerlIO_importFILE(FILE *stdio, int fl)
{
PerlSIO_set_ptr(stdio, (void*)ptr); /* LHS STDCHAR* cast non-portable */
#ifdef STDIO_PTR_LVAL_SETS_CNT
if (PerlSIO_get_cnt(stdio) != (cnt)) {
- dTHX;
assert(PerlSIO_get_cnt(stdio) == (cnt));
}
#endif
#endif /* USE_STDIO_PTR */
};
-#undef PerlIO_exportFILE
FILE *
PerlIO_exportFILE(PerlIO *f, int fl)
{
+ dTHX;
FILE *stdio;
PerlIO_flush(f);
stdio = fdopen(PerlIO_fileno(f), "r+");
if (stdio) {
- dTHX;
PerlIOStdio *s =
PerlIOSelf(PerlIO_push(aTHX_ f, &PerlIO_stdio, "r+", Nullsv),
PerlIOStdio);
return stdio;
}
-#undef PerlIO_findFILE
FILE *
PerlIO_findFILE(PerlIO *f)
{
return PerlIO_exportFILE(f, 0);
}
-#undef PerlIO_releaseFILE
void
PerlIO_releaseFILE(PerlIO *p, FILE *f)
{
IV n, const char *mode, int fd, int imode, int perm,
PerlIO *f, int narg, SV **args)
{
- if (f) {
+ if (PerlIOValid(f)) {
PerlIO *next = PerlIONext(f);
- PerlIO_funcs *tab =
- PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIOBase(next)->tab);
- next =
- (*tab->Open) (aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
+ PerlIO_funcs *tab = PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIOBase(next)->tab);
+ next = (*tab->Open) (aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
next, narg, args);
- if (!next
- || (*PerlIOBase(f)->tab->Pushed) (aTHX_ f, mode, PerlIOArg) != 0) {
+ if (!next || (*PerlIOBase(f)->tab->Pushed) (aTHX_ f, mode, PerlIOArg) != 0) {
return NULL;
}
}
else {
- PerlIO_funcs *tab =
- PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIO_default_btm());
+ PerlIO_funcs *tab = PerlIO_layer_fetch(aTHX_ layers, n - 1, PerlIO_default_btm());
int init = 0;
if (*mode == 'I') {
init = 1;
return NULL;
} else {
fd = PerlIO_fileno(f);
-#ifdef PERLIO_USING_CRLF
- /*
- * do something about failing setmode()? --jhi
- */
- PerlLIO_setmode(fd, O_BINARY);
-#endif
if (init && fd == 2) {
/*
* Initial stderr is unbuffered
*/
PerlIOBase(f)->flags |= PERLIO_F_UNBUF;
}
+#ifdef PERLIO_USING_CRLF
+# ifdef PERLIO_IS_BINMODE_FD
+ if (PERLIO_IS_BINMODE_FD(fd))
+ PerlIO_binmode(f, '<'/*not used*/, O_BINARY, Nullch);
+ else
+# endif
+ /*
+ * do something about failing setmode()? --jhi
+ */
+ PerlLIO_setmode(fd, O_BINARY);
+#endif
}
}
}
{
PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
int code = 0;
+ PerlIO *n = PerlIONext(f);
if (PerlIOBase(f)->flags & PERLIO_F_WRBUF) {
/*
* write() the buffer
*/
STDCHAR *buf = b->buf;
STDCHAR *p = buf;
- PerlIO *n = PerlIONext(f);
while (p < b->ptr) {
SSize_t count = PerlIO_write(n, p, b->ptr - p);
if (count > 0) {
/*
* We did not consume all of it
*/
- if (PerlIO_seek(PerlIONext(f), b->posn, SEEK_SET) == 0) {
- b->posn = PerlIO_tell(PerlIONext(f));
+ if (PerlIO_seek(n, b->posn, SEEK_SET) == 0) {
+ /* Reload n as some layers may pop themselves on seek */
+ b->posn = PerlIO_tell(n = PerlIONext(f));
}
}
}
b->ptr = b->end = b->buf;
PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
- /*
- * FIXME: Is this right for read case ?
- */
- if (PerlIO_flush(PerlIONext(f)) != 0)
+ /* We check for Valid because of dubious decision to make PerlIO_flush(NULL) flush all */
+ /* FIXME: Doing downstream flush may be sub-optimal see PerlIOBuf_fill() below */
+ if (PerlIOValid(n) && PerlIO_flush(n) != 0)
code = -1;
return code;
}
PerlIO *n = PerlIONext(f);
SSize_t avail;
/*
- * FIXME: doing the down-stream flush is a bad idea if it causes
- * pre-read data in stdio buffer to be discarded but this is too
- * simplistic - as it skips _our_ hosekeeping and breaks tell tests.
- * if (!(PerlIOBase(f)->flags & PERLIO_F_RDBUF)) { }
+ * FIXME: doing the down-stream flush maybe sub-optimal if it causes
+ * pre-read data in stdio buffer to be discarded.
+ * However, skipping the flush also skips _our_ hosekeeping
+ * and breaks tell tests. So we do the flush.
*/
if (PerlIO_flush(f) != 0)
return -1;
b->ptr = b->end = b->buf;
if (PerlIO_fast_gets(n)) {
/*
- * Layer below is also buffered We do _NOT_ want to call its
+ * Layer below is also buffered. We do _NOT_ want to call its
* ->Read() because that will loop till it gets what we asked for
* which may hang on a pipe etc. Instead take anything it has to
* hand, or ask it to fill _once_.
PerlIOBuf_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
{
PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
- if (f) {
+ if (PerlIOValid(f)) {
if (!b->ptr)
PerlIO_get_base(f);
return PerlIOBase_read(aTHX_ f, vbuf, count);
PerlIO_get_base(f);
b->ptr = ptr;
if (PerlIO_get_cnt(f) != cnt || b->ptr < b->buf) {
- dTHX;
assert(PerlIO_get_cnt(f) == cnt);
assert(b->ptr >= b->buf);
}
PerlIO_get_base(f);
if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
- if ((PerlIOBase(f)->flags & PERLIO_F_CRLF) && !c->nl) {
- STDCHAR *nl = b->ptr;
+ if ((PerlIOBase(f)->flags & PERLIO_F_CRLF) && (!c->nl || *c->nl == 0xd)) {
+ STDCHAR *nl = (c->nl) ? c->nl : b->ptr;
scan:
while (nl < b->end && *nl != 0xd)
nl++;
/*
* Blast - found CR as last char in buffer
*/
-
+
if (b->ptr < nl) {
/*
* They may not care, defer work as long as
{
PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
- IV flags = PerlIOBase(f)->flags;
if (!b->buf)
PerlIO_get_base(f);
if (!ptr) {
ptr -= cnt;
}
else {
+#if 0
/*
* Test code - delete when it works ...
*/
+ IV flags = PerlIOBase(f)->flags;
STDCHAR *chk = (c->nl) ? (c->nl+1) : b->end;
if (ptr+cnt == c->nl && c->nl+1 == b->end && *c->nl == 0xd) {
/* Defered CR at end of buffer case - we lied about count */
chk--;
- }
+ }
chk -= cnt;
if (ptr != chk ) {
- Perl_warn(aTHX_ "ptr wrong %p != %p fl=%08" UVxf
+ Perl_croak(aTHX_ "ptr wrong %p != %p fl=%08" UVxf
" nl=%p e=%p for %d", ptr, chk, flags, c->nl,
b->end, cnt);
}
+#endif
}
if (c->nl) {
if (ptr > c->nl) {
}
IV
-PerlIOMmap_unmap(PerlIO *f)
+PerlIOMmap_unmap(pTHX_ PerlIO *f)
{
PerlIOMmap *m = PerlIOSelf(f, PerlIOMmap);
PerlIOBuf *b = &m->base;
* No, or wrong sort of, buffer
*/
if (m->len) {
- if (PerlIOMmap_unmap(f) != 0)
+ if (PerlIOMmap_unmap(aTHX_ f) != 0)
return 0;
}
/*
/*
* Unmap the buffer
*/
- if (PerlIOMmap_unmap(f) != 0)
+ if (PerlIOMmap_unmap(aTHX_ f) != 0)
code = -1;
}
else {
#endif /* HAS_MMAP */
-#undef PerlIO_stdin
PerlIO *
-PerlIO_stdin(void)
+Perl_PerlIO_stdin(pTHX)
{
- dTHX;
if (!PL_perlio) {
PerlIO_stdstreams(aTHX);
}
return &PL_perlio[1];
}
-#undef PerlIO_stdout
PerlIO *
-PerlIO_stdout(void)
+Perl_PerlIO_stdout(pTHX)
{
- dTHX;
if (!PL_perlio) {
PerlIO_stdstreams(aTHX);
}
return &PL_perlio[2];
}
-#undef PerlIO_stderr
PerlIO *
-PerlIO_stderr(void)
+Perl_PerlIO_stderr(pTHX)
{
- dTHX;
if (!PL_perlio) {
PerlIO_stdstreams(aTHX);
}
/*--------------------------------------------------------------------------------------*/
-#undef PerlIO_getname
char *
PerlIO_getname(PerlIO *f, char *buf)
{
* terms of above
*/
+#undef PerlIO_fdopen
+PerlIO *
+PerlIO_fdopen(int fd, const char *mode)
+{
+ dTHX;
+ return PerlIO_openn(aTHX_ Nullch, mode, fd, 0, 0, NULL, 0, NULL);
+}
+
+#undef PerlIO_open
+PerlIO *
+PerlIO_open(const char *path, const char *mode)
+{
+ dTHX;
+ SV *name = sv_2mortal(newSVpvn(path, strlen(path)));
+ return PerlIO_openn(aTHX_ Nullch, mode, -1, 0, 0, NULL, 1, &name);
+}
+
+#undef Perlio_reopen
+PerlIO *
+PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
+{
+ dTHX;
+ SV *name = sv_2mortal(newSVpvn(path, strlen(path)));
+ return PerlIO_openn(aTHX_ Nullch, mode, -1, 0, 0, f, 1, &name);
+}
+
#undef PerlIO_getc
int
PerlIO_getc(PerlIO *f)
{
+ dTHX;
STDCHAR buf[1];
SSize_t count = PerlIO_read(f, buf, 1);
if (count == 1) {
int
PerlIO_ungetc(PerlIO *f, int ch)
{
+ dTHX;
if (ch != EOF) {
STDCHAR buf = ch;
if (PerlIO_unread(f, &buf, 1) == 1)
int
PerlIO_putc(PerlIO *f, int ch)
{
+ dTHX;
STDCHAR buf = ch;
return PerlIO_write(f, &buf, 1);
}
int
PerlIO_puts(PerlIO *f, const char *s)
{
+ dTHX;
STRLEN len = strlen(s);
return PerlIO_write(f, s, len);
}
void
PerlIO_rewind(PerlIO *f)
{
+ dTHX;
PerlIO_seek(f, (Off_t) 0, SEEK_SET);
PerlIO_clearerr(f);
}
int
PerlIO_stdoutf(const char *fmt, ...)
{
+ dTHX;
va_list ap;
int result;
va_start(ap, fmt);