Hash :
0771cac8
Author :
Date :
2023-09-03T18:14:53
same-inode, stat-size: support pointers too Add functions and macros so that we can test pointers to struct stat as well as plain struct stat. This lets coreutils deal with structs that are only partly initialized, without relying on undefined behavior. * NEWS: Mention this. * doc/posix-headers/sys_stat.texi, doc/stat-size.texi: Mention this and modernize. * lib/at-func2.c (at_func2): * lib/fts.c (same_fd): * lib/rename.c (rpl_rename) [RENAME_HARD_LINK_BUG]: * lib/same-inode.c: New file. * lib/same.c (same_nameat): * lib/term-style-control.c (activate_term_style_controller): Prefer psame_inode (a, b) to SAME_INODE (*a, *b). * lib/hash-triple-simple.c (triple_compare_ino_str): * lib/hash-triple.c (triple_compare): Prefer PSAME_INODE (a, b) to SAME_INODE (*a, *b). psame_inode is not suitable since the args are not struct stat *. * lib/same-inode.h: Check that config.h is included first. (SAME_INODE_INLINE, PSAME_INODE): New macros. (SAME_INODE): Reimplement in terms of PSAME_INODE. (psame_inode): New function. * lib/stat-size.h (STP_BLKSIZE, STP_NBLOCKS): New macros. (ST_BLKSIZE, ST_NBLOCKS): Use them. * lib/term-style-control.c (log_signal_handler_called): Always define as a function, to pacify -Wunused*. * modules/canonicalize-lgpl-tests (Files): Add m4/musl.m4. (Depends-on): Call gl_MUSL_LIBC. * modules/same-inode (Files): Add same-inode.c. (Depends-on): Add extern-inline, stdbool. (lib_SOURCES): New macro. * tests/test-binary-io.c, tests/test-canonicalize-lgpl.c: * tests/test-canonicalize.c, tests/test-cloexec.c: * tests/test-dup-safer.c, tests/test-dup2.c, tests/test-error.c: * tests/test-fcntl.c, tests/test-fdopendir.c, tests/test-fgetc.c: * tests/test-fputc.c, tests/test-fread.c, tests/test-fstat.c: * tests/test-fstatat.c, tests/test-ftruncate.c: * tests/test-fwrite.c, tests/test-getcwd.c: * tests/test-getdtablesize.c, tests/test-isblank.c: * tests/test-linkat.c, tests/test-lock.c, tests/test-lstat.h: * tests/test-malloc-gnu.c, tests/test-openat.c: * tests/test-pthread-thread.c, tests/test-pthread_sigmask1.c: * tests/test-pthread_sigmask2.c, tests/test-ptsname.c: * tests/test-ptsname_r.c, tests/test-raise.c: * tests/test-realloc-gnu.c, tests/test-rwlock1.c: * tests/test-sigprocmask.c, tests/test-snprintf.c: * tests/test-stat.h, tests/test-term-style-control-hello.c: * tests/test-term-style-control-yes.c, tests/test-thread_create.c: * tests/test-unlinkat.c, tests/test-vasnprintf.c: * tests/test-xalloc-die.c: Adjust to these changes, and fix some warnings elicited by -Wall -Wextra that I ran into while testing. * top/maint.mk (sc_prohibit_stat_st_blocks): Mention STP_NBLOCKS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
/* Determine whether two stat buffers are known to refer to the same file.
Copyright (C) 2006, 2009-2023 Free Software Foundation, Inc.
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef SAME_INODE_H
#define SAME_INODE_H 1
/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */
#if !_GL_CONFIG_H_INCLUDED
#error "Please include config.h first."
#endif
#include <sys/stat.h>
_GL_INLINE_HEADER_BEGIN
#ifndef SAME_INODE_INLINE
# define SAME_INODE_INLINE _GL_INLINE
#endif
/* True if A and B point to structs with st_dev and st_ino members
that are known to represent the same file.
Use | and ^ to shorten generated code, and to lessen the
probability of screwups if st_ino is an array. */
#if defined __VMS && __CRTL_VER < 80200000
# define PSAME_INODE(a, b) (! (((a)->st_dev ^ (b)->st_dev) \
| ((a)->st_ino[0] ^ (b)->st_ino[0]) \
| ((a)->st_ino[1] ^ (b)->st_ino[1]) \
| ((a)->st_ino[2] ^ (b)->st_ino[2])))
#elif defined _WIN32 && ! defined __CYGWIN__
/* Native Windows. */
# if _GL_WINDOWS_STAT_INODES
/* stat() and fstat() set st_dev and st_ino to 0 if information about
the inode is not available. */
# if _GL_WINDOWS_STAT_INODES == 2
# define PSAME_INODE(a, b) \
(! (! ((a)->st_dev | (a)->st_ino._gl_ino[0] | (a)->st_ino._gl_ino[1]) \
| ((a)->st_dev ^ (b)->st_dev) \
| ((a)->st_ino._gl_ino[0] ^ (b)->st_ino._gl_ino[0]) \
| ((a)->st_ino._gl_ino[1] ^ (b)->st_ino._gl_ino[1])))
# else
# define PSAME_INODE(a, b) (! (! ((a)->st_dev | (a)->st_ino) \
| ((a)->st_dev ^ (b)->st_dev) \
| ((a)->st_ino ^ (b)->st_ino)))
# endif
# else
/* stat() and fstat() set st_ino to 0 always. */
# define PSAME_INODE(a, b) 0
# endif
#else
/* POSIX. */
# define PSAME_INODE(a, b) (! (((a)->st_dev ^ (b)->st_dev) \
| ((a)->st_ino ^ (b)->st_ino)))
#endif
/* True if struct objects A and B are known to represent the same file. */
#define SAME_INODE(a, b) PSAME_INODE (&(a), &(b))
/* True if *A and *B represent the same file. Unlike PSAME_INODE,
args are evaluated once and must point to struct stat. */
SAME_INODE_INLINE bool
psame_inode (struct stat const *a, struct stat const *b)
{
return PSAME_INODE (a, b);
}
_GL_INLINE_HEADER_END
#endif