This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.24-167-g85f7554


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  85f7554cd97e7f03d8dc66278653045ef63a2221 (commit)
      from  fc3e1337be1c6935ab58bd13520f97a535cf70cc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=85f7554cd97e7f03d8dc66278653045ef63a2221

commit 85f7554cd97e7f03d8dc66278653045ef63a2221
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Sep 21 15:24:01 2016 +0200

    Add test case for O_TMPFILE handling in open, openat
    
    Also put xasprintf into test-skeleton.c (written in such a way that
    including <stdarg.h> is not needed).

diff --git a/ChangeLog b/ChangeLog
index 12a217a..825d4f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2016-09-21  Florian Weimer  <fweimer@redhat.com>
 
+	* test-skeleton.c (xasprintf): Add function.
+	* io/tst-open-tmpfile.c: New test.
+	* io/Makefile (tests): Add it.
+
+2016-09-21  Florian Weimer  <fweimer@redhat.com>
+
 	Avoid running $(CXX) during build to obtain header file paths.
 	* configure.ac (CXX_SYSINCLUDES, CXX_CMATH_HEADER): Set.
 	* config.make.in (c++-cstdlib-header, c++-cmath-header): Define.
diff --git a/io/Makefile b/io/Makefile
index deb6100..f5977af 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -71,7 +71,8 @@ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
 		   tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
 		   tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
 		   tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
-		   tst-posix_fallocate tst-fts tst-fts-lfs
+		   tst-posix_fallocate tst-fts tst-fts-lfs \
+		   tst-open-tmpfile
 
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)ftwtest.out
diff --git a/io/tst-open-tmpfile.c b/io/tst-open-tmpfile.c
new file mode 100644
index 0000000..9af1875
--- /dev/null
+++ b/io/tst-open-tmpfile.c
@@ -0,0 +1,216 @@
+/* Test open and openat with O_TMPFILE.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This test verifies that open and openat work as expected, i.e. they
+   create a deleted file with the requested file mode.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static int do_test (void);
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+#ifdef O_TMPFILE
+typedef int (*wrapper_func) (const char *, int, mode_t);
+
+/* Error-checking wrapper for the open function, compatible with the
+   wrapper_func type.  */
+static int
+wrap_open (const char *path, int flags, mode_t mode)
+{
+  int ret = open (path, flags, mode);
+  if (ret < 0)
+    {
+      printf ("error: open (\"%s\", 0x%x, 0%03o): %m\n", path, flags, mode);
+      exit (1);
+    }
+  return ret;
+}
+
+/* Error-checking wrapper for the openat function, compatible with the
+   wrapper_func type.  */
+static int
+wrap_openat (const char *path, int flags, mode_t mode)
+{
+  int ret = openat (AT_FDCWD, path, flags, mode);
+  if (ret < 0)
+    {
+      printf ("error: openat (\"%s\", 0x%x, 0%03o): %m\n", path, flags, mode);
+      exit (1);
+    }
+  return ret;
+}
+
+/* Return true if FD is flagged as deleted in /proc/self/fd, false if
+   not.  */
+static bool
+is_file_deteted (int fd)
+{
+  char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd);
+  char file_path[4096];
+  ssize_t file_path_length
+    = readlink (proc_fd_path, file_path, sizeof (file_path));
+  if (file_path_length < 0)
+    {
+      printf ("error: readlink (\"%s\"): %m", proc_fd_path);
+      free (proc_fd_path);
+      exit (1);
+    }
+  free (proc_fd_path);
+  if (file_path_length == sizeof (file_path))
+    {
+      printf ("error: path in /proc resolves to overlong file name: %.*s\n",
+              (int) file_path_length, file_path);
+      exit (1);
+    }
+  const char *deleted = " (deleted)";
+  if (file_path_length < strlen (deleted))
+    {
+      printf ("error: path in /proc is too short: %.*s\n",
+              (int) file_path_length, file_path);
+      exit (1);
+    }
+  return memcmp (file_path + file_path_length - strlen (deleted),
+              deleted, strlen (deleted)) == 0;
+}
+
+/* Check open/openat (as specified by OP and WRAPPER) with a specific
+   PATH/FLAGS/MODE combination.  */
+static void
+check_wrapper_flags_mode (const char *op, wrapper_func wrapper,
+                          const char *path, int flags, mode_t mode)
+{
+  int fd = wrapper (path, flags | O_TMPFILE, mode);
+  struct stat64 st;
+  if (fstat64 (fd, &st) != 0)
+    {
+      printf ("error: fstat64: %m\n");
+      exit (1);
+    }
+
+  /* Verify that the mode was correctly processed.  */
+  int actual_mode = st.st_mode & 0777;
+  if (actual_mode != mode)
+    {
+      printf ("error: unexpected mode; expected 0%03o, actual 0%03o\n",
+              mode, actual_mode);
+      exit (1);
+    }
+
+  /* Check that the file is marked as deleted in /proc.  */
+  if (!is_file_deteted (fd))
+    {
+      printf ("error: path in /proc is not marked as deleted\n");
+      exit (1);
+    }
+
+  close (fd);
+}
+
+/* Check OP/WRAPPER with various flags at a specific PATH and
+   MODE.  */
+static void
+check_wrapper_mode (const char *op, wrapper_func wrapper,
+                    const char *path, mode_t mode)
+{
+  check_wrapper_flags_mode (op, wrapper, path, O_WRONLY, mode);
+  check_wrapper_flags_mode (op, wrapper, path, O_WRONLY | O_EXCL, mode);
+  check_wrapper_flags_mode (op, wrapper, path, O_RDWR, mode);
+  check_wrapper_flags_mode (op, wrapper, path, O_RDWR | O_EXCL, mode);
+}
+
+/* Check open/openat with varying permissions.  */
+static void
+check_wrapper (const char *op, wrapper_func wrapper,
+                    const char *path)
+{
+  printf ("info: testing %s at: %s\n", op, path);
+  check_wrapper_mode (op, wrapper, path, 0);
+  check_wrapper_mode (op, wrapper, path, 0640);
+  check_wrapper_mode (op, wrapper, path, 0600);
+  check_wrapper_mode (op, wrapper, path, 0755);
+  check_wrapper_mode (op, wrapper, path, 0750);
+}
+
+/* Verify that the directory at PATH supports O_TMPFILE.  Exit with
+   status 77 (unsupported) if the kernel does not support O_TMPFILE.
+   Even with kernel support, not all file systems O_TMPFILE, so return
+   true if the directory supports O_TMPFILE, false if not.  */
+static bool
+probe_path (const char *path)
+{
+  int fd = openat (AT_FDCWD, path, O_TMPFILE | O_RDWR, 0);
+  if (fd < 0)
+    {
+      if (errno == EISDIR)
+        /* The system does not support O_TMPFILE.  */
+        {
+          printf ("info: kernel does not support O_TMPFILE\n");
+          exit (77);
+        }
+      if (errno == EOPNOTSUPP)
+        {
+          printf ("info: path does not support O_TMPFILE: %s\n", path);
+          return false;
+        }
+      printf ("error: openat (\"%s\", O_TMPFILE | O_RDWR): %m\n", path);
+      exit (1);
+    }
+  close (fd);
+  return true;
+}
+
+static int
+do_test (void)
+{
+  umask (0);
+  const char *paths[] = { ".", "/dev/shm", "/tmp",
+                          getenv ("TEST_TMPFILE_PATH"),
+                          NULL };
+  bool supported = false;
+  for (int i = 0; paths[i] != NULL; ++i)
+    if (probe_path (paths[i]))
+      {
+        supported = true;
+        check_wrapper ("open", wrap_open, paths[i]);
+        check_wrapper ("openat", wrap_openat, paths[i]);
+      }
+
+  if (!supported)
+    return 77;
+
+  return 0;
+}
+
+#else  /* !O_TMPFILE */
+
+static int
+do_test (void)
+{
+  return 77;
+}
+
+#endif  /* O_TMPFILE */
diff --git a/test-skeleton.c b/test-skeleton.c
index 913a335..65a3818 100644
--- a/test-skeleton.c
+++ b/test-skeleton.c
@@ -33,6 +33,7 @@
 #include <sys/wait.h>
 #include <sys/param.h>
 #include <time.h>
+#include <stdarg.h>
 
 /* The test function is normally called `do_test' and it is called
    with argc and argv as the arguments.  We nevertheless provide the
@@ -115,6 +116,20 @@ xrealloc (void *p, size_t n)
   return result;
 }
 
+/* Call asprintf with error checking.  */
+__attribute__ ((always_inline, format (printf, 1, 2)))
+static __inline__ char *
+xasprintf (const char *format, ...)
+{
+  char *result;
+  if (asprintf (&result, format, __builtin_va_arg_pack ()) < 0)
+    {
+      printf ("error: asprintf: %m\n");
+      exit (1);
+    }
+  return result;
+}
+
 /* Write a message to standard output.  Can be used in signal
    handlers.  */
 static void

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog             |    6 ++
 io/Makefile           |    3 +-
 io/tst-open-tmpfile.c |  216 +++++++++++++++++++++++++++++++++++++++++++++++++
 test-skeleton.c       |   15 ++++
 4 files changed, 239 insertions(+), 1 deletions(-)
 create mode 100644 io/tst-open-tmpfile.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]