Blame SOURCES/perl-5.30.0-perl-134221-support-append-mode-for-open-.-undef.patch

7586d2
From 8e9cf86aa69cb79c91edf5ff0586f87bfe4c91bd Mon Sep 17 00:00:00 2001
7586d2
From: Tony Cook <tony@develop-help.com>
7586d2
Date: Tue, 2 Jul 2019 14:16:35 +1000
7586d2
Subject: [PATCH] (perl #134221) support append mode for open .. undef
7586d2
MIME-Version: 1.0
7586d2
Content-Type: text/plain; charset=UTF-8
7586d2
Content-Transfer-Encoding: 8bit
7586d2
7586d2
Petr Písař: Ported to 5.30.0 from
7586d2
45b29440d38be155c5177c8d6f9a5d4e7c2c098c.
7586d2
7586d2
Signed-off-by: Petr Písař <ppisar@redhat.com>
7586d2
---
7586d2
 doio.c             | 15 +++++++++++++++
7586d2
 embed.fnc          |  1 +
7586d2
 perlio.c           | 26 +++++++++++++++++++++-----
7586d2
 perlio.h           |  3 +++
7586d2
 proto.h            |  5 +++++
7586d2
 t/io/perlio_open.t | 14 ++++++++++++--
7586d2
 6 files changed, 57 insertions(+), 7 deletions(-)
7586d2
7586d2
diff --git a/doio.c b/doio.c
7586d2
index 05a0696..424e0e3 100644
7586d2
--- a/doio.c
7586d2
+++ b/doio.c
7586d2
@@ -265,6 +265,21 @@ Perl_my_mkstemp_cloexec(char *templte)
7586d2
 #endif
7586d2
 }
7586d2
 
7586d2
+int
7586d2
+Perl_my_mkostemp_cloexec(char *templte, int flags)
7586d2
+{
7586d2
+    dVAR;
7586d2
+    PERL_ARGS_ASSERT_MY_MKOSTEMP_CLOEXEC;
7586d2
+#if defined(O_CLOEXEC)
7586d2
+    DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
7586d2
+        PL_strategy_mkstemp,
7586d2
+	Perl_my_mkostemp(templte, flags | O_CLOEXEC),
7586d2
+	Perl_my_mkostemp(templte, flags));
7586d2
+#else
7586d2
+    DO_ONEOPEN_THEN_CLOEXEC(Perl_my_mkostemp(templte, flags));
7586d2
+#endif
7586d2
+}
7586d2
+
7586d2
 #ifdef HAS_PIPE
7586d2
 int
7586d2
 Perl_PerlProc_pipe_cloexec(pTHX_ int *pipefd)
7586d2
diff --git a/embed.fnc b/embed.fnc
7586d2
index 259affd..c977d39 100644
7586d2
--- a/embed.fnc
7586d2
+++ b/embed.fnc
7586d2
@@ -476,6 +476,7 @@ p	|int	|PerlLIO_dup2_cloexec|int oldfd|int newfd
7586d2
 pR	|int	|PerlLIO_open_cloexec|NN const char *file|int flag
7586d2
 pR	|int	|PerlLIO_open3_cloexec|NN const char *file|int flag|int perm
7586d2
 pnoR	|int	|my_mkstemp_cloexec|NN char *templte
7586d2
+pnoR	|int	|my_mkostemp_cloexec|NN char *templte|int flags
7586d2
 #ifdef HAS_PIPE
7586d2
 pR	|int	|PerlProc_pipe_cloexec|NN int *pipefd
7586d2
 #endif
7586d2
diff --git a/perlio.c b/perlio.c
7586d2
index 904d47a..5a0cd36 100644
7586d2
--- a/perlio.c
7586d2
+++ b/perlio.c
7586d2
@@ -1490,7 +1490,9 @@ PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
7586d2
 	     int imode, int perm, PerlIO *f, int narg, SV **args)
7586d2
 {
7586d2
     if (!f && narg == 1 && *args == &PL_sv_undef) {
7586d2
-	if ((f = PerlIO_tmpfile())) {
7586d2
+        int imode = PerlIOUnix_oflags(mode);
7586d2
+
7586d2
+	if (imode != -1 && (f = PerlIO_tmpfile_flags(imode))) {
7586d2
 	    if (!layers || !*layers)
7586d2
 		layers = Perl_PerlIO_context_layers(aTHX_ mode);
7586d2
 	    if (layers && *layers)
7586d2
@@ -5048,6 +5050,15 @@ PerlIO_stdoutf(const char *fmt, ...)
7586d2
 #undef PerlIO_tmpfile
7586d2
 PerlIO *
7586d2
 PerlIO_tmpfile(void)
7586d2
+{
7586d2
+    return PerlIO_tmpfile_flags(0);
7586d2
+}
7586d2
+
7586d2
+#define MKOSTEMP_MODES ( O_RDWR | O_CREAT | O_EXCL )
7586d2
+#define MKOSTEMP_MODE_MASK ( O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC )
7586d2
+
7586d2
+PerlIO *
7586d2
+PerlIO_tmpfile_flags(int imode)
7586d2
 {
7586d2
 #ifndef WIN32
7586d2
      dTHX;
7586d2
@@ -5063,27 +5074,32 @@ PerlIO_tmpfile(void)
7586d2
      const char * const tmpdir = TAINTING_get ? NULL : PerlEnv_getenv("TMPDIR");
7586d2
      SV * sv = NULL;
7586d2
      int old_umask = umask(0177);
7586d2
+     imode &= ~MKOSTEMP_MODE_MASK;
7586d2
      if (tmpdir && *tmpdir) {
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_mkstemp_cloexec(SvPVX(sv));
7586d2
+	 fd = Perl_my_mkostemp_cloexec(SvPVX(sv), imode);
7586d2
      }
7586d2
      if (fd < 0) {
7586d2
 	 SvREFCNT_dec(sv);
7586d2
 	 sv = NULL;
7586d2
 	 /* else we try /tmp */
7586d2
-	 fd = Perl_my_mkstemp_cloexec(tempname);
7586d2
+	 fd = Perl_my_mkostemp_cloexec(tempname, imode);
7586d2
      }
7586d2
      if (fd < 0) {
7586d2
          /* Try cwd */
7586d2
          sv = newSVpvs(".");
7586d2
          sv_catpv(sv, tempname + 4);
7586d2
-         fd = Perl_my_mkstemp_cloexec(SvPVX(sv));
7586d2
+         fd = Perl_my_mkostemp_cloexec(SvPVX(sv), imode);
7586d2
      }
7586d2
      umask(old_umask);
7586d2
      if (fd >= 0) {
7586d2
-	  f = PerlIO_fdopen(fd, "w+");
7586d2
+         /* fdopen() with a numeric mode */
7586d2
+         char mode[8];
7586d2
+         int writing = 1;
7586d2
+         (void)PerlIO_intmode2str(imode | MKOSTEMP_MODES, mode, &writing);
7586d2
+         f = PerlIO_fdopen(fd, mode);
7586d2
 	  if (f)
7586d2
 	       PerlIOBase(f)->flags |= PERLIO_F_TEMP;
7586d2
 	  PerlLIO_unlink(sv ? SvPVX_const(sv) : tempname);
7586d2
diff --git a/perlio.h b/perlio.h
7586d2
index d515020..ee16ab8 100644
7586d2
--- a/perlio.h
7586d2
+++ b/perlio.h
7586d2
@@ -286,6 +286,9 @@ PERL_CALLCONV SSize_t PerlIO_get_bufsiz(PerlIO *);
7586d2
 #ifndef PerlIO_tmpfile
7586d2
 PERL_CALLCONV PerlIO *PerlIO_tmpfile(void);
7586d2
 #endif
7586d2
+#ifndef PerlIO_tmpfile_flags
7586d2
+PERL_CALLCONV PerlIO *PerlIO_tmpfile_flags(int flags);
7586d2
+#endif
7586d2
 #ifndef PerlIO_stdin
7586d2
 PERL_CALLCONV PerlIO *PerlIO_stdin(void);
7586d2
 #endif
7586d2
diff --git a/proto.h b/proto.h
7586d2
index 74a8e46..e0ea55b 100644
7586d2
--- a/proto.h
7586d2
+++ b/proto.h
7586d2
@@ -2270,6 +2270,11 @@ PERL_CALLCONV Pid_t	Perl_my_fork(void);
7586d2
 PERL_CALLCONV I32	Perl_my_lstat(pTHX);
7586d2
 #endif
7586d2
 PERL_CALLCONV I32	Perl_my_lstat_flags(pTHX_ const U32 flags);
7586d2
+PERL_CALLCONV int	Perl_my_mkostemp_cloexec(char *templte, int flags)
7586d2
+			__attribute__warn_unused_result__;
7586d2
+#define PERL_ARGS_ASSERT_MY_MKOSTEMP_CLOEXEC	\
7586d2
+	assert(templte)
7586d2
+
7586d2
 PERL_CALLCONV int	Perl_my_mkstemp_cloexec(char *templte)
7586d2
 			__attribute__warn_unused_result__;
7586d2
 #define PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC	\
7586d2
diff --git a/t/io/perlio_open.t b/t/io/perlio_open.t
7586d2
index 99d7e51..56c354b 100644
7586d2
--- a/t/io/perlio_open.t
7586d2
+++ b/t/io/perlio_open.t
7586d2
@@ -11,7 +11,7 @@ BEGIN {
7586d2
 use strict;
7586d2
 use warnings;
7586d2
 
7586d2
-plan tests => 6;
7586d2
+plan tests => 10;
7586d2
 
7586d2
 use Fcntl qw(:seek);
7586d2
 
7586d2
@@ -31,6 +31,16 @@ use Fcntl qw(:seek);
7586d2
     is($data, "the right read stuff", "found the right stuff");
7586d2
 }
7586d2
 
7586d2
-
7586d2
+SKIP:
7586d2
+{
7586d2
+    ok((open my $fh, "+>>", undef), "open my \$fh, '+>>', undef")
7586d2
+      or skip "can't open temp for append: $!", 3;
7586d2
+    print $fh "abc";
7586d2
+    ok(seek($fh, 0, SEEK_SET), "seek to zero");
7586d2
+    print $fh "xyz";
7586d2
+    ok(seek($fh, 0, SEEK_SET), "seek to zero again");
7586d2
+    my $data = <$fh>;
7586d2
+    is($data, "abcxyz", "check the second write appended");
7586d2
+}
7586d2
 
7586d2
 
7586d2
-- 
7586d2
2.20.1
7586d2