fdio: allow NULL for fstatat_allow_noent stbuf
authorJonathan Lebon <jlebon@redhat.com>
Fri, 6 Oct 2017 21:26:41 +0000 (21:26 +0000)
committerSimon McVittie <smcv@debian.org>
Thu, 26 Oct 2017 23:19:45 +0000 (00:19 +0100)
Often, the caller doesn't actually care about the details of the stat
struct itself, but just whether the entry exists or not. It does work
to just pass `NULL` directly to glibc in a quick test, but given that
the argument is tagged as `__nonnull` and that the documentation does
not explicitly specify this is supported, let's do this safely.

Origin: upstream (submodule libglnx), 2017.13, commit:5362f6bc3ff3e30f379e767b203d15c9e56d6f08

Gbp-Pq: Topic 2017.13
Gbp-Pq: Name fdio-allow-NULL-for-fstatat_allow_noent-stbuf.patch

libglnx/glnx-fdio.h
libglnx/tests/test-libglnx-fdio.c

index 518135c51c9f9550706dff7d1365e4a1552e1355..1aa0c434657312f12d308b89003e0dcdd110e8a0 100644 (file)
@@ -299,7 +299,7 @@ glnx_fstatat (int           dfd,
  * glnx_fstatat_allow_noent:
  * @dfd: Directory FD to stat beneath
  * @path: Path to stat beneath @dfd
- * @buf: (out caller-allocates): Return location for stat details
+ * @buf: (out caller-allocates) (allow-none): Return location for stat details
  * @flags: Flags to pass to fstatat()
  * @error: Return location for a #GError, or %NULL
  *
@@ -318,7 +318,8 @@ glnx_fstatat_allow_noent (int               dfd,
                           int               flags,
                           GError          **error)
 {
-  if (TEMP_FAILURE_RETRY (fstatat (dfd, path, out_buf, flags)) != 0)
+  struct stat stbuf;
+  if (TEMP_FAILURE_RETRY (fstatat (dfd, path, out_buf ?: &stbuf, flags)) != 0)
     {
       if (errno != ENOENT)
         {
index bf973b9a9a4a41bf17a4fa3d1c3cce6ef81c9f54..350294c4b603b2fd71aac3ec0ddf6f6f4d673afb 100644 (file)
@@ -161,6 +161,16 @@ test_fstatat (void)
     return;
   g_assert_cmpint (errno, ==, ENOENT);
   g_assert_no_error (local_error);
+
+  /* test NULL parameter for stat */
+  if (!glnx_fstatat_allow_noent (AT_FDCWD, ".", NULL, 0, error))
+    return;
+  g_assert_cmpint (errno, ==, 0);
+  g_assert_no_error (local_error);
+  if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchfile", NULL, 0, error))
+    return;
+  g_assert_cmpint (errno, ==, ENOENT);
+  g_assert_no_error (local_error);
 }
 
 static void