Use Gnulib’s same-inode module

This is more portable to non-POSIX systems.
However, don’t bother trying to port to systems
where st_ino is not a scalar of type dev_t,
as these systems no longer seem to be active targets
and it’s not worth the maintenance hassle.
* gnulib.modules: Add same-inode, now that we use it
explicitly rather than indirectly.
* src/compare.c (diff_link):
* src/create.c (compare_links, restore_parent_fd):
* src/incremen.c (compare_directory_meta, procdir):
* src/extract.c (dl_compare, repair_delayed_set_stat)
(apply_nonancestor_delayed_set_stat, extract_link)
(apply_delayed_link):
* src/names.c (add_file_id):
* src/system.c (sys_file_is_archive, sys_detect_dev_null_output):
Include same-inode.h, and prefer its macros and functions
to doing things by hand.
* src/create.c (struct link):
* src/extract.c (struct delayed_set_stat, struct delayed_link):
* src/incremen.c (struct directory):
* src/names.c (struct file_id_list):
Rename members to st_dev and st_ino so that SAME_INODE and
PSAME_INODE can be used on the type.  All uses changed.
* src/system.c (sys_compare_links): Remove.
All uses replaced by psame_inode.
This commit is contained in:
Paul Eggert
2025-08-09 16:10:49 -07:00
parent 5402831d62
commit bdc442bd5c
8 changed files with 68 additions and 84 deletions

View File

@@ -94,6 +94,7 @@ root-uid
rpmatch rpmatch
full-read full-read
safe-read safe-read
same-inode
savedir savedir
selinux-at selinux-at
setenv setenv

View File

@@ -942,7 +942,6 @@ void sys_spawn_shell (void);
bool sys_compare_uid (struct stat *a, struct stat *b); bool sys_compare_uid (struct stat *a, struct stat *b);
bool sys_compare_gid (struct stat *a, struct stat *b); bool sys_compare_gid (struct stat *a, struct stat *b);
bool sys_file_is_archive (struct tar_stat_info *p); bool sys_file_is_archive (struct tar_stat_info *p);
bool sys_compare_links (struct stat *link_data, struct stat *stat_data);
int sys_truncate (int fd); int sys_truncate (int fd);
pid_t sys_child_open_for_compress (void); pid_t sys_child_open_for_compress (void);
pid_t sys_child_open_for_uncompress (void); pid_t sys_child_open_for_uncompress (void);

View File

@@ -34,6 +34,7 @@
#include <alignalloc.h> #include <alignalloc.h>
#include <quotearg.h> #include <quotearg.h>
#include <rmt.h> #include <rmt.h>
#include <same-inode.h>
#include <stdarg.h> #include <stdarg.h>
/* Nonzero if we are verifying at the moment. */ /* Nonzero if we are verifying at the moment. */
@@ -251,7 +252,7 @@ diff_link (void)
if (get_stat_data (current_stat_info.file_name, &file_data) if (get_stat_data (current_stat_info.file_name, &file_data)
&& get_stat_data (current_stat_info.link_name, &link_data) && get_stat_data (current_stat_info.link_name, &link_data)
&& !sys_compare_links (&file_data, &link_data)) && !psame_inode (&file_data, &link_data))
report_difference (&current_stat_info, report_difference (&current_stat_info,
_("Not linked to %s"), _("Not linked to %s"),
quote_n_colon (QUOTE_ARG, quote_n_colon (QUOTE_ARG,

View File

@@ -24,6 +24,7 @@
#include <areadlink.h> #include <areadlink.h>
#include <flexmember.h> #include <flexmember.h>
#include <quotearg.h> #include <quotearg.h>
#include <same-inode.h>
#include "common.h" #include "common.h"
#include <hash.h> #include <hash.h>
@@ -34,8 +35,8 @@ enum { IMPOSTOR_ERRNO = ENOENT };
struct link struct link
{ {
dev_t dev; dev_t st_dev;
ino_t ino; ino_t st_ino;
nlink_t nlink; nlink_t nlink;
char name[FLEXIBLE_ARRAY_MEMBER]; char name[FLEXIBLE_ARRAY_MEMBER];
}; };
@@ -1387,7 +1388,7 @@ static size_t
hash_link (void const *entry, size_t n_buckets) hash_link (void const *entry, size_t n_buckets)
{ {
struct link const *l = entry; struct link const *l = entry;
uintmax_t num = l->dev ^ l->ino; uintmax_t num = l->st_dev ^ l->st_ino;
return num % n_buckets; return num % n_buckets;
} }
@@ -1397,7 +1398,7 @@ compare_links (void const *entry1, void const *entry2)
{ {
struct link const *link1 = entry1; struct link const *link1 = entry1;
struct link const *link2 = entry2; struct link const *link2 = entry2;
return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0; return PSAME_INODE (link1, link2);
} }
static void static void
@@ -1430,8 +1431,8 @@ dump_hard_link (struct tar_stat_info *st)
off_t block_ordinal; off_t block_ordinal;
union block *blk; union block *blk;
lp.ino = st->stat.st_ino; lp.st_dev = st->stat.st_dev;
lp.dev = st->stat.st_dev; lp.st_ino = st->stat.st_ino;
if ((duplicate = hash_lookup (link_table, &lp))) if ((duplicate = hash_lookup (link_table, &lp)))
{ {
@@ -1485,8 +1486,8 @@ file_count_links (struct tar_stat_info *st)
} }
lp = xmalloc (FLEXNSIZEOF (struct link, name, strlen (linkname) + 1)); lp = xmalloc (FLEXNSIZEOF (struct link, name, strlen (linkname) + 1));
lp->ino = st->stat.st_ino; lp->st_dev = st->stat.st_dev;
lp->dev = st->stat.st_dev; lp->st_ino = st->stat.st_ino;
lp->nlink = st->stat.st_nlink; lp->nlink = st->stat.st_nlink;
strcpy (lp->name, linkname); strcpy (lp->name, linkname);
free (linkname); free (linkname);
@@ -1560,8 +1561,7 @@ restore_parent_fd (struct tar_stat_info const *st)
if (parentfd < 0) if (parentfd < 0)
parentfd = - errno; parentfd = - errno;
else if (fstat (parentfd, &parentstat) < 0 else if (fstat (parentfd, &parentstat) < 0
|| parent->stat.st_ino != parentstat.st_ino || !psame_inode (&parent->stat, &parentstat))
|| parent->stat.st_dev != parentstat.st_dev)
{ {
close (parentfd); close (parentfd);
parentfd = IMPOSTOR_ERRNO; parentfd = IMPOSTOR_ERRNO;
@@ -1574,8 +1574,7 @@ restore_parent_fd (struct tar_stat_info const *st)
if (0 <= origfd) if (0 <= origfd)
{ {
if (fstat (parentfd, &parentstat) < 0 if (fstat (parentfd, &parentstat) < 0
|| parent->stat.st_ino != parentstat.st_ino || !psame_inode (&parent->stat, &parentstat))
|| parent->stat.st_dev != parentstat.st_dev)
close (origfd); close (origfd);
else else
parentfd = origfd; parentfd = origfd;

View File

@@ -26,6 +26,7 @@
#include <hash.h> #include <hash.h>
#include <priv-set.h> #include <priv-set.h>
#include <root-uid.h> #include <root-uid.h>
#include <same-inode.h>
#include <utimens.h> #include <utimens.h>
#include "common.h" #include "common.h"
@@ -85,8 +86,8 @@ struct delayed_set_stat
struct delayed_set_stat *next; struct delayed_set_stat *next;
/* Metadata for this directory. */ /* Metadata for this directory. */
dev_t dev; dev_t st_dev;
ino_t ino; ino_t st_ino;
mode_t mode; /* The desired mode is MODE & ~ current_umask. */ mode_t mode; /* The desired mode is MODE & ~ current_umask. */
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
@@ -147,8 +148,8 @@ struct delayed_link
other process removes the placeholder. Don't use ctime as other process removes the placeholder. Don't use ctime as
this would cause race conditions and other screwups, e.g., this would cause race conditions and other screwups, e.g.,
when restoring hard-linked symlinks. */ when restoring hard-linked symlinks. */
dev_t dev; dev_t st_dev;
ino_t ino; ino_t st_ino;
#if HAVE_BIRTHTIME #if HAVE_BIRTHTIME
struct timespec birthtime; struct timespec birthtime;
#endif #endif
@@ -203,11 +204,11 @@ static size_t
dl_hash (void const *entry, size_t table_size) dl_hash (void const *entry, size_t table_size)
{ {
struct delayed_link const *dl = entry; struct delayed_link const *dl = entry;
uintmax_t n = dl->dev; uintmax_t n = dl->st_dev;
int nshift = TYPE_WIDTH (n) - TYPE_WIDTH (dl->dev); int nshift = TYPE_WIDTH (n) - TYPE_WIDTH (dl->st_dev);
if (0 < nshift) if (0 < nshift)
n <<= nshift; n <<= nshift;
n ^= dl->ino; n ^= dl->st_ino;
return n % table_size; return n % table_size;
} }
@@ -215,7 +216,7 @@ static bool
dl_compare (void const *a, void const *b) dl_compare (void const *a, void const *b)
{ {
struct delayed_link const *da = a, *db = b; struct delayed_link const *da = a, *db = b;
return (da->dev == db->dev) & (da->ino == db->ino); return PSAME_INODE (da, db);
} }
static size_t static size_t
@@ -496,8 +497,8 @@ mark_after_links (struct delayed_set_stat *head)
stat_error (h->file_name); stat_error (h->file_name);
else else
{ {
h->dev = st.st_dev; h->st_dev = st.st_dev;
h->ino = st.st_ino; h->st_ino = st.st_ino;
} }
} }
while ((h = h->next) && ! h->after_links); while ((h = h->next) && ! h->after_links);
@@ -551,8 +552,8 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
} }
else else
{ {
data->dev = real_st.st_dev; data->st_dev = real_st.st_dev;
data->ino = real_st.st_ino; data->st_ino = real_st.st_ino;
} }
} }
} }
@@ -568,8 +569,8 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
data->after_links = false; data->after_links = false;
if (st) if (st)
{ {
data->dev = st->stat.st_dev; data->st_dev = st->stat.st_dev;
data->ino = st->stat.st_ino; data->st_ino = st->stat.st_ino;
} }
xattr_map_init (&data->xattr_map); xattr_map_init (&data->xattr_map);
} }
@@ -631,8 +632,8 @@ update_interdir_set_stat (char const *dir)
data = hash_lookup (delayed_set_stat_table, &key); data = hash_lookup (delayed_set_stat_table, &key);
if (data && data->interdir) if (data && data->interdir)
{ {
data->dev = current_stat_info.stat.st_dev; data->st_dev = current_stat_info.stat.st_dev;
data->ino = current_stat_info.stat.st_ino; data->st_ino = current_stat_info.stat.st_ino;
data->mode = current_stat_info.stat.st_mode; data->mode = current_stat_info.stat.st_mode;
data->uid = current_stat_info.stat.st_uid; data->uid = current_stat_info.stat.st_uid;
data->gid = current_stat_info.stat.st_gid; data->gid = current_stat_info.stat.st_gid;
@@ -663,11 +664,10 @@ repair_delayed_set_stat (char const *dir,
return; return;
} }
if (st.st_dev == dir_stat_info->st_dev if (psame_inode (&st, dir_stat_info))
&& st.st_ino == dir_stat_info->st_ino)
{ {
data->dev = current_stat_info.stat.st_dev; data->st_dev = current_stat_info.stat.st_dev;
data->ino = current_stat_info.stat.st_ino; data->st_ino = current_stat_info.stat.st_ino;
data->mode = current_stat_info.stat.st_mode; data->mode = current_stat_info.stat.st_mode;
data->uid = current_stat_info.stat.st_uid; data->uid = current_stat_info.stat.st_uid;
data->gid = current_stat_info.stat.st_gid; data->gid = current_stat_info.stat.st_gid;
@@ -1022,7 +1022,7 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
{ {
current_mode = st.st_mode; current_mode = st.st_mode;
current_mode_mask = all_mode_bits; current_mode_mask = all_mode_bits;
if (! (st.st_dev == data->dev && st.st_ino == data->ino)) if (!SAME_INODE (st, *data))
{ {
paxerror (0, paxerror (0,
_("%s: Directory renamed before its status" _("%s: Directory renamed before its status"
@@ -1416,8 +1416,8 @@ find_delayed_link_source (char const *name)
} }
struct delayed_link dl; struct delayed_link dl;
dl.dev = st.st_dev; dl.st_dev = st.st_dev;
dl.ino = st.st_ino; dl.st_ino = st.st_ino;
return hash_lookup (delayed_link_table, &dl) != NULL; return hash_lookup (delayed_link_table, &dl) != NULL;
} }
@@ -1473,8 +1473,8 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
xmalloc (FLEXNSIZEOF (struct delayed_link, target, xmalloc (FLEXNSIZEOF (struct delayed_link, target,
strlen (current_stat_info.link_name) + 1)); strlen (current_stat_info.link_name) + 1));
p->next = NULL; p->next = NULL;
p->dev = st.st_dev; p->st_dev = st.st_dev;
p->ino = st.st_ino; p->st_ino = st.st_ino;
#if HAVE_BIRTHTIME #if HAVE_BIRTHTIME
p->birthtime = get_stat_birthtime (&st); p->birthtime = get_stat_birthtime (&st);
#endif #endif
@@ -1545,8 +1545,8 @@ extract_link (char *file_name, MAYBE_UNUSED char typeflag)
&& fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0) && fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0)
{ {
struct delayed_link dl1; struct delayed_link dl1;
dl1.ino = st1.st_ino; dl1.st_ino = st1.st_ino;
dl1.dev = st1.st_dev; dl1.st_dev = st1.st_dev;
struct delayed_link *ds = hash_lookup (delayed_link_table, &dl1); struct delayed_link *ds = hash_lookup (delayed_link_table, &dl1);
if (ds && ds->change_dir == chdir_current if (ds && ds->change_dir == chdir_current
&& BIRTHTIME_EQ (ds->birthtime, get_stat_birthtime (&st1))) && BIRTHTIME_EQ (ds->birthtime, get_stat_birthtime (&st1)))
@@ -1567,8 +1567,7 @@ extract_link (char *file_name, MAYBE_UNUSED char typeflag)
== 0) == 0)
&& (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW) && (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW)
== 0) == 0)
&& st1.st_dev == st2.st_dev && psame_inode (&st1, &st2)))
&& st1.st_ino == st2.st_ino))
return true; return true;
errno = e; errno = e;
@@ -1894,8 +1893,7 @@ apply_delayed_link (struct delayed_link *ds)
don't create a link, as the placeholder was probably don't create a link, as the placeholder was probably
removed by a later extraction. */ removed by a later extraction. */
if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0 if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
&& st.st_dev == ds->dev && SAME_INODE (st, *ds)
&& st.st_ino == ds->ino
&& BIRTHTIME_EQ (get_stat_birthtime (&st), ds->birthtime)) && BIRTHTIME_EQ (get_stat_birthtime (&st), ds->birthtime))
{ {
/* Unlink the placeholder, then create a hard link if possible, /* Unlink the placeholder, then create a hard link if possible,

View File

@@ -22,6 +22,7 @@
#include <flexmember.h> #include <flexmember.h>
#include <hash.h> #include <hash.h>
#include <quotearg.h> #include <quotearg.h>
#include <same-inode.h>
#include "common.h" #include "common.h"
/* Incremental dump specialities. */ /* Incremental dump specialities. */
@@ -73,8 +74,8 @@ struct directory
{ {
struct directory *next; struct directory *next;
struct timespec mtime; /* Modification time */ struct timespec mtime; /* Modification time */
dev_t device_number; /* device number for directory */ dev_t st_dev; /* device number for directory */
ino_t inode_number; /* inode number for directory */ ino_t st_ino; /* inode number for directory */
struct dumpdir *dump; /* Directory contents */ struct dumpdir *dump; /* Directory contents */
struct dumpdir *idump; /* Initial contents if the directory was struct dumpdir *idump; /* Initial contents if the directory was
rescanned */ rescanned */
@@ -284,7 +285,7 @@ hash_directory_meta (void const *entry, size_t n_buckets)
{ {
struct directory const *directory = entry; struct directory const *directory = entry;
/* FIXME: Work out a better algorytm */ /* FIXME: Work out a better algorytm */
return (directory->device_number + directory->inode_number) % n_buckets; return (directory->st_dev + directory->st_ino) % n_buckets;
} }
/* Compare two directories for equality of their device and inode numbers. */ /* Compare two directories for equality of their device and inode numbers. */
@@ -293,8 +294,7 @@ compare_directory_meta (void const *entry1, void const *entry2)
{ {
struct directory const *directory1 = entry1; struct directory const *directory1 = entry1;
struct directory const *directory2 = entry2; struct directory const *directory2 = entry2;
return directory1->device_number == directory2->device_number return PSAME_INODE (directory1, directory2);
&& directory1->inode_number == directory2->inode_number;
} }
/* Make a directory entry for given relative NAME and canonical name CANAME. /* Make a directory entry for given relative NAME and canonical name CANAME.
@@ -375,8 +375,8 @@ note_directory (char const *name, struct timespec mtime,
struct directory *directory = attach_directory (name); struct directory *directory = attach_directory (name);
directory->mtime = mtime; directory->mtime = mtime;
directory->device_number = dev; directory->st_dev = dev;
directory->inode_number = ino; directory->st_ino = ino;
directory->children = CHANGED_CHILDREN; directory->children = CHANGED_CHILDREN;
if (nfs) if (nfs)
dir_set_flag (directory, DIRF_NFS); dir_set_flag (directory, DIRF_NFS);
@@ -457,8 +457,8 @@ find_directory_meta (dev_t dev, ino_t ino)
{ {
struct directory *dir = make_directory ("", NULL); struct directory *dir = make_directory ("", NULL);
struct directory *ret; struct directory *ret;
dir->device_number = dev; dir->st_dev = dev;
dir->inode_number = ino; dir->st_ino = ino;
ret = hash_lookup (directory_meta_table, dir); ret = hash_lookup (directory_meta_table, dir);
free_directory (dir); free_directory (dir);
return ret; return ret;
@@ -528,10 +528,9 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
directories, consider all NFS devices as equal, directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */ relying on the i-node to establish differences. */
if (! ((!check_device_option if (! (!check_device_option || (dir_is_nfs (directory) && nfs)
|| (dir_is_nfs (directory) && nfs) ? directory->st_ino == stat_data->st_ino
|| directory->device_number == stat_data->st_dev) : PSAME_INODE (directory, stat_data)))
&& directory->inode_number == stat_data->st_ino))
{ {
/* FIXME: find_directory_meta ignores nfs */ /* FIXME: find_directory_meta ignores nfs */
struct directory *d = find_directory_meta (stat_data->st_dev, struct directory *d = find_directory_meta (stat_data->st_dev,
@@ -555,8 +554,8 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
{ {
perhaps_renamed = true; perhaps_renamed = true;
directory->children = ALL_CHILDREN; directory->children = ALL_CHILDREN;
directory->device_number = stat_data->st_dev; directory->st_dev = stat_data->st_dev;
directory->inode_number = stat_data->st_ino; directory->st_ino = stat_data->st_ino;
} }
if (nfs) if (nfs)
dir_set_flag (directory, DIRF_NFS); dir_set_flag (directory, DIRF_NFS);
@@ -1439,10 +1438,10 @@ write_directory_file_entry (void *entry, void *data)
fwrite (s, strlen (s) + 1, 1, fp); fwrite (s, strlen (s) + 1, 1, fp);
int ns = directory->mtime.tv_nsec; int ns = directory->mtime.tv_nsec;
fprintf (fp, "%d%c", ns, 0); fprintf (fp, "%d%c", ns, 0);
s = sysinttostr (directory->device_number, s = sysinttostr (directory->st_dev,
TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf); TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
fwrite (s, strlen (s) + 1, 1, fp); fwrite (s, strlen (s) + 1, 1, fp);
s = sysinttostr (directory->inode_number, s = sysinttostr (directory->st_ino,
TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf); TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf);
fwrite (s, strlen (s) + 1, 1, fp); fwrite (s, strlen (s) + 1, 1, fp);

View File

@@ -21,6 +21,7 @@
#include <fnmatch.h> #include <fnmatch.h>
#include <hash.h> #include <hash.h>
#include <quotearg.h> #include <quotearg.h>
#include <same-inode.h>
#include <wordsplit.h> #include <wordsplit.h>
#include <argp.h> #include <argp.h>
@@ -881,8 +882,8 @@ name_init (void)
struct file_id_list struct file_id_list
{ {
struct file_id_list *next; struct file_id_list *next;
ino_t ino; dev_t st_dev;
dev_t dev; ino_t st_ino;
const char *from_file; const char *from_file;
}; };
@@ -913,7 +914,7 @@ add_file_id (const char *filename)
stat_fatal (filename); stat_fatal (filename);
reading_from = file_list_name (); reading_from = file_list_name ();
for (p = file_id_list; p; p = p->next) for (p = file_id_list; p; p = p->next)
if (p->ino == st.st_ino && p->dev == st.st_dev) if (SAME_INODE (*p, st))
{ {
int oldc = set_char_quoting (NULL, ':', 1); int oldc = set_char_quoting (NULL, ':', 1);
paxerror (0, _("%s: file list requested from %s already read from %s"), paxerror (0, _("%s: file list requested from %s already read from %s"),
@@ -924,8 +925,8 @@ add_file_id (const char *filename)
} }
p = xmalloc (sizeof *p); p = xmalloc (sizeof *p);
p->next = file_id_list; p->next = file_id_list;
p->ino = st.st_ino; p->st_dev = st.st_dev;
p->dev = st.st_dev; p->st_ino = st.st_ino;
p->from_file = reading_from; p->from_file = reading_from;
file_id_list = p; file_id_list = p;
return true; return true;

View File

@@ -25,6 +25,7 @@
#include "common.h" #include "common.h"
#include <priv-set.h> #include <priv-set.h>
#include <rmt.h> #include <rmt.h>
#include <same-inode.h>
#include <signal.h> #include <signal.h>
#include <wordsplit.h> #include <wordsplit.h>
#include <poll.h> #include <poll.h>
@@ -125,12 +126,6 @@ sys_compare_gid (struct stat *a, struct stat *b)
return true; return true;
} }
void
sys_compare_links (struct stat *link_data, struct stat *stat_data)
{
return true;
}
int int
sys_truncate (int fd) sys_truncate (int fd)
{ {
@@ -194,8 +189,7 @@ bool
sys_file_is_archive (struct tar_stat_info *p) sys_file_is_archive (struct tar_stat_info *p)
{ {
return (!dev_null_output && !_isrmt (archive) return (!dev_null_output && !_isrmt (archive)
&& p->stat.st_dev == archive_stat.st_dev && psame_inode (&p->stat, &archive_stat));
&& p->stat.st_ino == archive_stat.st_ino);
} }
static char const dev_null[] = "/dev/null"; static char const dev_null[] = "/dev/null";
@@ -211,8 +205,7 @@ sys_detect_dev_null_output (void)
&& S_ISCHR (archive_stat.st_mode) && S_ISCHR (archive_stat.st_mode)
&& (dev_null_stat.st_ino != 0 && (dev_null_stat.st_ino != 0
|| stat (dev_null, &dev_null_stat) == 0) || stat (dev_null, &dev_null_stat) == 0)
&& archive_stat.st_ino == dev_null_stat.st_ino && psame_inode (&archive_stat, &dev_null_stat)));
&& archive_stat.st_dev == dev_null_stat.st_dev));
} }
void void
@@ -279,13 +272,6 @@ sys_compare_gid (struct stat *a, struct stat *b)
return a->st_gid == b->st_gid; return a->st_gid == b->st_gid;
} }
bool
sys_compare_links (struct stat *link_data, struct stat *stat_data)
{
return stat_data->st_dev == link_data->st_dev
&& stat_data->st_ino == link_data->st_ino;
}
int int
sys_truncate (int fd) sys_truncate (int fd)
{ {