X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/74df577f6857d2d8543c90e43f90405f92948a61..3074a83070878eb5e9c440e75e1f005b50b45c68:/doio.c diff --git a/doio.c b/doio.c index 160adc5..4b8923f 100644 --- a/doio.c +++ b/doio.c @@ -61,7 +61,7 @@ #include void -Perl_setfd_cloexec(pTHX_ int fd) +Perl_setfd_cloexec(int fd) { assert(fd >= 0); #if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) @@ -70,7 +70,7 @@ Perl_setfd_cloexec(pTHX_ int fd) } void -Perl_setfd_inhexec(pTHX_ int fd) +Perl_setfd_inhexec(int fd) { assert(fd >= 0); #if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) @@ -79,12 +79,30 @@ Perl_setfd_inhexec(pTHX_ int fd) } void +Perl_setfd_cloexec_for_nonsysfd(pTHX_ int fd) +{ + assert(fd >= 0); + if(fd > PL_maxsysfd) + setfd_cloexec(fd); +} + +void Perl_setfd_inhexec_for_sysfd(pTHX_ int fd) { assert(fd >= 0); if(fd <= PL_maxsysfd) setfd_inhexec(fd); } +void +Perl_setfd_cloexec_or_inhexec_by_sysfdness(pTHX_ int fd) +{ + assert(fd >= 0); + if(fd <= PL_maxsysfd) + setfd_inhexec(fd); + else + setfd_cloexec(fd); +} + #define DO_GENOPEN_THEN_CLOEXEC(GENOPEN_NORMAL, GENSETFD_CLOEXEC) \ do { \ @@ -221,6 +239,19 @@ Perl_PerlLIO_open3_cloexec(pTHX_ const char *file, int flag, int perm) #endif } +int +Perl_my_mkstemp_cloexec(char *templte) +{ + PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC; +#if defined(O_CLOEXEC) + DO_ONEOPEN_EXPERIMENTING_CLOEXEC( + Perl_my_mkostemp(templte, O_CLOEXEC), + Perl_my_mkstemp(templte)); +#else + DO_ONEOPEN_THEN_CLOEXEC(Perl_my_mkstemp(templte)); +#endif +} + #ifdef HAS_PIPE int Perl_PerlProc_pipe_cloexec(pTHX_ int *pipefd) @@ -687,7 +718,7 @@ Perl_do_open6(pTHX_ GV *gv, const char *oname, STRLEN len, } else { if (dodup) - wanted_fd = PerlLIO_dup(wanted_fd); + wanted_fd = PerlLIO_dup_cloexec(wanted_fd); else was_fdopen = TRUE; if (!(fp = PerlIO_openn(aTHX_ type,mode,wanted_fd,0,0,NULL,num_svs,svp))) { @@ -978,33 +1009,15 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, if (was_fdopen) { /* need to close fp without closing underlying fd */ int ofd = PerlIO_fileno(fp); - int dupfd = ofd >= 0 ? PerlLIO_dup(ofd) : -1; -#if defined(HAS_FCNTL) && defined(F_SETFD) - /* Assume if we have F_SETFD we have F_GETFD. */ - /* Get a copy of all the fd flags. */ - int fd_flags = ofd >= 0 ? fcntl(ofd, F_GETFD) : -1; - if (fd_flags < 0) { - if (dupfd >= 0) - PerlLIO_close(dupfd); - goto say_false; - } -#endif + int dupfd = ofd >= 0 ? PerlLIO_dup_cloexec(ofd) : -1; if (ofd < 0 || dupfd < 0) { if (dupfd >= 0) PerlLIO_close(dupfd); goto say_false; } PerlIO_close(fp); - PerlLIO_dup2(dupfd, ofd); -#if defined(HAS_FCNTL) && defined(F_SETFD) - /* The dup trick has lost close-on-exec on ofd, - * and possibly any other flags, so restore them. */ - if (fcntl(ofd,F_SETFD, fd_flags) < 0) { - if (dupfd >= 0) - PerlLIO_close(dupfd); - goto say_false; - } -#endif + PerlLIO_dup2_cloexec(dupfd, ofd); + setfd_inhexec_for_sysfd(ofd); PerlLIO_close(dupfd); } else @@ -1014,12 +1027,6 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, PerlIO_clearerr(fp); fd = PerlIO_fileno(fp); } -#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) - if (fd >= 0 && fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { - PerlLIO_close(fd); - goto say_false; - } -#endif IoIFP(io) = fp; IoFLAGS(io) &= ~IOf_NOLINE; @@ -1089,7 +1096,7 @@ S_openindirtemp(pTHX_ GV *gv, SV *orig_name, SV *temp_out_name) { { int old_umask = umask(0177); - fd = Perl_my_mkstemp(SvPVX(temp_out_name)); + fd = Perl_my_mkstemp_cloexec(SvPVX(temp_out_name)); umask(old_umask); }