+2022-12-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ fts: make debug version compilable again
+ This fixes things in what I hope is a better way than the
+ fd-only approach proposed by Kamil Dudka here:
+ https://lists.gnu.org/archive/html/bug-gnulib/2018-03/msg00079.html
+ https://lists.gnu.org/archive/html/bug-gnulib/2018-03/msg00080.html
+ * lib/fts.c (GNULIB_FTS_DEBUG): Rename from FTS_DEBUG,
+ to avoid collision with coreutils symbol.
+ Do not include <stdint.h> (not needed, since we include <stdint.h>)
+ or "getcwdat.h" (no longer exists).
+ (fd_ring_check, fd_ring_print): Add forward decls.
+ (struct devino): New type.
+ (PRINT_DEVINO): New macro.
+ (getdevino): New static function.
+ (fd_ring_print): Do nothing if not debugging.
+ (fd_ring_print, fd_ring_check): Use getdevino instead of getcwdat.
+ The output isn’t as good, but at least it compiles and runs.
+
2022-12-07 Paul Eggert <eggert@cs.ucla.edu>
verify: update __STDC_VERSION__ as per C23
#define BNAMES 2 /* fts_children, names only */
#define BREAD 3 /* fts_read */
-#if FTS_DEBUG
+#if GNULIB_FTS_DEBUG
# include <inttypes.h>
-# include <stdint.h>
# include <stdio.h>
-# include "getcwdat.h"
bool fts_debug = false;
# define Dprintf(x) do { if (fts_debug) printf x; } while (false)
+static void fd_ring_check (FTS const *);
+static void fd_ring_print (FTS const *, FILE *, char const *);
#else
# define Dprintf(x)
# define fd_ring_check(x)
return (head);
}
-#if FTS_DEBUG
+#if GNULIB_FTS_DEBUG
+
+struct devino {
+ intmax_t dev, ino;
+};
+#define PRINT_DEVINO "(%jd,%jd)"
+
+static struct devino
+getdevino (int fd)
+{
+ struct stat st;
+ return (fd == AT_FDCWD
+ ? (struct devino) { -1, 0 }
+ : fstat (fd, &st) == 0
+ ? (struct devino) { st.st_dev, st.st_ino }
+ : (struct devino) { -1, errno });
+}
/* Walk ->fts_parent links starting at E_CURR, until the root of the
current hierarchy. There should be a directory with dev/inode
static void
fd_ring_print (FTS const *sp, FILE *stream, char const *msg)
{
+ if (!fts_debug)
+ return;
I_ring const *fd_ring = &sp->fts_fd_ring;
- unsigned int i = fd_ring->fts_front;
- char *cwd = getcwdat (sp->fts_cwd_fd, NULL, 0);
- fprintf (stream, "=== %s ========== %s\n", msg, cwd);
- free (cwd);
+ unsigned int i = fd_ring->ir_front;
+ struct devino cwd = getdevino (sp->fts_cwd_fd);
+ fprintf (stream, "=== %s ========== "PRINT_DEVINO"\n", msg, cwd.dev, cwd.ino);
if (i_ring_empty (fd_ring))
return;
while (true)
{
- int fd = fd_ring->fts_fd_ring[i];
+ int fd = fd_ring->ir_data[i];
if (fd < 0)
fprintf (stream, "%d: %d:\n", i, fd);
else
{
- char *wd = getcwdat (fd, NULL, 0);
- fprintf (stream, "%d: %d: %s\n", i, fd, wd);
- free (wd);
+ struct devino wd = getdevino (fd);
+ fprintf (stream, "%d: %d: "PRINT_DEVINO"\n", i, fd, wd.dev, wd.ino);
}
- if (i == fd_ring->fts_back)
+ if (i == fd_ring->ir_back)
break;
i = (i + I_RING_SIZE - 1) % I_RING_SIZE;
}
int cwd_fd = sp->fts_cwd_fd;
cwd_fd = fcntl (cwd_fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1);
- char *dot = getcwdat (cwd_fd, NULL, 0);
- error (0, 0, "===== check ===== cwd: %s", dot);
- free (dot);
+ struct devino dot = getdevino (cwd_fd);
+ fprintf (stderr, "===== check ===== cwd: "PRINT_DEVINO"\n",
+ dot.dev, dot.ino);
while ( ! i_ring_empty (&fd_w))
{
int fd = i_ring_pop (&fd_w);
}
if (!same_fd (fd, parent_fd))
{
- char *cwd = getcwdat (fd, NULL, 0);
- error (0, errno, "ring : %s", cwd);
- char *c2 = getcwdat (parent_fd, NULL, 0);
- error (0, errno, "parent: %s", c2);
- free (cwd);
- free (c2);
+ struct devino cwd = getdevino (fd);
+ fprintf (stderr, "ring : "PRINT_DEVINO"\n", cwd.dev, cwd.ino);
+ struct devino c2 = getdevino (parent_fd);
+ fprintf (stderr, "parent: "PRINT_DEVINO"\n", c2.dev, c2.ino);
fts_assert (0);
}
close (cwd_fd);