Blame SOURCES/perl-5.31.1-perl-134221-support-O_APPEND-for-open-.-undef-on-VMS.patch

7586d2
From 74b421cc877e412c4eda06757396a1e19fc756ba Mon Sep 17 00:00:00 2001
7586d2
From: Tony Cook <tony@develop-help.com>
7586d2
Date: Mon, 15 Jul 2019 11:53:23 +1000
7586d2
Subject: [PATCH 3/3] (perl #134221) support O_APPEND for open ..., undef on
7586d2
 VMS
7586d2
MIME-Version: 1.0
7586d2
Content-Type: text/plain; charset=UTF-8
7586d2
Content-Transfer-Encoding: 8bit
7586d2
7586d2
VMS doesn't allow you to delete an open file like POSIXish systems
7586d2
do, but you can mark a file to be deleted once it's closed, but
7586d2
only when you open it.
7586d2
7586d2
Since VMS doesn't (yet) have mkostemp() we can add our own flag to
7586d2
our mkostemp() emulation to pass the necessary magic to open() call
7586d2
to delete the file on close.
7586d2
7586d2
Signed-off-by: Petr Písař <ppisar@redhat.com>
7586d2
---
7586d2
 perlio.c | 10 ++++++----
7586d2
 util.c   | 15 ++++++++++++++-
7586d2
 util.h   | 11 +++++++++++
7586d2
 3 files changed, 31 insertions(+), 5 deletions(-)
7586d2
7586d2
diff --git a/perlio.c b/perlio.c
7586d2
index 81ebc156ad..805959f840 100644
7586d2
--- a/perlio.c
7586d2
+++ b/perlio.c
7586d2
@@ -5062,7 +5062,7 @@ PerlIO_tmpfile_flags(int imode)
7586d2
      const int fd = win32_tmpfd_mode(imode);
7586d2
      if (fd >= 0)
7586d2
 	  f = PerlIO_fdopen(fd, "w+b");
7586d2
-#elif ! defined(VMS) && ! defined(OS2)
7586d2
+#elif ! defined(OS2)
7586d2
      int fd = -1;
7586d2
      char tempname[] = "/tmp/PerlIO_XXXXXX";
7586d2
      const char * const tmpdir = TAINTING_get ? NULL : PerlEnv_getenv("TMPDIR");
7586d2
@@ -5073,19 +5073,19 @@ PerlIO_tmpfile_flags(int imode)
7586d2
 	 /* if TMPDIR is set and not empty, we try that first */
7586d2
 	 sv = newSVpv(tmpdir, 0);
7586d2
 	 sv_catpv(sv, tempname + 4);
7586d2
-	 fd = Perl_my_mkostemp_cloexec(SvPVX(sv), imode);
7586d2
+	 fd = Perl_my_mkostemp_cloexec(SvPVX(sv), imode | O_VMS_DELETEONCLOSE);
7586d2
      }
7586d2
      if (fd < 0) {
7586d2
 	 SvREFCNT_dec(sv);
7586d2
 	 sv = NULL;
7586d2
 	 /* else we try /tmp */
7586d2
-	 fd = Perl_my_mkostemp_cloexec(tempname, imode);
7586d2
+	 fd = Perl_my_mkostemp_cloexec(tempname, imode | O_VMS_DELETEONCLOSE);
7586d2
      }
7586d2
      if (fd < 0) {
7586d2
          /* Try cwd */
7586d2
          sv = newSVpvs(".");
7586d2
          sv_catpv(sv, tempname + 4);
7586d2
-         fd = Perl_my_mkostemp_cloexec(SvPVX(sv), imode);
7586d2
+         fd = Perl_my_mkostemp_cloexec(SvPVX(sv), imode | O_VMS_DELETEONCLOSE);
7586d2
      }
7586d2
      umask(old_umask);
7586d2
      if (fd >= 0) {
7586d2
@@ -5096,7 +5096,9 @@ PerlIO_tmpfile_flags(int imode)
7586d2
          f = PerlIO_fdopen(fd, mode);
7586d2
 	  if (f)
7586d2
 	       PerlIOBase(f)->flags |= PERLIO_F_TEMP;
7586d2
+#   ifndef VMS
7586d2
 	  PerlLIO_unlink(sv ? SvPVX_const(sv) : tempname);
7586d2
+#   endif
7586d2
      }
7586d2
      SvREFCNT_dec(sv);
7586d2
 #else	/* !HAS_MKSTEMP, fallback to stdio tmpfile(). */
7586d2
diff --git a/util.c b/util.c
7586d2
index e6863f6dfe..165d13a39e 100644
7586d2
--- a/util.c
7586d2
+++ b/util.c
7586d2
@@ -5712,6 +5712,11 @@ S_my_mkostemp(char *templte, int flags) {
7586d2
     STRLEN len = strlen(templte);
7586d2
     int fd;
7586d2
     int attempts = 0;
7586d2
+#ifdef VMS
7586d2
+    int delete_on_close = flags & O_VMS_DELETEONCLOSE;
7586d2
+
7586d2
+    flags &= ~O_VMS_DELETEONCLOSE;
7586d2
+#endif
7586d2
 
7586d2
     if (len < 6 ||
7586d2
         templte[len-1] != 'X' || templte[len-2] != 'X' || templte[len-3] != 'X' ||
7586d2
@@ -5725,7 +5730,15 @@ S_my_mkostemp(char *templte, int flags) {
7586d2
         for (i = 1; i <= 6; ++i) {
7586d2
             templte[len-i] = TEMP_FILE_CH[(int)(Perl_internal_drand48() * TEMP_FILE_CH_COUNT)];
7586d2
         }
7586d2
-        fd = PerlLIO_open3(templte, O_RDWR | O_CREAT | O_EXCL | flags, 0600);
7586d2
+#ifdef VMS
7586d2
+        if (delete_on_close) {
7586d2
+            fd = open(templte, O_RDWR | O_CREAT | O_EXCL | flags, 0600, "fop=dlt");
7586d2
+        }
7586d2
+        else
7586d2
+#endif
7586d2
+        {
7586d2
+            fd = PerlLIO_open3(templte, O_RDWR | O_CREAT | O_EXCL | flags, 0600);
7586d2
+        }
7586d2
     } while (fd == -1 && errno == EEXIST && ++attempts <= 100);
7586d2
 
7586d2
     return fd;
7586d2
diff --git a/util.h b/util.h
7586d2
index d8fa3e8396..d9df7b39c6 100644
7586d2
--- a/util.h
7586d2
+++ b/util.h
7586d2
@@ -248,6 +248,17 @@ means arg not present, 1 is empty string/null byte */
7586d2
 int mkstemp(char*);
7586d2
 #endif
7586d2
 
7586d2
+#ifdef PERL_CORE
7586d2
+#   if defined(VMS)
7586d2
+/* only useful for calls to our mkostemp() emulation */
7586d2
+#       define O_VMS_DELETEONCLOSE 0x40000000
7586d2
+#       ifdef HAS_MKOSTEMP
7586d2
+#           error 134221 will need a new solution for VMS
7586d2
+#       endif
7586d2
+#   else
7586d2
+#       define O_VMS_DELETEONCLOSE 0
7586d2
+#   endif
7586d2
+#endif
7586d2
 #if defined(HAS_MKOSTEMP) && defined(PERL_CORE)
7586d2
 #   define Perl_my_mkostemp(templte, flags) mkostemp(templte, flags)
7586d2
 #endif
7586d2
-- 
7586d2
2.20.1
7586d2