From 131d45a96c910d0fe46597ab156a35837879bf9c Mon Sep 17 00:00:00 2001 From: Jarkko Hietaniemi Date: Wed, 26 Aug 2015 08:55:37 -0400 Subject: Explicitly use and check for FD_CLOEXEC. This may break places which have the FD_CLOEXEC functionality but do not have the FD_CLOEXEC define. In any case, using a boolean for the F_SETFD flag is icky. Using an explicit 1 is also dubious. --- perl.c | 4 ++-- pp_sys.c | 24 +++++++++++++----------- toke.c | 6 ++++-- util.c | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/perl.c b/perl.c index 303e1f2c5c..64cc3957ff 100644 --- a/perl.c +++ b/perl.c @@ -3796,10 +3796,10 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript) CopFILE(PL_curcop), Strerror(errno)); } fd = PerlIO_fileno(rsfp); -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) if (fd >= 0) { /* ensure close-on-exec */ - if (fcntl(fd, F_SETFD, 1) < 0) { + if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n", CopFILE(PL_curcop), Strerror(errno)); } diff --git a/pp_sys.c b/pp_sys.c index dc1b3cec1a..658dee19fa 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -708,10 +708,10 @@ PP(pp_pipe_op) PerlLIO_close(fd[1]); goto badexit; } -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) /* ensure close-on-exec */ - if ((fcntl(fd[0], F_SETFD,fd[0] > PL_maxsysfd) < 0) || - (fcntl(fd[1], F_SETFD,fd[1] > PL_maxsysfd) < 0)) + 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; @@ -2496,8 +2496,9 @@ PP(pp_socket) if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd); RETPUSHUNDEF; } -#if defined(HAS_FCNTL) && defined(F_SETFD) - if (fcntl(fd, F_SETFD, fd > PL_maxsysfd) < 0) /* ensure close-on-exec */ +#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 @@ -2542,10 +2543,10 @@ PP(pp_sockpair) if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]); RETPUSHUNDEF; } -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) /* ensure close-on-exec */ - if ((fcntl(fd[0],F_SETFD,fd[0] > PL_maxsysfd) < 0) || - (fcntl(fd[1],F_SETFD,fd[1] > PL_maxsysfd) < 0)) + 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 @@ -2659,8 +2660,9 @@ PP(pp_accept) if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd); goto badexit; } -#if defined(HAS_FCNTL) && defined(F_SETFD) - if (fcntl(fd, F_SETFD, fd > PL_maxsysfd) < 0) /* ensure close-on-exec */ +#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 @@ -4386,7 +4388,7 @@ PP(pp_system) #endif if (did_pipes) { PerlLIO_close(pp[0]); -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) if (fcntl(pp[1], F_SETFD, FD_CLOEXEC) < 0) RETPUSHUNDEF; #endif diff --git a/toke.c b/toke.c index 7a0f1b6c55..d30bfe69da 100644 --- a/toke.c +++ b/toke.c @@ -7039,10 +7039,12 @@ Perl_yylex(pTHX) if (!GvIO(gv)) GvIOp(gv) = newIO(); IoIFP(GvIOp(gv)) = PL_rsfp; -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) { const int fd = PerlIO_fileno(PL_rsfp); - fcntl(fd,F_SETFD,fd >= 3); + if (fd >= 3) { + fcntl(fd,F_SETFD, FD_CLOEXEC); + } } #endif /* Mark this internal pseudo-handle as clean */ diff --git a/util.c b/util.c index e357379197..98c2cd9952 100644 --- a/util.c +++ b/util.c @@ -2373,7 +2373,7 @@ Perl_my_popen_list(pTHX_ const char *mode, int n, SV **args) /* Close parent's end of error status pipe (if any) */ if (did_pipes) { PerlLIO_close(pp[0]); -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) /* Close error pipe automatically if exec works */ if (fcntl(pp[1], F_SETFD, FD_CLOEXEC) < 0) return NULL; -- cgit v1.2.1