This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
PATCH [perl #132164] regcomp.c: Don't try to increment infinity
[perl5.git] / perlio.c
index 2a57772..f5eb485 100644 (file)
--- a/perlio.c
+++ b/perlio.c
 
 #include "XSUB.h"
 
-#ifdef __Lynx__
-/* Missing proto on LynxOS */
-int mkstemp(char*);
-#endif
-
 #ifdef VMS
 #include <rms.h>
 #endif
@@ -250,7 +245,7 @@ PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
     return win32_fdupopen(f);
 # 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
@@ -294,7 +289,7 @@ PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
                 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);
            }
@@ -360,14 +355,14 @@ PerlIO_debug(const char *fmt, ...)
            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) {
@@ -2647,6 +2642,7 @@ PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
                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);
@@ -2667,10 +2663,15 @@ PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
            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) {
@@ -2705,7 +2706,9 @@ PerlIOUnix_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
     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);
@@ -2969,7 +2972,7 @@ PerlIO_importFILE(FILE *stdio, const char *mode)
               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;
@@ -2991,11 +2994,12 @@ PerlIO_importFILE(FILE *stdio, const char *mode)
        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){
@@ -3006,8 +3010,6 @@ PerlIO_importFILE(FILE *stdio, const char *mode)
                        }
                          /*This MVS dataset , OK!*/
                }
-#else
-           PerlIOUnix_refcnt_inc(fileno(stdio));
 #endif
        }
     }
@@ -3033,7 +3035,9 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
        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 {
@@ -3044,7 +3048,7 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
                 return NULL;
            if (*mode == IoTYPE_NUMERIC) {
                mode++;
-               fd = PerlLIO_open3(path, imode, perm);
+               fd = PerlLIO_open3_cloexec(path, imode, perm);
            }
            else {
                FILE *stdio;
@@ -3064,7 +3068,9 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
                    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);
                    }
@@ -3105,7 +3111,9 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
                }
                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;
            }
@@ -3126,7 +3134,7 @@ PerlIOStdio_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
        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;
@@ -3142,7 +3150,9 @@ PerlIOStdio_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
     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;
@@ -3299,7 +3309,7 @@ PerlIOStdio_close(pTHX_ PerlIO *f)
            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
@@ -3324,7 +3334,8 @@ PerlIOStdio_close(pTHX_ PerlIO *f)
        result = close(fd);
 #endif
        if (dupfd >= 0) {
-           PerlLIO_dup2(dupfd,fd);
+           PerlLIO_dup2_cloexec(dupfd, fd);
+           setfd_inhexec_for_sysfd(fd);
            PerlLIO_close(dupfd);
        }
         MUTEX_UNLOCK(&PL_perlio_mutex);
@@ -5034,32 +5045,29 @@ PerlIO_tmpfile(void)
      const int fd = win32_tmpfd();
      if (fd >= 0)
          f = PerlIO_fdopen(fd, "w+b");
-#elif 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) {