}
#ifndef O_ACCMODE
-#define O_ACCMODE 3 /* Assume traditional implementation */
+#define O_ACCMODE 3 /* Assume traditional implementation */
#endif
int
PerlIO *
PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
{
-#ifndef PERL_MICRO
+#ifdef PERL_MICRO
+ return NULL;
+#else
+#ifdef PERL_IMPLICIT_SYS
+ return PerlSIO_fdupopen(f);
+#else
+#ifdef WIN32
+ return win32_fdupopen(f);
+#else
if (f) {
int fd = PerlLIO_dup(PerlIO_fileno(f));
if (fd >= 0) {
}
#endif
return NULL;
+#endif
+#endif
}
return tmpfile();
}
-#else /* PERLIO_IS_STDIO */
+#else /* PERLIO_IS_STDIO */
#ifdef USE_SFIO
}
-#else /* USE_SFIO */
+#else /* USE_SFIO */
/*======================================================================================*/
/*
* Implement all the PerlIO interface ourselves.
if (!s)
s = "(none)";
sprintf(buffer, "%s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));
- len = strlen(buffer);
+ len = strlen(buffer);
vsprintf(buffer+len, fmt, ap);
PerlLIO_write(dbg, buffer, strlen(buffer));
#else
PerlIO_funcs *tab = PerlIOBase(f)->tab;
PerlIO *new;
PerlIO_debug("fdupopen f=%p param=%p\n",(void*)f,(void*)param);
- new = (*tab->Dup)(aTHX_ PerlIO_allocate(aTHX),f,param, flags);
+ new = (*tab->Dup)(aTHX_ PerlIO_allocate(aTHX),f,param, flags);
return new;
}
else {
f++;
}
}
- PerlIO_list_free(aTHX_ PL_known_layers);
- PL_known_layers = NULL;
- PerlIO_list_free(aTHX_ PL_def_layerlist);
- PL_def_layerlist = NULL;
}
void
MGVTBL perlio_vtab = {
perlio_mg_get,
perlio_mg_set,
- NULL, /* len */
+ NULL, /* len */
perlio_mg_clear,
perlio_mg_free
};
XSRETURN(count);
}
-#endif /* USE_ATTIBUTES_FOR_PERLIO */
+#endif /* USE_ATTIBUTES_FOR_PERLIO */
SV *
PerlIO_tab_sv(pTHX_ PerlIO_funcs *tab)
*/
char q = ((*s == '\'') ? '"' : '\'');
if (ckWARN(WARN_LAYER))
- Perl_warner(aTHX_ packWARN(WARN_LAYER),
+ Perl_warner(aTHX_ packWARN(WARN_LAYER),
"perlio: invalid separator character %c%c%c in layer specification list %s",
q, *s, q, s);
+ SETERRNO(EINVAL, LIB$_INVARG);
return -1;
}
do {
*/
case '\0':
e--;
- if (ckWARN(WARN_LAYER))
- Perl_warner(aTHX_ packWARN(WARN_LAYER),
+ if (ckWARN(WARN_LAYER))
+ Perl_warner(aTHX_ packWARN(WARN_LAYER),
"perlio: argument list not closed for layer \"%.*s\"",
(int) (e - s), s);
return -1;
&PL_sv_undef);
}
else {
- if (warn_layer)
+ if (warn_layer)
Perl_warner(aTHX_ packWARN(WARN_LAYER), "perlio: unknown layer \"%.*s\"",
(int) llen, s);
return -1;
tab = &PerlIO_crlf;
#else
if (PerlIO_stdio.Set_ptrcnt)
- tab = &PerlIO_stdio;
+ tab = &PerlIO_stdio;
#endif
PerlIO_debug("Pushing %s\n", tab->name);
PerlIO_list_push(aTHX_ av, PerlIO_find_layer(aTHX_ tab->name, 0, 0),
int
PerlIO_apply_layera(pTHX_ PerlIO *f, const char *mode,
- PerlIO_list_t *layers, IV n)
+ PerlIO_list_t *layers, IV n, IV max)
{
- IV max = layers->cur;
int code = 0;
while (n < max) {
PerlIO_funcs *tab = PerlIO_layer_fetch(aTHX_ layers, n, NULL);
PerlIO_list_t *layers = PerlIO_list_alloc(aTHX);
code = PerlIO_parse_layers(aTHX_ layers, names);
if (code == 0) {
- code = PerlIO_apply_layera(aTHX_ f, mode, layers, 0);
+ code = PerlIO_apply_layera(aTHX_ f, mode, layers, 0, layers->cur);
}
PerlIO_list_free(aTHX_ layers);
}
else {
av = def;
}
- PerlIO_parse_layers(aTHX_ av, layers);
- return av;
+ if (PerlIO_parse_layers(aTHX_ av, layers) == 0) {
+ return av;
+ }
+ else {
+ PerlIO_list_free(aTHX_ av);
+ return (PerlIO_list_t *) NULL;
+ }
}
else {
if (incdef)
}
else {
layera = PerlIO_resolve_layers(aTHX_ layers, mode, narg, args);
+ if (!layera) {
+ return NULL;
+ }
}
/*
* Start at "top" of layer stack
* More layers above the one that we used to open -
* apply them now
*/
- if (PerlIO_apply_layera(aTHX_ f, mode, layera, n + 1)
- != 0) {
+ if (PerlIO_apply_layera(aTHX_ f, mode, layera, n + 1, layera->cur) != 0) {
+ /* If pushing layers fails close the file */
+ PerlIO_close(f);
f = NULL;
}
}
NULL,
NULL,
NULL,
- NULL, /* flush */
- NULL, /* fill */
+ NULL, /* flush */
+ NULL, /* fill */
NULL,
NULL,
NULL,
NULL,
- NULL, /* get_base */
- NULL, /* get_bufsiz */
- NULL, /* get_ptr */
- NULL, /* get_cnt */
- NULL, /* set_ptrcnt */
+ NULL, /* get_base */
+ NULL, /* get_bufsiz */
+ NULL, /* get_ptr */
+ NULL, /* get_cnt */
+ NULL, /* set_ptrcnt */
};
PerlIO_funcs PerlIO_byte = {
NULL,
NULL,
NULL,
- NULL, /* flush */
- NULL, /* fill */
+ NULL, /* flush */
+ NULL, /* fill */
NULL,
NULL,
NULL,
NULL,
- NULL, /* get_base */
- NULL, /* get_bufsiz */
- NULL, /* get_ptr */
- NULL, /* get_cnt */
- NULL, /* set_ptrcnt */
+ NULL, /* get_base */
+ NULL, /* get_bufsiz */
+ NULL, /* get_ptr */
+ NULL, /* get_cnt */
+ NULL, /* set_ptrcnt */
};
PerlIO *
NULL,
NULL,
NULL,
- NULL, /* flush */
- NULL, /* fill */
+ NULL, /* flush */
+ NULL, /* fill */
NULL,
NULL,
NULL,
NULL,
- NULL, /* get_base */
- NULL, /* get_bufsiz */
- NULL, /* get_ptr */
- NULL, /* get_cnt */
- NULL, /* set_ptrcnt */
+ NULL, /* get_base */
+ NULL, /* get_bufsiz */
+ NULL, /* get_ptr */
+ NULL, /* get_cnt */
+ NULL, /* set_ptrcnt */
};
/*--------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------*/
{
int i;
#ifdef USE_ITHREADS
- PerlIO_debug("Cleanup %p\n",aTHX);
+ PerlIO_debug("Cleanup layers for %p\n",aTHX);
+#else
+ PerlIO_debug("Cleanup layers\n");
#endif
/* Raise STDIN..STDERR refcount so we don't close them */
for (i=0; i < 3; i++)
/* Restore STDIN..STDERR refcount */
for (i=0; i < 3; i++)
PerlIOUnix_refcnt_dec(i);
+
+ if (PL_known_layers) {
+ PerlIO_list_free(aTHX_ PL_known_layers);
+ PL_known_layers = NULL;
+ }
+ if(PL_def_layerlist) {
+ PerlIO_list_free(aTHX_ PL_def_layerlist);
+ PL_def_layerlist = NULL;
+ }
}
*/
typedef struct {
- struct _PerlIO base; /* The generic part */
- int fd; /* UNIX like file descriptor */
- int oflags; /* open/fcntl flags */
+ struct _PerlIO base; /* The generic part */
+ int fd; /* UNIX like file descriptor */
+ int oflags; /* open/fcntl flags */
} PerlIOUnix;
int
IV n, const char *mode, int fd, int imode,
int perm, PerlIO *f, int narg, SV **args)
{
- if (f) {
+ if (PerlIOValid(f)) {
if (PerlIOBase(f)->flags & PERLIO_F_OPEN)
(*PerlIOBase(f)->tab->Close)(aTHX_ f);
}
mode++;
if (!f) {
f = PerlIO_allocate(aTHX);
+ }
+ if (!PerlIOValid(f)) {
s = PerlIOSelf(PerlIO_push(aTHX_ f, self, mode, PerlIOArg),
PerlIOUnix);
}
- else
+ else {
s = PerlIOSelf(f, PerlIOUnix);
+ }
s->fd = fd;
s->oflags = imode;
PerlIOBase(f)->flags |= PERLIO_F_OPEN;
- PerlIOUnix_refcnt_inc(fd);
+ PerlIOUnix_refcnt_inc(fd);
return f;
}
else {
if (PerlIOUnix_refcnt_dec(fd) > 0) {
PerlIOBase(f)->flags &= ~PERLIO_F_OPEN;
return 0;
- }
+ }
}
else {
SETERRNO(EBADF,SS$_IVCHAN);
PerlIOUnix_seek,
PerlIOUnix_tell,
PerlIOUnix_close,
- PerlIOBase_noop_ok, /* flush */
- PerlIOBase_noop_fail, /* fill */
+ PerlIOBase_noop_ok, /* flush */
+ PerlIOBase_noop_fail, /* fill */
PerlIOBase_eof,
PerlIOBase_error,
PerlIOBase_clearerr,
PerlIOBase_setlinebuf,
- NULL, /* get_base */
- NULL, /* get_bufsiz */
- NULL, /* get_ptr */
- NULL, /* get_cnt */
- NULL, /* set_ptrcnt */
+ NULL, /* get_base */
+ NULL, /* get_bufsiz */
+ NULL, /* get_ptr */
+ NULL, /* get_cnt */
+ NULL, /* set_ptrcnt */
};
/*--------------------------------------------------------------------------------------*/
typedef struct {
struct _PerlIO base;
- FILE *stdio; /* The stream */
+ FILE *stdio; /* The stream */
} PerlIOStdio;
IV
return PerlIOBase_pushed(aTHX_ f, mode, arg);
}
+
PerlIO *
PerlIO_importFILE(FILE *stdio, int fl)
{
dTHX;
PerlIO *f = NULL;
if (stdio) {
- PerlIOStdio *s =
- PerlIOSelf(PerlIO_push
- (aTHX_(f = PerlIO_allocate(aTHX)), &PerlIO_stdio,
- "r+", Nullsv), PerlIOStdio);
+ /* We need to probe to see how we can open the stream
+ so start with read/write and then try write and read
+ we dup() so that we can fclose without loosing the fd.
+ */
+ int fd = PerlLIO_dup(fileno(stdio));
+ char *mode = "r+";
+ FILE *f2 = fdopen(fd, mode);
+ PerlIOStdio *s;
+ if (!f2 && errno == EINVAL) {
+ mode = "w";
+ f2 = fdopen(fd, mode);
+ }
+ if (!f2 && errno == EINVAL) {
+ mode = "r";
+ f2 = fdopen(fd, mode);
+ }
+ if (!f2) {
+ /* Don't seem to be able to open */
+ return f;
+ }
+ fclose(f2);
+ s = PerlIOSelf(PerlIO_push
+ (aTHX_(f = PerlIO_allocate(aTHX)), &PerlIO_stdio,
+ mode, Nullsv), PerlIOStdio);
s->stdio = stdio;
}
return f;
int perm, PerlIO *f, int narg, SV **args)
{
char tmode[8];
- if (f) {
+ if (PerlIOValid(f)) {
char *path = SvPV_nolen(*args);
PerlIOStdio *s = PerlIOSelf(f, PerlIOStdio);
FILE *stdio;
else {
FILE *stdio = PerlSIO_fopen(path, mode);
if (stdio) {
- PerlIOStdio *s =
- PerlIOSelf(PerlIO_push
- (aTHX_(f = PerlIO_allocate(aTHX)), self,
+ PerlIOStdio *s;
+ if (!f) {
+ f = PerlIO_allocate(aTHX);
+ }
+ s = PerlIOSelf(PerlIO_push(aTHX_ f, self,
(mode = PerlIOStdio_mode(mode, tmode)),
PerlIOArg),
PerlIOStdio);
PerlIOStdio_mode(mode, tmode));
}
if (stdio) {
- PerlIOStdio *s =
- PerlIOSelf(PerlIO_push
- (aTHX_(f = PerlIO_allocate(aTHX)), self,
- mode, PerlIOArg), PerlIOStdio);
+ PerlIOStdio *s;
+ if (!f) {
+ f = PerlIO_allocate(aTHX);
+ }
+ s = PerlIOSelf(PerlIO_push(aTHX_ f, self, mode, PerlIOArg), PerlIOStdio);
s->stdio = stdio;
PerlIOUnix_refcnt_inc(fileno(s->stdio));
return f;
FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
if (PerlIOUnix_refcnt_dec(fileno(stdio)) > 0) {
/* Do not close it but do flush any buffers */
- return PerlIO_flush(f);
+ return PerlIO_flush(f);
}
return (
#ifdef SOCKS5_VERSION_NAME
FILE *stdio = PerlIOSelf(f, PerlIOStdio)->stdio;
if (ptr != NULL) {
#ifdef STDIO_PTR_LVALUE
- PerlSIO_set_ptr(stdio, (void*)ptr); /* LHS STDCHAR* cast non-portable */
+ PerlSIO_set_ptr(stdio, (void*)ptr); /* LHS STDCHAR* cast non-portable */
#ifdef STDIO_PTR_LVAL_SETS_CNT
if (PerlSIO_get_cnt(stdio) != (cnt)) {
assert(PerlSIO_get_cnt(stdio) == (cnt));
*/
return;
#endif
-#else /* STDIO_PTR_LVALUE */
+#else /* STDIO_PTR_LVALUE */
PerlProc_abort();
-#endif /* STDIO_PTR_LVALUE */
+#endif /* STDIO_PTR_LVALUE */
}
/*
* Now (or only) set cnt
*/
#ifdef STDIO_CNT_LVALUE
PerlSIO_set_cnt(stdio, cnt);
-#else /* STDIO_CNT_LVALUE */
+#else /* STDIO_CNT_LVALUE */
#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
PerlSIO_set_ptr(stdio,
PerlSIO_get_ptr(stdio) + (PerlSIO_get_cnt(stdio) -
cnt));
-#else /* STDIO_PTR_LVAL_SETS_CNT */
+#else /* STDIO_PTR_LVAL_SETS_CNT */
PerlProc_abort();
-#endif /* STDIO_PTR_LVAL_SETS_CNT */
-#endif /* STDIO_CNT_LVALUE */
+#endif /* STDIO_PTR_LVAL_SETS_CNT */
+#endif /* STDIO_CNT_LVALUE */
}
#endif
PerlIOStdio_get_cnt,
#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT)))
PerlIOStdio_set_ptrcnt
-#else /* STDIO_PTR_LVALUE */
+#else /* STDIO_PTR_LVALUE */
NULL
-#endif /* STDIO_PTR_LVALUE */
-#else /* USE_STDIO_PTR */
+#endif /* STDIO_PTR_LVALUE */
+#else /* USE_STDIO_PTR */
NULL,
NULL,
NULL
-#endif /* USE_STDIO_PTR */
+#endif /* USE_STDIO_PTR */
};
FILE *
{
dTHX;
FILE *stdio;
+ char buf[8];
PerlIO_flush(f);
- stdio = fdopen(PerlIO_fileno(f), "r+");
+ stdio = fdopen(PerlIO_fileno(f), PerlIO_modestr(f,buf));
if (stdio) {
PerlIOStdio *s =
- PerlIOSelf(PerlIO_push(aTHX_ f, &PerlIO_stdio, "r+", Nullsv),
+ PerlIOSelf(PerlIO_push(aTHX_ f, &PerlIO_stdio, buf, Nullsv),
PerlIOStdio);
s->stdio = stdio;
}
void
PerlIO_releaseFILE(PerlIO *p, FILE *f)
{
+ PerlIOl *l;
+ while ((l = *p)) {
+ if (l->tab == &PerlIO_stdio) {
+ PerlIOStdio *s = PerlIOSelf(&l, PerlIOStdio);
+ if (s->stdio == f) {
+ dTHX;
+ PerlIO_pop(aTHX_ p);
+ return;
+ }
+ }
+ p = PerlIONext(p);
+ }
+ return;
}
/*--------------------------------------------------------------------------------------*/
*/
}
f = (*tab->Open) (aTHX_ tab, layers, n - 1, mode, fd, imode, perm,
- NULL, narg, args);
+ f, narg, args);
if (f) {
- if (PerlIO_push(aTHX_ f, self, mode, PerlIOArg) == 0) {
+ if (PerlIO_push(aTHX_ f, self, mode, PerlIOArg) == 0) {
/*
* if push fails during open, open fails. close will pop us.
*/
PerlIOBase_flush_linebuf(aTHX);
if (!b->buf)
- PerlIO_get_base(f); /* allocate via vtable */
+ PerlIO_get_base(f); /* allocate via vtable */
b->ptr = b->end = b->buf;
if (PerlIO_fast_gets(n)) {
*/
typedef struct {
- PerlIOBuf base; /* PerlIOBuf stuff */
- STDCHAR *nl; /* Position of crlf we "lied" about in the
+ PerlIOBuf base; /* PerlIOBuf stuff */
+ STDCHAR *nl; /* Position of crlf we "lied" about in the
* buffer */
} PerlIOCrlf;
}
else {
int code;
- b->ptr++; /* say we have read it as far as
+ b->ptr++; /* say we have read it as far as
* flush() is concerned */
- b->buf++; /* Leave space in front of buffer */
- b->bufsiz--; /* Buffer is thus smaller */
- code = PerlIO_fill(f); /* Fetch some more */
- b->bufsiz++; /* Restore size for next time */
- b->buf--; /* Point at space */
- b->ptr = nl = b->buf; /* Which is what we hand
+ b->buf++; /* Leave space in front of buffer */
+ b->bufsiz--; /* Buffer is thus smaller */
+ code = PerlIO_fill(f); /* Fetch some more */
+ b->bufsiz++; /* Restore size for next time */
+ b->buf--; /* Point at space */
+ b->ptr = nl = b->buf; /* Which is what we hand
* off */
- b->posn--; /* Buffer starts here */
- *nl = 0xd; /* Fill in the CR */
+ b->posn--; /* Buffer starts here */
+ *nl = 0xd; /* Fill in the CR */
if (code == 0)
- goto test; /* fill() call worked */
+ goto test; /* fill() call worked */
/*
* CR at EOF - just fall through
*/
if (!ptr) {
if (c->nl) {
ptr = c->nl + 1;
- if (ptr == b->end && *c->nl == 0xd) {
+ if (ptr == b->end && *c->nl == 0xd) {
/* Defered CR at end of buffer case - we lied about count */
- ptr--;
- }
- }
+ ptr--;
+ }
+ }
else {
ptr = b->end;
}
*/
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) {
+ 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 ) {
break;
}
else {
- *(b->ptr)++ = 0xd; /* CR */
- *(b->ptr)++ = 0xa; /* LF */
+ *(b->ptr)++ = 0xd; /* CR */
+ *(b->ptr)++ = 0xa; /* LF */
buf++;
if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
PerlIO_flush(f);
sizeof(PerlIOCrlf),
PERLIO_K_BUFFERED | PERLIO_K_CANCRLF,
PerlIOCrlf_pushed,
- PerlIOBase_noop_ok, /* popped */
+ PerlIOBase_noop_ok, /* popped */
PerlIOBuf_open,
NULL,
PerlIOBase_fileno,
PerlIOBuf_dup,
- PerlIOBuf_read, /* generic read works with ptr/cnt lies
+ PerlIOBuf_read, /* generic read works with ptr/cnt lies
* ... */
- PerlIOCrlf_unread, /* Put CR,LF in buffer for each '\n' */
- PerlIOCrlf_write, /* Put CR,LF in buffer for each '\n' */
+ PerlIOCrlf_unread, /* Put CR,LF in buffer for each '\n' */
+ PerlIOCrlf_write, /* Put CR,LF in buffer for each '\n' */
PerlIOBuf_seek,
PerlIOBuf_tell,
PerlIOBuf_close,
*/
typedef struct {
- PerlIOBuf base; /* PerlIOBuf stuff */
- Mmap_t mptr; /* Mapped address */
- Size_t len; /* mapped length */
- STDCHAR *bbuf; /* malloced buffer if map fails */
+ PerlIOBuf base; /* PerlIOBuf stuff */
+ Mmap_t mptr; /* Mapped address */
+ Size_t len; /* mapped length */
+ STDCHAR *bbuf; /* malloced buffer if map fails */
} PerlIOMmap;
static size_t page_size = 0;
page_size = getpagesize();
# else
# if defined(I_SYS_PARAM) && defined(PAGESIZE)
- page_size = PAGESIZE; /* compiletime, bad */
+ page_size = PAGESIZE; /* compiletime, bad */
# endif
# endif
#endif
/*
* We have a write buffer or flushed PerlIOBuf read buffer
*/
- m->bbuf = b->buf; /* save it in case we need it again */
- b->buf = NULL; /* Clear to trigger below */
+ m->bbuf = b->buf; /* save it in case we need it again */
+ b->buf = NULL; /* Clear to trigger below */
}
if (!b->buf) {
- PerlIOMmap_map(aTHX_ f); /* Try and map it */
+ PerlIOMmap_map(aTHX_ f); /* Try and map it */
if (!b->buf) {
/*
* Map did not work - recover PerlIOBuf buffer if we have one
PerlIOBuf_set_ptrcnt,
};
-#endif /* HAS_MMAP */
+#endif /* HAS_MMAP */
PerlIO *
Perl_PerlIO_stdin(pTHX)
#undef HAS_FSETPOS
#undef HAS_FGETPOS
-#endif /* USE_SFIO */
-#endif /* PERLIO_IS_STDIO */
+#endif /* USE_SFIO */
+#endif /* PERLIO_IS_STDIO */
/*======================================================================================*/
/*
vprintf(char *pat, char *args)
{
_doprnt(pat, args, stdout);
- return 0; /* wrong, but perl doesn't use the return
+ return 0; /* wrong, but perl doesn't use the return
* value */
}
vfprintf(FILE *fd, char *pat, char *args)
{
_doprnt(pat, args, fd);
- return 0; /* wrong, but perl doesn't use the return
+ return 0; /* wrong, but perl doesn't use the return
* value */
}