summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2017-12-19 16:53:39 +0000
committerZefram <zefram@fysh.org>2017-12-22 16:13:23 +0000
commit74df577f6857d2d8543c90e43f90405f92948a61 (patch)
treeaf79ab48854bb2583b061679690f55c33ce0115f /pp_sys.c
parentf9821aff984443d5ac38188fab7a9b12dd3cb09c (diff)
downloadperl-74df577f6857d2d8543c90e43f90405f92948a61.tar.gz
set FD_CLOEXEC atomically in easy cases
In many places where a file descriptor is being opened, open it with FD_CLOEXEC already set if possible. This commit covers the easy cases, where the file descriptor arises without the use of PerlIO, pp_open, or my_popen.
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c47
1 files changed, 13 insertions, 34 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 0649794104..c2873b8e08 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -690,8 +690,10 @@ PP(pp_pipe_op)
if (IoIFP(wstio))
do_close(wgv, FALSE);
- if (PerlProc_pipe(fd) < 0)
+ if (PerlProc_pipe_cloexec(fd) < 0)
goto badexit;
+ setfd_inhexec_for_sysfd(fd[0]);
+ setfd_inhexec_for_sysfd(fd[1]);
IoIFP(rstio) = PerlIO_fdopen(fd[0], "r" PIPE_OPEN_MODE);
IoOFP(wstio) = PerlIO_fdopen(fd[1], "w" PIPE_OPEN_MODE);
@@ -711,12 +713,6 @@ PP(pp_pipe_op)
PerlLIO_close(fd[1]);
goto badexit;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if ((fd[0] > PL_maxsysfd && fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fd[1] > PL_maxsysfd && fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0))
- goto badexit;
-#endif
RETPUSHYES;
badexit:
@@ -2379,7 +2375,7 @@ PP(pp_truncate)
*/
mode |= O_BINARY;
#endif
- tmpfd = PerlLIO_open(name, mode);
+ tmpfd = PerlLIO_open_cloexec(name, mode);
if (tmpfd < 0) {
result = 0;
@@ -2521,10 +2517,11 @@ PP(pp_socket)
do_close(gv, FALSE);
TAINT_PROPER("socket");
- fd = PerlSock_socket(domain, type, protocol);
+ fd = PerlSock_socket_cloexec(domain, type, protocol);
if (fd < 0) {
RETPUSHUNDEF;
}
+ setfd_inhexec_for_sysfd(fd);
IoIFP(io) = PerlIO_fdopen(fd, "r" SOCKET_OPEN_MODE); /* stdio gets confused about sockets */
IoOFP(io) = PerlIO_fdopen(fd, "w" SOCKET_OPEN_MODE);
IoTYPE(io) = IoTYPE_SOCKET;
@@ -2534,11 +2531,6 @@ PP(pp_socket)
if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd);
RETPUSHUNDEF;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
- RETPUSHUNDEF;
-#endif
RETPUSHYES;
}
@@ -2564,8 +2556,10 @@ PP(pp_sockpair)
do_close(gv2, FALSE);
TAINT_PROPER("socketpair");
- if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
+ if (PerlSock_socketpair_cloexec(domain, type, protocol, fd) < 0)
RETPUSHUNDEF;
+ setfd_inhexec_for_sysfd(fd[0]);
+ setfd_inhexec_for_sysfd(fd[1]);
IoIFP(io1) = PerlIO_fdopen(fd[0], "r" SOCKET_OPEN_MODE);
IoOFP(io1) = PerlIO_fdopen(fd[0], "w" SOCKET_OPEN_MODE);
IoTYPE(io1) = IoTYPE_SOCKET;
@@ -2581,12 +2575,6 @@ PP(pp_sockpair)
if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]);
RETPUSHUNDEF;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if ((fd[0] > PL_maxsysfd && fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fd[1] > PL_maxsysfd && fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0))
- RETPUSHUNDEF;
-#endif
RETPUSHYES;
#else
@@ -2673,7 +2661,7 @@ PP(pp_accept)
goto nuts;
nstio = GvIOn(ngv);
- fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
+ fd = PerlSock_accept_cloexec(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
#if defined(OEMVS)
if (len == 0) {
/* Some platforms indicate zero length when an AF_UNIX client is
@@ -2687,6 +2675,7 @@ PP(pp_accept)
if (fd < 0)
goto badexit;
+ setfd_inhexec_for_sysfd(fd);
if (IoIFP(nstio))
do_close(ngv, FALSE);
IoIFP(nstio) = PerlIO_fdopen(fd, "r" SOCKET_OPEN_MODE);
@@ -2698,11 +2687,6 @@ PP(pp_accept)
if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd);
goto badexit;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
- goto badexit;
-#endif
#ifdef __SCO_VERSION__
len = sizeof (struct sockaddr_in); /* OpenUNIX 8 somehow truncates info */
@@ -4449,7 +4433,7 @@ PP(pp_system)
sigset_t newset, oldset;
#endif
- if (PerlProc_pipe(pp) >= 0)
+ if (PerlProc_pipe_cloexec(pp) >= 0)
did_pipes = 1;
#ifdef __amigaos4__
amigaos_fork_set_userdata(aTHX_
@@ -4546,13 +4530,8 @@ PP(pp_system)
#ifdef HAS_SIGPROCMASK
sigprocmask(SIG_SETMASK, &oldset, NULL);
#endif
- if (did_pipes) {
+ if (did_pipes)
PerlLIO_close(pp[0]);
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- if (fcntl(pp[1], F_SETFD, FD_CLOEXEC) < 0)
- RETPUSHUNDEF;
-#endif
- }
if (PL_op->op_flags & OPf_STACKED) {
SV * const really = *++MARK;
value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);