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.
rpmatch
full-read
safe-read
+same-inode
savedir
selinux-at
setenv
bool sys_compare_uid (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_compare_links (struct stat *link_data, struct stat *stat_data);
int sys_truncate (int fd);
pid_t sys_child_open_for_compress (void);
pid_t sys_child_open_for_uncompress (void);
#include <alignalloc.h>
#include <quotearg.h>
#include <rmt.h>
+#include <same-inode.h>
#include <stdarg.h>
/* Nonzero if we are verifying at the moment. */
if (get_stat_data (current_stat_info.file_name, &file_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 (¤t_stat_info,
_("Not linked to %s"),
quote_n_colon (QUOTE_ARG,
#include <areadlink.h>
#include <flexmember.h>
#include <quotearg.h>
+#include <same-inode.h>
#include "common.h"
#include <hash.h>
struct link
{
- dev_t dev;
- ino_t ino;
+ dev_t st_dev;
+ ino_t st_ino;
nlink_t nlink;
char name[FLEXIBLE_ARRAY_MEMBER];
};
hash_link (void const *entry, size_t n_buckets)
{
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;
}
{
struct link const *link1 = entry1;
struct link const *link2 = entry2;
- return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
+ return PSAME_INODE (link1, link2);
}
static void
off_t block_ordinal;
union block *blk;
- lp.ino = st->stat.st_ino;
- lp.dev = st->stat.st_dev;
+ lp.st_dev = st->stat.st_dev;
+ lp.st_ino = st->stat.st_ino;
if ((duplicate = hash_lookup (link_table, &lp)))
{
}
lp = xmalloc (FLEXNSIZEOF (struct link, name, strlen (linkname) + 1));
- lp->ino = st->stat.st_ino;
- lp->dev = st->stat.st_dev;
+ lp->st_dev = st->stat.st_dev;
+ lp->st_ino = st->stat.st_ino;
lp->nlink = st->stat.st_nlink;
strcpy (lp->name, linkname);
free (linkname);
if (parentfd < 0)
parentfd = - errno;
else if (fstat (parentfd, &parentstat) < 0
- || parent->stat.st_ino != parentstat.st_ino
- || parent->stat.st_dev != parentstat.st_dev)
+ || !psame_inode (&parent->stat, &parentstat))
{
close (parentfd);
parentfd = IMPOSTOR_ERRNO;
if (0 <= origfd)
{
if (fstat (parentfd, &parentstat) < 0
- || parent->stat.st_ino != parentstat.st_ino
- || parent->stat.st_dev != parentstat.st_dev)
+ || !psame_inode (&parent->stat, &parentstat))
close (origfd);
else
parentfd = origfd;
#include <hash.h>
#include <priv-set.h>
#include <root-uid.h>
+#include <same-inode.h>
#include <utimens.h>
#include "common.h"
struct delayed_set_stat *next;
/* Metadata for this directory. */
- dev_t dev;
- ino_t ino;
+ dev_t st_dev;
+ ino_t st_ino;
mode_t mode; /* The desired mode is MODE & ~ current_umask. */
uid_t uid;
gid_t gid;
other process removes the placeholder. Don't use ctime as
this would cause race conditions and other screwups, e.g.,
when restoring hard-linked symlinks. */
- dev_t dev;
- ino_t ino;
+ dev_t st_dev;
+ ino_t st_ino;
#if HAVE_BIRTHTIME
struct timespec birthtime;
#endif
dl_hash (void const *entry, size_t table_size)
{
struct delayed_link const *dl = entry;
- uintmax_t n = dl->dev;
- int nshift = TYPE_WIDTH (n) - TYPE_WIDTH (dl->dev);
+ uintmax_t n = dl->st_dev;
+ int nshift = TYPE_WIDTH (n) - TYPE_WIDTH (dl->st_dev);
if (0 < nshift)
n <<= nshift;
- n ^= dl->ino;
+ n ^= dl->st_ino;
return n % table_size;
}
dl_compare (void const *a, void const *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
stat_error (h->file_name);
else
{
- h->dev = st.st_dev;
- h->ino = st.st_ino;
+ h->st_dev = st.st_dev;
+ h->st_ino = st.st_ino;
}
}
while ((h = h->next) && ! h->after_links);
}
else
{
- data->dev = real_st.st_dev;
- data->ino = real_st.st_ino;
+ data->st_dev = real_st.st_dev;
+ data->st_ino = real_st.st_ino;
}
}
}
data->after_links = false;
if (st)
{
- data->dev = st->stat.st_dev;
- data->ino = st->stat.st_ino;
+ data->st_dev = st->stat.st_dev;
+ data->st_ino = st->stat.st_ino;
}
xattr_map_init (&data->xattr_map);
}
data = hash_lookup (delayed_set_stat_table, &key);
if (data && data->interdir)
{
- data->dev = current_stat_info.stat.st_dev;
- data->ino = current_stat_info.stat.st_ino;
+ data->st_dev = current_stat_info.stat.st_dev;
+ data->st_ino = current_stat_info.stat.st_ino;
data->mode = current_stat_info.stat.st_mode;
data->uid = current_stat_info.stat.st_uid;
data->gid = current_stat_info.stat.st_gid;
return;
}
- if (st.st_dev == dir_stat_info->st_dev
- && st.st_ino == dir_stat_info->st_ino)
+ if (psame_inode (&st, dir_stat_info))
{
- data->dev = current_stat_info.stat.st_dev;
- data->ino = current_stat_info.stat.st_ino;
+ data->st_dev = current_stat_info.stat.st_dev;
+ data->st_ino = current_stat_info.stat.st_ino;
data->mode = current_stat_info.stat.st_mode;
data->uid = current_stat_info.stat.st_uid;
data->gid = current_stat_info.stat.st_gid;
{
current_mode = st.st_mode;
current_mode_mask = all_mode_bits;
- if (! (st.st_dev == data->dev && st.st_ino == data->ino))
+ if (!SAME_INODE (st, *data))
{
paxerror (0,
_("%s: Directory renamed before its status"
}
struct delayed_link dl;
- dl.dev = st.st_dev;
- dl.ino = st.st_ino;
+ dl.st_dev = st.st_dev;
+ dl.st_ino = st.st_ino;
return hash_lookup (delayed_link_table, &dl) != NULL;
}
xmalloc (FLEXNSIZEOF (struct delayed_link, target,
strlen (current_stat_info.link_name) + 1));
p->next = NULL;
- p->dev = st.st_dev;
- p->ino = st.st_ino;
+ p->st_dev = st.st_dev;
+ p->st_ino = st.st_ino;
#if HAVE_BIRTHTIME
p->birthtime = get_stat_birthtime (&st);
#endif
&& fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0)
{
struct delayed_link dl1;
- dl1.ino = st1.st_ino;
- dl1.dev = st1.st_dev;
+ dl1.st_ino = st1.st_ino;
+ dl1.st_dev = st1.st_dev;
struct delayed_link *ds = hash_lookup (delayed_link_table, &dl1);
if (ds && ds->change_dir == chdir_current
&& BIRTHTIME_EQ (ds->birthtime, get_stat_birthtime (&st1)))
== 0)
&& (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW)
== 0)
- && st1.st_dev == st2.st_dev
- && st1.st_ino == st2.st_ino))
+ && psame_inode (&st1, &st2)))
return true;
errno = e;
don't create a link, as the placeholder was probably
removed by a later extraction. */
if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
- && st.st_dev == ds->dev
- && st.st_ino == ds->ino
+ && SAME_INODE (st, *ds)
&& BIRTHTIME_EQ (get_stat_birthtime (&st), ds->birthtime))
{
/* Unlink the placeholder, then create a hard link if possible,
#include <flexmember.h>
#include <hash.h>
#include <quotearg.h>
+#include <same-inode.h>
#include "common.h"
/* Incremental dump specialities. */
{
struct directory *next;
struct timespec mtime; /* Modification time */
- dev_t device_number; /* device number for directory */
- ino_t inode_number; /* inode number for directory */
+ dev_t st_dev; /* device number for directory */
+ ino_t st_ino; /* inode number for directory */
struct dumpdir *dump; /* Directory contents */
struct dumpdir *idump; /* Initial contents if the directory was
rescanned */
{
struct directory const *directory = entry;
/* 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. */
{
struct directory const *directory1 = entry1;
struct directory const *directory2 = entry2;
- return directory1->device_number == directory2->device_number
- && directory1->inode_number == directory2->inode_number;
+ return PSAME_INODE (directory1, directory2);
}
/* Make a directory entry for given relative NAME and canonical name CANAME.
struct directory *directory = attach_directory (name);
directory->mtime = mtime;
- directory->device_number = dev;
- directory->inode_number = ino;
+ directory->st_dev = dev;
+ directory->st_ino = ino;
directory->children = CHANGED_CHILDREN;
if (nfs)
dir_set_flag (directory, DIRF_NFS);
{
struct directory *dir = make_directory ("", NULL);
struct directory *ret;
- dir->device_number = dev;
- dir->inode_number = ino;
+ dir->st_dev = dev;
+ dir->st_ino = ino;
ret = hash_lookup (directory_meta_table, dir);
free_directory (dir);
return ret;
directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */
- if (! ((!check_device_option
- || (dir_is_nfs (directory) && nfs)
- || directory->device_number == stat_data->st_dev)
- && directory->inode_number == stat_data->st_ino))
+ if (! (!check_device_option || (dir_is_nfs (directory) && nfs)
+ ? directory->st_ino == stat_data->st_ino
+ : PSAME_INODE (directory, stat_data)))
{
/* FIXME: find_directory_meta ignores nfs */
struct directory *d = find_directory_meta (stat_data->st_dev,
{
perhaps_renamed = true;
directory->children = ALL_CHILDREN;
- directory->device_number = stat_data->st_dev;
- directory->inode_number = stat_data->st_ino;
+ directory->st_dev = stat_data->st_dev;
+ directory->st_ino = stat_data->st_ino;
}
if (nfs)
dir_set_flag (directory, DIRF_NFS);
fwrite (s, strlen (s) + 1, 1, fp);
int ns = directory->mtime.tv_nsec;
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);
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);
fwrite (s, strlen (s) + 1, 1, fp);
#include <fnmatch.h>
#include <hash.h>
#include <quotearg.h>
+#include <same-inode.h>
#include <wordsplit.h>
#include <argp.h>
struct file_id_list
{
struct file_id_list *next;
- ino_t ino;
- dev_t dev;
+ dev_t st_dev;
+ ino_t st_ino;
const char *from_file;
};
stat_fatal (filename);
reading_from = file_list_name ();
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);
paxerror (0, _("%s: file list requested from %s already read from %s"),
}
p = xmalloc (sizeof *p);
p->next = file_id_list;
- p->ino = st.st_ino;
- p->dev = st.st_dev;
+ p->st_dev = st.st_dev;
+ p->st_ino = st.st_ino;
p->from_file = reading_from;
file_id_list = p;
return true;
#include "common.h"
#include <priv-set.h>
#include <rmt.h>
+#include <same-inode.h>
#include <signal.h>
#include <wordsplit.h>
#include <poll.h>
return true;
}
-void
-sys_compare_links (struct stat *link_data, struct stat *stat_data)
-{
- return true;
-}
-
int
sys_truncate (int fd)
{
sys_file_is_archive (struct tar_stat_info *p)
{
return (!dev_null_output && !_isrmt (archive)
- && p->stat.st_dev == archive_stat.st_dev
- && p->stat.st_ino == archive_stat.st_ino);
+ && psame_inode (&p->stat, &archive_stat));
}
static char const dev_null[] = "/dev/null";
&& S_ISCHR (archive_stat.st_mode)
&& (dev_null_stat.st_ino != 0
|| stat (dev_null, &dev_null_stat) == 0)
- && archive_stat.st_ino == dev_null_stat.st_ino
- && archive_stat.st_dev == dev_null_stat.st_dev));
+ && psame_inode (&archive_stat, &dev_null_stat)));
}
void
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
sys_truncate (int fd)
{