bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fts: slightly more robust


From: Jim Meyering
Subject: fts: slightly more robust
Date: Tue, 01 Sep 2009 11:43:06 +0200

I suspect that it'd be very hard to trigger these close failures,
but it's better to be safe.

And along the same lines, since there are more way in which fts_close
can fail, encourage callers not to ignore its return value.
There were four offenders in coreutils, before today.

I chose not to make it hard to ignore fts_set, since
for many uses, its return value is legitimately ignorable.


>From d7702d8443dae6073597f2cc4fa49f85dfeaaed2 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 1 Sep 2009 11:18:07 +0200
Subject: [PATCH 1/2] fts: fts_close now fails also when closing a dir file 
descriptor fails

* lib/fts.c (fts_close): Detect close failure, not just fchdir failure,
and propagate to caller, along with errno.
---
 ChangeLog |    4 ++++
 lib/fts.c |   10 ++++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5ff10df..89cf0ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2009-09-01  Jim Meyering  <address@hidden>

+       fts: fts_close now fails also when closing a dir file descriptor fails
+       * lib/fts.c (fts_close): Detect close failure, not just fchdir failure,
+       and propagate to caller, along with errno.
+
        announce-gen: correct formatting in --help output
        * build-aux/announce-gen (usage): Move the one-line description in
        --help output "up", to where it belongs, just after Usage:.
diff --git a/lib/fts.c b/lib/fts.c
index bbcd1ff..a30e38a 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -606,14 +606,20 @@ fts_close (FTS *sp)
        if (ISSET(FTS_CWDFD))
          {
            if (0 <= sp->fts_cwd_fd)
-             close (sp->fts_cwd_fd);
+             if (close (sp->fts_cwd_fd))
+               saved_errno = errno;
          }
        else if (!ISSET(FTS_NOCHDIR))
          {
            /* Return to original directory, save errno if necessary. */
            if (fchdir(sp->fts_rfd))
              saved_errno = errno;
-           close(sp->fts_rfd);
+
+           /* If close fails, record errno only if saved_errno is zero,
+              so that we report the probably-more-meaningful fchdir errno.  */
+           if (close (sp->fts_rfd))
+             if (saved_errno == 0)
+               saved_errno = errno;
          }

        fd_ring_clear (&sp->fts_fd_ring);
--
1.6.4.2.384.g5fc62


>From 9b740ea4bcb104eeceb0c847a376d2b7dbb77d1b Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 1 Sep 2009 11:20:41 +0200
Subject: [PATCH 2/2] fts: help ensure that return values are not ignored

* lib/fts_.h (__GNUC_PREREQ): Define.
(__attribute_warn_unused_result__): Define.
(fts_children, fts_close, fts_open, fts_read): Declare with
__attribute_warn_unused_result__.
---
 ChangeLog  |    6 ++++++
 lib/fts_.h |   26 ++++++++++++++++++++++----
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 89cf0ee..efb2906 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2009-09-01  Jim Meyering  <address@hidden>

+       fts: help ensure that return values are not ignored
+       * lib/fts_.h (__GNUC_PREREQ): Define.
+       (__attribute_warn_unused_result__): Define.
+       (fts_children, fts_close, fts_open, fts_read): Declare with
+       __attribute_warn_unused_result__.
+
        fts: fts_close now fails also when closing a dir file descriptor fails
        * lib/fts.c (fts_close): Detect close failure, not just fchdir failure,
        and propagate to caller, along with errno.
diff --git a/lib/fts_.h b/lib/fts_.h
index ad339ca..0e2d505 100644
--- a/lib/fts_.h
+++ b/lib/fts_.h
@@ -233,12 +233,30 @@ typedef struct _ftsent {
        char fts_name[1];               /* file name */
 } FTSENT;

+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#if __GNUC_PREREQ (3,4)
+# undef __attribute_warn_unused_result__
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+
 __BEGIN_DECLS
-FTSENT *fts_children (FTS *, int) __THROW;
-int     fts_close (FTS *) __THROW;
+FTSENT *fts_children (FTS *, int) __THROW __attribute_warn_unused_result__;
+int     fts_close (FTS *) __THROW __attribute_warn_unused_result__;
 FTS    *fts_open (char * const *, int,
-                  int (*)(const FTSENT **, const FTSENT **)) __THROW;
-FTSENT *fts_read (FTS *) __THROW;
+                  int (*)(const FTSENT **, const FTSENT **))
+  __THROW __attribute_warn_unused_result__;
+FTSENT *fts_read (FTS *) __THROW __attribute_warn_unused_result__;
 int     fts_set (FTS *, FTSENT *, int) __THROW;
 __END_DECLS

--
1.6.4.2.384.g5fc62




reply via email to

[Prev in Thread] Current Thread [Next in Thread]