#include "XSUB.h"
-#ifdef __Lynx__
-/* Missing proto on LynxOS */
-int mkstemp(char*);
-#endif
-
#ifdef VMS
#include <rms.h>
#endif
{
#if defined(PERL_MICRO) || defined(__SYMBIAN32__)
return NULL;
-#else
-#ifdef PERL_IMPLICIT_SYS
+#elif defined(PERL_IMPLICIT_SYS)
return PerlSIO_fdupopen(f);
#else
-#ifdef WIN32
+# ifdef WIN32
return win32_fdupopen(f);
-#else
+# else
if (f) {
- const int fd = PerlLIO_dup(PerlIO_fileno(f));
+ const int fd = PerlLIO_dup_cloexec(PerlIO_fileno(f));
if (fd >= 0) {
char mode[8];
-#ifdef DJGPP
+# ifdef DJGPP
const int omode = djgpp_get_stream_mode(f);
-#else
+# else
const int omode = fcntl(fd, F_GETFL);
-#endif
+# endif
PerlIO_intmode2str(omode,mode,NULL);
/* the r+ is a hack */
return PerlIO_fdopen(fd, mode);
else {
SETERRNO(EBADF, SS_IVCHAN);
}
-#endif
+# endif
return NULL;
#endif
-#endif
}
return NULL;
if (*mode == IoTYPE_NUMERIC) {
- fd = PerlLIO_open3(name, imode, perm);
+ fd = PerlLIO_open3_cloexec(name, imode, perm);
if (fd >= 0)
return PerlIO_fdopen(fd, mode + 1);
}
PerlProc_getgid() == PerlProc_getegid()) {
const char * const s = PerlEnv_getenv("PERLIO_DEBUG");
if (s && *s)
- PL_perlio_debug_fd
- = PerlLIO_open3(s, O_WRONLY | O_CREAT | O_APPEND, 0666);
+ PL_perlio_debug_fd = PerlLIO_open3_cloexec(s,
+ O_WRONLY | O_CREAT | O_APPEND, 0666);
else
- PL_perlio_debug_fd = PerlLIO_dup(2); /* stderr */
+ PL_perlio_debug_fd = PerlLIO_dup_cloexec(2); /* stderr */
} else {
/* tainting or set*id, so ignore the environment and send the
debug output to stderr, like other -D switches. */
- PL_perlio_debug_fd = PerlLIO_dup(2); /* stderr */
+ PL_perlio_debug_fd = PerlLIO_dup_cloexec(2); /* stderr */
}
}
if (PL_perlio_debug_fd > 0) {
PERL_UNUSED_CONTEXT;
if (list->cur >= list->len) {
- list->len += 8;
+ const IV new_len = list->len + 8;
if (list->array)
- Renew(list->array, list->len, PerlIO_pair_t);
+ Renew(list->array, new_len, PerlIO_pair_t);
else
- Newx(list->array, list->len, PerlIO_pair_t);
+ Newx(list->array, new_len, PerlIO_pair_t);
+ list->len = new_len;
}
p = &(list->array[list->cur++]);
p->funcs = funcs;
if (*e++) {
break;
}
- /*
- * Drop through
- */
+ /* Fall through */
case '\0':
e--;
Perl_ck_warner(aTHX_ packWARN(WARN_LAYER),
(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;
+ return cBOOL(PerlIO_apply_layers(aTHX_ f, NULL, names) == 0);
}
else {
/* Fake 5.6 legacy of using this call to turn ON O_TEXT */
/* Legacy binmode is now _defined_ as being equivalent to pushing :raw
So code that used to be here is now in PerlIORaw_pushed().
*/
- return PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_raw), NULL, NULL) ? TRUE : FALSE;
+ return cBOOL(PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_raw), NULL, NULL));
}
}
new_array = (int*) realloc(PL_perlio_fd_refcnt, new_max * sizeof(int));
if (!new_array) {
-#ifdef USE_ITHREADS
MUTEX_UNLOCK(&PL_perlio_mutex);
-#endif
croak_no_mem();
}
if (fd >= 0) {
dVAR;
-#ifdef USE_ITHREADS
MUTEX_LOCK(&PL_perlio_mutex);
-#endif
if (fd >= PL_perlio_fd_refcnt_size)
S_more_refcounted_fds(aTHX_ fd);
DEBUG_i( PerlIO_debug("refcnt_inc: fd %d refcnt=%d\n",
fd, PL_perlio_fd_refcnt[fd]) );
-#ifdef USE_ITHREADS
MUTEX_UNLOCK(&PL_perlio_mutex);
-#endif
} else {
/* diag_listed_as: refcnt_inc: fd %d%s */
Perl_croak(aTHX_ "refcnt_inc: fd %d < 0\n", fd);
#else
dVAR;
#endif
-#ifdef USE_ITHREADS
MUTEX_LOCK(&PL_perlio_mutex);
-#endif
if (fd >= PL_perlio_fd_refcnt_size) {
/* diag_listed_as: refcnt_dec: fd %d%s */
Perl_croak_nocontext("refcnt_dec: fd %d >= refcnt_size %d\n",
}
cnt = --PL_perlio_fd_refcnt[fd];
DEBUG_i( PerlIO_debug("refcnt_dec: fd %d refcnt=%d\n", fd, cnt) );
-#ifdef USE_ITHREADS
MUTEX_UNLOCK(&PL_perlio_mutex);
-#endif
} else {
/* diag_listed_as: refcnt_dec: fd %d%s */
Perl_croak_nocontext("refcnt_dec: fd %d < 0\n", fd);
int cnt = 0;
if (fd >= 0) {
dVAR;
-#ifdef USE_ITHREADS
MUTEX_LOCK(&PL_perlio_mutex);
-#endif
if (fd >= PL_perlio_fd_refcnt_size) {
/* diag_listed_as: refcnt: fd %d%s */
Perl_croak(aTHX_ "refcnt: fd %d >= refcnt_size %d\n",
fd, PL_perlio_fd_refcnt[fd]);
}
cnt = PL_perlio_fd_refcnt[fd];
-#ifdef USE_ITHREADS
MUTEX_UNLOCK(&PL_perlio_mutex);
-#endif
} else {
/* diag_listed_as: refcnt: fd %d%s */
Perl_croak(aTHX_ "refcnt: fd %d < 0\n", fd);
IV n, const char *mode, int fd, int imode,
int perm, PerlIO *f, int narg, SV **args)
{
+ bool known_cloexec = 0;
if (PerlIOValid(f)) {
if (PerlIOBase(f)->tab && PerlIOBase(f)->flags & PERLIO_F_OPEN)
(*PerlIOBase(f)->tab->Close)(aTHX_ f);
const char *path = SvPV_const(*args, len);
if (!IS_SAFE_PATHNAME(path, len, "open"))
return NULL;
- fd = PerlLIO_open3(path, imode, perm);
+ fd = PerlLIO_open3_cloexec(path, imode, perm);
+ known_cloexec = 1;
}
}
if (fd >= 0) {
+ if (known_cloexec)
+ setfd_inhexec_for_sysfd(fd);
+ else
+ setfd_cloexec_or_inhexec_by_sysfdness(fd);
if (*mode == IoTYPE_IMPLICIT)
mode++;
if (!f) {
const PerlIOUnix * const os = PerlIOSelf(o, PerlIOUnix);
int fd = os->fd;
if (flags & PERLIO_DUP_FD) {
- fd = PerlLIO_dup(fd);
+ fd = PerlLIO_dup_cloexec(fd);
+ if (fd >= 0)
+ setfd_inhexec_for_sysfd(fd);
}
if (fd >= 0) {
f = PerlIOBase_dup(aTHX_ f, o, param, flags);
Note that the errno value set by a failing fdopen
varies between stdio implementations.
*/
- const int fd = PerlLIO_dup(fd0);
+ const int fd = PerlLIO_dup_cloexec(fd0);
FILE *f2;
if (fd < 0) {
return f;
if ((f = PerlIO_push(aTHX_(PerlIO_allocate(aTHX)), PERLIO_FUNCS_CAST(&PerlIO_stdio), mode, NULL))) {
s = PerlIOSelf(f, PerlIOStdio);
s->stdio = stdio;
+ fd0 = fileno(stdio);
+ if(fd0 != -1){
+ PerlIOUnix_refcnt_inc(fd0);
+ setfd_cloexec_or_inhexec_by_sysfdness(fd0);
+ }
#ifdef EBCDIC
- fd0 = fileno(stdio);
- if(fd0 != -1){
- PerlIOUnix_refcnt_inc(fd0);
- }
else{
rc = fldata(stdio,filename,&fileinfo);
if(rc != 0){
}
/*This MVS dataset , OK!*/
}
-#else
- PerlIOUnix_refcnt_inc(fileno(stdio));
#endif
}
}
if (!s->stdio)
return NULL;
s->stdio = stdio;
- PerlIOUnix_refcnt_inc(fileno(s->stdio));
+ fd = fileno(stdio);
+ PerlIOUnix_refcnt_inc(fd);
+ setfd_cloexec_or_inhexec_by_sysfdness(fd);
return f;
}
else {
return NULL;
if (*mode == IoTYPE_NUMERIC) {
mode++;
- fd = PerlLIO_open3(path, imode, perm);
+ fd = PerlLIO_open3_cloexec(path, imode, perm);
}
else {
FILE *stdio;
f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg);
if (f) {
PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
- PerlIOUnix_refcnt_inc(fileno(stdio));
+ fd = fileno(stdio);
+ PerlIOUnix_refcnt_inc(fd);
+ setfd_cloexec_or_inhexec_by_sysfdness(fd);
} else {
PerlSIO_fclose(stdio);
}
}
if ((f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg))) {
PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
- PerlIOUnix_refcnt_inc(fileno(stdio));
+ fd = fileno(stdio);
+ PerlIOUnix_refcnt_inc(fd);
+ setfd_cloexec_or_inhexec_by_sysfdness(fd);
}
return f;
}
const int fd = fileno(stdio);
char mode[8];
if (flags & PERLIO_DUP_FD) {
- const int dfd = PerlLIO_dup(fileno(stdio));
+ const int dfd = PerlLIO_dup_cloexec(fileno(stdio));
if (dfd >= 0) {
stdio = PerlSIO_fdopen(dfd, PerlIO_modestr(o,mode));
goto set_this;
set_this:
PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
if(stdio) {
- PerlIOUnix_refcnt_inc(fileno(stdio));
+ int fd = fileno(stdio);
+ PerlIOUnix_refcnt_inc(fd);
+ setfd_cloexec_or_inhexec_by_sysfdness(fd);
}
}
return f;
structure at all
*/
# else
- f->_file = -1;
+ PERLIO_FILE_file(f) = -1;
# endif
return 1;
# else
if (stdio == stdout || stdio == stderr)
return PerlIO_flush(f);
}
-#ifdef USE_ITHREADS
MUTEX_LOCK(&PL_perlio_mutex);
/* Right. We need a mutex here because for a brief while we
will have the situation that fd is actually closed. Hence if
Except that correctness trumps speed.
Advice from klortho #11912. */
-#endif
if (invalidate) {
/* Tricky - must fclose(stdio) to free memory but not close(fd)
Use Sarathy's trick from maint-5.6 to invalidate the
SAVE_ERRNO;
invalidate = PerlIOStdio_invalidate_fileno(aTHX_ stdio);
if (!invalidate) {
- dupfd = PerlLIO_dup(fd);
+ dupfd = PerlLIO_dup_cloexec(fd);
#ifdef USE_ITHREADS
if (dupfd < 0) {
/* Oh cXap. This isn't going to go well. Not sure if we can
result = close(fd);
#endif
if (dupfd >= 0) {
- PerlLIO_dup2(dupfd,fd);
+ PerlLIO_dup2_cloexec(dupfd, fd);
+ setfd_inhexec_for_sysfd(fd);
PerlLIO_close(dupfd);
}
-#ifdef USE_ITHREADS
MUTEX_UNLOCK(&PL_perlio_mutex);
-#endif
return result;
}
}
* - casting the LHS to (void*) -- totally unportable
*
* So let's try silencing the warning at least for gcc. */
- GCC_DIAG_IGNORE(-Wpointer-sign);
+ GCC_DIAG_IGNORE_STMT(-Wpointer-sign);
PerlSIO_set_ptr(stdio, ptr); /* LHS STDCHAR* cast non-portable */
- GCC_DIAG_RESTORE;
+ GCC_DIAG_RESTORE_STMT;
#ifdef STDIO_PTR_LVAL_SETS_CNT
assert(PerlSIO_get_cnt(stdio) == (cnt));
#endif
*/
#ifdef STDIO_CNT_LVALUE
PerlSIO_set_cnt(stdio, cnt);
-#else /* STDIO_CNT_LVALUE */
-#if (defined(STDIO_PTR_LVALUE) && defined(STDIO_PTR_LVAL_SETS_CNT))
+#elif (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 */
PerlProc_abort();
-#endif /* STDIO_PTR_LVAL_SETS_CNT */
#endif /* STDIO_CNT_LVALUE */
}
if (!b->buf) {
if (!b->bufsiz)
b->bufsiz = PERLIOBUF_DEFAULT_BUFSIZ;
- Newxz(b->buf,b->bufsiz, STDCHAR);
+ Newx(b->buf,b->bufsiz, STDCHAR);
if (!b->buf) {
b->buf = (STDCHAR *) & b->oneword;
b->bufsiz = sizeof(b->oneword);
const int fd = win32_tmpfd();
if (fd >= 0)
f = PerlIO_fdopen(fd, "w+b");
-#else /* WIN32 */
-# if defined(HAS_MKSTEMP) && ! defined(VMS) && ! defined(OS2)
+#elif ! defined(VMS) && ! defined(OS2)
int fd = -1;
char tempname[] = "/tmp/PerlIO_XXXXXX";
const char * const tmpdir = TAINTING_get ? NULL : PerlEnv_getenv("TMPDIR");
SV * sv = NULL;
int old_umask = umask(0177);
- /*
- * I have no idea how portable mkstemp() is ... NI-S
- */
if (tmpdir && *tmpdir) {
/* if TMPDIR is set and not empty, we try that first */
sv = newSVpv(tmpdir, 0);
sv_catpv(sv, tempname + 4);
- fd = mkstemp(SvPVX(sv));
+ fd = Perl_my_mkstemp_cloexec(SvPVX(sv));
}
if (fd < 0) {
SvREFCNT_dec(sv);
sv = NULL;
/* else we try /tmp */
- fd = mkstemp(tempname);
+ fd = Perl_my_mkstemp_cloexec(tempname);
}
if (fd < 0) {
/* Try cwd */
sv = newSVpvs(".");
sv_catpv(sv, tempname + 4);
- fd = mkstemp(SvPVX(sv));
+ fd = Perl_my_mkstemp_cloexec(SvPVX(sv));
}
umask(old_umask);
if (fd >= 0) {
PerlLIO_unlink(sv ? SvPVX_const(sv) : tempname);
}
SvREFCNT_dec(sv);
-# else /* !HAS_MKSTEMP, fallback to stdio tmpfile(). */
+#else /* !HAS_MKSTEMP, fallback to stdio tmpfile(). */
FILE * const stdio = PerlSIO_tmpfile();
if (stdio)
f = PerlIO_fdopen(fileno(stdio), "w+");
-# endif /* else HAS_MKSTEMP */
#endif /* else WIN32 */
return f;
}
}
#endif
-#if !defined(HAS_VPRINTF)
-
-int
-vprintf(char *pat, char *args)
-{
- _doprnt(pat, args, stdout);
- return 0; /* wrong, but perl doesn't use the return
- * value */
-}
-
-int
-vfprintf(FILE *fd, char *pat, char *args)
-{
- _doprnt(pat, args, fd);
- return 0; /* wrong, but perl doesn't use the return
- * value */
-}
-
-#endif
-
/* print a failure format string message to stderr and fail exit the process
using only libc without depending on any perl data structures being
initialized.