>From f530e59fd363722a7a4fa9fd60b2da2241c1a9fc Mon Sep 17 00:00:00 2001
From: Yclept Nemo <pscjtwjdjtAhnbjm/dpn>
Date: Wed, 20 May 2015 23:18:15 -0400
Subject: [PATCH] Workaround: open() ignores 'mode' with O_TMPFILE
---
configure.ac | 51
++++++++++++++++++++++++++++++++++++++++++
src/fs/io/FileOutputStream.cxx | 8 ++-----
src/system/FileDescriptor.cxx | 4 ++++
src/system/FileDescriptor.hxx | 9 ++++++++
4 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index 82f814d..ed76f51 100644
--- a/configure.ac
+++ b/configure.ac
@@ -561,6 +561,57 @@ if test x$enable_largefile != xno; then
fi
dnl
---------------------------------------------------------------------------
+dnl LIBC Workarounds
+dnl
---------------------------------------------------------------------------
+if test "x$host_is_linux" = xyes && test "x$ac_cv_func_linkat" = xyes &&
test "x$enable_largefile" != xno; then
+ AC_MSG_CHECKING( [if O_TMPFILE requires fchmod])
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#define _FILE_OFFSET_BITS 64
+ #include <fcntl.h>
+ #include <limits.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ ]]
+ , [[struct stat statbuf;
+ int fd;
+ int mode = 0666;
+ if ((fd = open(".", O_TMPFILE|O_WRONLY, mode)) < 0)
+ return 1;
+ if (fstat(fd, &statbuf) < 0)
+ return 1;
+ if (close(fd) < 0)
+ return 1;
+ if ((statbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode)
+ return 1;
+ return 0;
+ ]]
+ )
+ ]
+ , open_tmpfile_fchmod=no
+ , open_tmpfile_fchmod=yes
+ , open_tmpfile_fchmod=yes
+ )
+ if test "x$open_tmpfile_fchmod" = xyes; then
+ AC_MSG_RESULT([yes])
+ AC_CHECK_FUNCS(
+ [fchmod]
+ , [ AC_DEFINE([OPEN_TMPFILE_FCHMOD],
+ [1],
+ [Workaround: _LARGE_FILE + O_TMPFILE -> mode ==
0])
+ AC_MSG_NOTICE([Enabling open/tmpfile workaround using
fchmod])
+ ]
+ , [ AC_DEFINE([HAVE_LINKAT],
+ [0])
+ AC_MSG_NOTICE([Disabling linkat support])
+ ]
+ )
+ else
+ AC_MSG_RESULT([no])
+ fi
+fi
+
+dnl
---------------------------------------------------------------------------
dnl Miscellaneous Libraries
dnl
---------------------------------------------------------------------------
diff --git a/src/fs/io/FileOutputStream.cxx b/src/fs/io/FileOutputStream.cxx
index a4ef8f6..6451b8c 100644
--- a/src/fs/io/FileOutputStream.cxx
+++ b/src/fs/io/FileOutputStream.cxx
@@ -106,13 +106,10 @@ FileOutputStream::Cancel()
#include <errno.h>
#ifdef HAVE_LINKAT
-#ifndef O_TMPFILE
-/* supported since Linux 3.11 */
-#define __O_TMPFILE 020000000
-#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
#include <stdio.h>
#endif
+#ifdef HAVE_LINKAT
/**
* Open a file using Linux's O_TMPFILE for writing the given file.
*/
@@ -125,8 +122,7 @@ OpenTempFile(FileDescriptor &fd, Path path)
return fd.Open(directory.c_str(), O_TMPFILE|O_WRONLY, 0666);
}
-
-#endif /* HAVE_LINKAT */
+#endif
FileOutputStream::FileOutputStream(Path _path, Error &error)
:BaseFileOutputStream(_path)
diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx
index db258e1..f30c9c2 100644
--- a/src/system/FileDescriptor.cxx
+++ b/src/system/FileDescriptor.cxx
@@ -61,6 +61,10 @@ bool
FileDescriptor::Open(const char *pathname, int flags, mode_t mode)
{
fd = ::open(pathname, flags | O_NOCTTY | O_CLOEXEC, mode);
+#ifdef OPEN_TMPFILE_FCHMOD
+ if ((flags & O_TMPFILE) && IsDefined())
+ fchmod(fd, mode);
+#endif
return IsDefined();
}
diff --git a/src/system/FileDescriptor.hxx b/src/system/FileDescriptor.hxx
index 75a7684..43cb857 100644
--- a/src/system/FileDescriptor.hxx
+++ b/src/system/FileDescriptor.hxx
@@ -36,11 +36,20 @@
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
+#include <fcntl.h>
#ifdef USE_SIGNALFD
#include <signal.h>
#endif
+#ifdef HAVE_LINKAT
+#ifndef O_TMPFILE
+/* supported since Linux 3.11 */
+#define __O_TMPFILE 020000000
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+#endif
+#endif
+
/**
* An OO wrapper for a UNIX file descriptor.
*
--
2.1.4
From f530e59fd363722a7a4fa9fd60b2da2241c1a9fc Mon Sep 17 00:00:00 2001
From: Yclept Nemo <pscjtwjdjtAhnbjm/dpn>
Date: Wed, 20 May 2015 23:18:15 -0400
Subject: [PATCH] Workaround: open() ignores 'mode' with O_TMPFILE
---
configure.ac | 51 ++++++++++++++++++++++++++++++++++++++++++
src/fs/io/FileOutputStream.cxx | 8 ++-----
src/system/FileDescriptor.cxx | 4 ++++
src/system/FileDescriptor.hxx | 9 ++++++++
4 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index 82f814d..ed76f51 100644
--- a/configure.ac
+++ b/configure.ac
@@ -561,6 +561,57 @@ if test x$enable_largefile != xno; then
fi
dnl ---------------------------------------------------------------------------
+dnl LIBC Workarounds
+dnl ---------------------------------------------------------------------------
+if test "x$host_is_linux" = xyes && test "x$ac_cv_func_linkat" = xyes && test "x$enable_largefile" != xno; then
+ AC_MSG_CHECKING( [if O_TMPFILE requires fchmod])
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#define _FILE_OFFSET_BITS 64
+ #include <fcntl.h>
+ #include <limits.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ ]]
+ , [[struct stat statbuf;
+ int fd;
+ int mode = 0666;
+ if ((fd = open(".", O_TMPFILE|O_WRONLY, mode)) < 0)
+ return 1;
+ if (fstat(fd, &statbuf) < 0)
+ return 1;
+ if (close(fd) < 0)
+ return 1;
+ if ((statbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode)
+ return 1;
+ return 0;
+ ]]
+ )
+ ]
+ , open_tmpfile_fchmod=no
+ , open_tmpfile_fchmod=yes
+ , open_tmpfile_fchmod=yes
+ )
+ if test "x$open_tmpfile_fchmod" = xyes; then
+ AC_MSG_RESULT([yes])
+ AC_CHECK_FUNCS(
+ [fchmod]
+ , [ AC_DEFINE([OPEN_TMPFILE_FCHMOD],
+ [1],
+ [Workaround: _LARGE_FILE + O_TMPFILE -> mode == 0])
+ AC_MSG_NOTICE([Enabling open/tmpfile workaround using fchmod])
+ ]
+ , [ AC_DEFINE([HAVE_LINKAT],
+ [0])
+ AC_MSG_NOTICE([Disabling linkat support])
+ ]
+ )
+ else
+ AC_MSG_RESULT([no])
+ fi
+fi
+
+dnl ---------------------------------------------------------------------------
dnl Miscellaneous Libraries
dnl ---------------------------------------------------------------------------
diff --git a/src/fs/io/FileOutputStream.cxx b/src/fs/io/FileOutputStream.cxx
index a4ef8f6..6451b8c 100644
--- a/src/fs/io/FileOutputStream.cxx
+++ b/src/fs/io/FileOutputStream.cxx
@@ -106,13 +106,10 @@ FileOutputStream::Cancel()
#include <errno.h>
#ifdef HAVE_LINKAT
-#ifndef O_TMPFILE
-/* supported since Linux 3.11 */
-#define __O_TMPFILE 020000000
-#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
#include <stdio.h>
#endif
+#ifdef HAVE_LINKAT
/**
* Open a file using Linux's O_TMPFILE for writing the given file.
*/
@@ -125,8 +122,7 @@ OpenTempFile(FileDescriptor &fd, Path path)
return fd.Open(directory.c_str(), O_TMPFILE|O_WRONLY, 0666);
}
-
-#endif /* HAVE_LINKAT */
+#endif
FileOutputStream::FileOutputStream(Path _path, Error &error)
:BaseFileOutputStream(_path)
diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx
index db258e1..f30c9c2 100644
--- a/src/system/FileDescriptor.cxx
+++ b/src/system/FileDescriptor.cxx
@@ -61,6 +61,10 @@ bool
FileDescriptor::Open(const char *pathname, int flags, mode_t mode)
{
fd = ::open(pathname, flags | O_NOCTTY | O_CLOEXEC, mode);
+#ifdef OPEN_TMPFILE_FCHMOD
+ if ((flags & O_TMPFILE) && IsDefined())
+ fchmod(fd, mode);
+#endif
return IsDefined();
}
diff --git a/src/system/FileDescriptor.hxx b/src/system/FileDescriptor.hxx
index 75a7684..43cb857 100644
--- a/src/system/FileDescriptor.hxx
+++ b/src/system/FileDescriptor.hxx
@@ -36,11 +36,20 @@
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
+#include <fcntl.h>
#ifdef USE_SIGNALFD
#include <signal.h>
#endif
+#ifdef HAVE_LINKAT
+#ifndef O_TMPFILE
+/* supported since Linux 3.11 */
+#define __O_TMPFILE 020000000
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+#endif
+#endif
+
/**
* An OO wrapper for a UNIX file descriptor.
*
--
2.1.4
_______________________________________________
mpd-devel mailing list
[email protected]
http://mailman.blarg.de/listinfo/mpd-devel