|
Packit |
33f14e |
/* System dependent declarations.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
Copyright (C) 1988-1989, 1992-1995, 1998, 2001-2002, 2004, 2006, 2009-2013,
|
|
Packit |
33f14e |
2015-2017 Free Software Foundation, Inc.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
This file is part of GNU DIFF.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
33f14e |
it under the terms of the GNU General Public License as published by
|
|
Packit |
33f14e |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
33f14e |
(at your option) any later version.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
This program is distributed in the hope that it will be useful,
|
|
Packit |
33f14e |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
33f14e |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
33f14e |
GNU General Public License for more details.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
You should have received a copy of the GNU General Public License
|
|
Packit |
33f14e |
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <config.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Use this to suppress gcc's "...may be used before initialized" warnings. */
|
|
Packit |
33f14e |
#ifdef lint
|
|
Packit |
33f14e |
# define IF_LINT(Code) Code
|
|
Packit |
33f14e |
#else
|
|
Packit |
33f14e |
# define IF_LINT(Code) /* empty */
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Define '__attribute__' and 'volatile' first
|
|
Packit |
33f14e |
so that they're used consistently in all system includes. */
|
|
Packit |
33f14e |
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
|
|
Packit |
33f14e |
# define __attribute__(x)
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <verify.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <sys/types.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <sys/stat.h>
|
|
Packit |
33f14e |
#include "stat-macros.h"
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef STAT_BLOCKSIZE
|
|
Packit |
33f14e |
# if HAVE_STRUCT_STAT_ST_BLKSIZE
|
|
Packit |
33f14e |
# define STAT_BLOCKSIZE(s) ((s).st_blksize)
|
|
Packit |
33f14e |
# else
|
|
Packit |
33f14e |
# define STAT_BLOCKSIZE(s) (8 * 1024)
|
|
Packit |
33f14e |
# endif
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <unistd.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <fcntl.h>
|
|
Packit |
33f14e |
#include <time.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <sys/wait.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <dirent.h>
|
|
Packit |
33f14e |
#ifndef _D_EXACT_NAMLEN
|
|
Packit |
33f14e |
# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <stdlib.h>
|
|
Packit |
33f14e |
#define EXIT_TROUBLE 2
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <limits.h>
|
|
Packit |
33f14e |
#include <locale.h>
|
|
Packit |
33f14e |
#include <stddef.h>
|
|
Packit |
33f14e |
#include <inttypes.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <string.h>
|
|
Packit |
33f14e |
#if ! HAVE_STRCASECOLL
|
|
Packit |
33f14e |
# if HAVE_STRICOLL || defined stricoll
|
|
Packit |
33f14e |
# define strcasecoll(a, b) stricoll (a, b)
|
|
Packit |
33f14e |
# else
|
|
Packit |
33f14e |
# define strcasecoll(a, b) strcasecmp (a, b) /* best we can do */
|
|
Packit |
33f14e |
# endif
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
#if ! (HAVE_STRCASECMP || defined strcasecmp)
|
|
Packit |
33f14e |
int strcasecmp (char const *, char const *);
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <gettext.h>
|
|
Packit |
33f14e |
#if ! ENABLE_NLS
|
|
Packit |
33f14e |
# undef textdomain
|
|
Packit |
33f14e |
# define textdomain(Domainname) /* empty */
|
|
Packit |
33f14e |
# undef bindtextdomain
|
|
Packit |
33f14e |
# define bindtextdomain(Domainname, Dirname) /* empty */
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#define _(msgid) gettext (msgid)
|
|
Packit |
33f14e |
#define N_(msgid) msgid
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <ctype.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* ISDIGIT differs from isdigit, as follows:
|
|
Packit |
33f14e |
- Its arg may be any int or unsigned int; it need not be an unsigned char.
|
|
Packit |
33f14e |
- It's guaranteed to evaluate its argument exactly once.
|
|
Packit |
33f14e |
- It's typically faster.
|
|
Packit |
33f14e |
POSIX 1003.1-2001 says that only '0' through '9' are digits.
|
|
Packit |
33f14e |
Prefer ISDIGIT to isdigit unless it's important to use the locale's
|
|
Packit |
33f14e |
definition of 'digit' even when the host does not conform to POSIX. */
|
|
Packit |
33f14e |
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <errno.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <signal.h>
|
|
Packit |
33f14e |
#if !defined SIGCHLD && defined SIGCLD
|
|
Packit |
33f14e |
# define SIGCHLD SIGCLD
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#undef MIN
|
|
Packit |
33f14e |
#undef MAX
|
|
Packit |
33f14e |
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
|
|
Packit |
33f14e |
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <stdbool.h>
|
|
Packit |
33f14e |
#include <intprops.h>
|
|
Packit |
33f14e |
#include "propername.h"
|
|
Packit |
33f14e |
#include "version.h"
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Type used for fast comparison of several bytes at a time.
|
|
Packit |
33f14e |
This used to be uintmax_t, but changing it to size_t
|
|
Packit |
33f14e |
made plain 'cmp' 90% faster (GCC 4.8.1, x86). */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef word
|
|
Packit |
33f14e |
# define word size_t
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* The signed integer type of a line number. Since files are read
|
|
Packit |
33f14e |
into main memory, ptrdiff_t should be wide enough. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
typedef ptrdiff_t lin;
|
|
Packit |
33f14e |
#define LIN_MAX PTRDIFF_MAX
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* The signed integer type for printing line numbers, and its printf
|
|
Packit |
33f14e |
length modifier. This is not simply ptrdiff_t, to cater to older
|
|
Packit |
33f14e |
and/or nonstandard C libraries where "l" works but "ll" and "t" do
|
|
Packit |
33f14e |
not, or where 'long' is too narrow and "ll" works but "t" does not. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#if LIN_MAX <= LONG_MAX
|
|
Packit |
33f14e |
typedef long int printint;
|
|
Packit |
33f14e |
# define pI "l"
|
|
Packit |
33f14e |
#elif LIN_MAX <= LLONG_MAX
|
|
Packit |
33f14e |
typedef long long int printint;
|
|
Packit |
33f14e |
# define pI "ll"
|
|
Packit |
33f14e |
#else
|
|
Packit |
33f14e |
typedef ptrdiff_t printint;
|
|
Packit |
33f14e |
# define pI "t"
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
verify (TYPE_SIGNED (lin));
|
|
Packit |
33f14e |
verify (TYPE_SIGNED (printint));
|
|
Packit |
33f14e |
verify (LIN_MAX == TYPE_MAXIMUM (lin));
|
|
Packit |
33f14e |
verify (LIN_MAX <= TYPE_MAXIMUM (printint));
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Limit so that 2 * CONTEXT + 1 does not overflow. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#define CONTEXT_MAX ((LIN_MAX - 1) / 2)
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* This section contains POSIX-compliant defaults for macros
|
|
Packit |
33f14e |
that are meant to be overridden by hand in config.h as needed. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef file_name_cmp
|
|
Packit |
33f14e |
# define file_name_cmp strcmp
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef initialize_main
|
|
Packit |
33f14e |
# define initialize_main(argcp, argvp)
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef NULL_DEVICE
|
|
Packit |
33f14e |
# define NULL_DEVICE "/dev/null"
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Do struct stat *S, *T describe the same special file? */
|
|
Packit |
33f14e |
#ifndef same_special_file
|
|
Packit |
33f14e |
# if HAVE_STRUCT_STAT_ST_RDEV && defined S_ISBLK && defined S_ISCHR
|
|
Packit |
33f14e |
# define same_special_file(s, t) \
|
|
Packit |
33f14e |
(((S_ISBLK ((s)->st_mode) && S_ISBLK ((t)->st_mode)) \
|
|
Packit |
33f14e |
|| (S_ISCHR ((s)->st_mode) && S_ISCHR ((t)->st_mode))) \
|
|
Packit |
33f14e |
&& (s)->st_rdev == (t)->st_rdev)
|
|
Packit |
33f14e |
# else
|
|
Packit |
33f14e |
# define same_special_file(s, t) 0
|
|
Packit |
33f14e |
# endif
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Do struct stat *S, *T describe the same file? Answer -1 if unknown. */
|
|
Packit |
33f14e |
#ifndef same_file
|
|
Packit |
33f14e |
# define same_file(s, t) \
|
|
Packit |
33f14e |
((((s)->st_ino == (t)->st_ino) && ((s)->st_dev == (t)->st_dev)) \
|
|
Packit |
33f14e |
|| same_special_file (s, t))
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Do struct stat *S, *T have the same file attributes?
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
POSIX says that two files are identical if st_ino and st_dev are
|
|
Packit |
33f14e |
the same, but many file systems incorrectly assign the same (device,
|
|
Packit |
33f14e |
inode) pair to two distinct files, including:
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
- GNU/Linux NFS servers that export all local file systems as a
|
|
Packit |
33f14e |
single NFS file system, if a local device number (st_dev) exceeds
|
|
Packit |
33f14e |
255, or if a local inode number (st_ino) exceeds 16777215.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
- Network Appliance NFS servers in snapshot directories; see
|
|
Packit |
33f14e |
Network Appliance bug #195.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
- ClearCase MVFS; see bug id ATRia04618.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
Check whether two files that purport to be the same have the same
|
|
Packit |
33f14e |
attributes, to work around instances of this common bug. Do not
|
|
Packit |
33f14e |
inspect all attributes, only attributes useful in checking for this
|
|
Packit |
33f14e |
bug.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
It's possible for two distinct files on a buggy file system to have
|
|
Packit |
33f14e |
the same attributes, but it's not worth slowing down all
|
|
Packit |
33f14e |
implementations (or complicating the configuration) to cater to
|
|
Packit |
33f14e |
these rare cases in buggy implementations. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef same_file_attributes
|
|
Packit |
33f14e |
# define same_file_attributes(s, t) \
|
|
Packit |
33f14e |
((s)->st_mode == (t)->st_mode \
|
|
Packit |
33f14e |
&& (s)->st_nlink == (t)->st_nlink \
|
|
Packit |
33f14e |
&& (s)->st_uid == (t)->st_uid \
|
|
Packit |
33f14e |
&& (s)->st_gid == (t)->st_gid \
|
|
Packit |
33f14e |
&& (s)->st_size == (t)->st_size \
|
|
Packit |
33f14e |
&& (s)->st_mtime == (t)->st_mtime \
|
|
Packit |
33f14e |
&& (s)->st_ctime == (t)->st_ctime)
|
|
Packit |
33f14e |
#endif
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#define STREQ(a, b) (strcmp (a, b) == 0)
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#ifndef FALLTHROUGH
|
|
Packit |
33f14e |
# if __GNUC__ < 7
|
|
Packit |
33f14e |
# define FALLTHROUGH ((void) 0)
|
|
Packit |
33f14e |
# else
|
|
Packit |
33f14e |
# define FALLTHROUGH __attribute__ ((__fallthrough__))
|
|
Packit |
33f14e |
# endif
|
|
Packit |
33f14e |
#endif
|