(root)/
diffutils-3.10/
src/
system.h
       1  /* System dependent declarations.
       2  
       3     Copyright (C) 1988-1989, 1992-1995, 1998, 2001-2002, 2004, 2006, 2009-2013,
       4     2015-2023 Free Software Foundation, Inc.
       5  
       6     This file is part of GNU DIFF.
       7  
       8     This program is free software: you can redistribute it and/or modify
       9     it under the terms of the GNU General Public License as published by
      10     the Free Software Foundation, either version 3 of the License, or
      11     (at your option) any later version.
      12  
      13     This program is distributed in the hope that it will be useful,
      14     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16     GNU General Public License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      20  
      21  #include <config.h>
      22  
      23  /* Use this to suppress gcc's "...may be used before initialized" warnings. */
      24  #ifdef GCC_LINT
      25  # define IF_LINT(Code) Code
      26  #else
      27  # define IF_LINT(Code) /* empty */
      28  #endif
      29  
      30  #include <verify.h>
      31  
      32  #include <sys/types.h>
      33  
      34  #include <sys/stat.h>
      35  #include <stat-macros.h>
      36  
      37  #ifndef STAT_BLOCKSIZE
      38  # if HAVE_STRUCT_STAT_ST_BLKSIZE
      39  #  define STAT_BLOCKSIZE(s) ((s).st_blksize)
      40  # else
      41  #  define STAT_BLOCKSIZE(s) (8 * 1024)
      42  # endif
      43  #endif
      44  
      45  #include <unistd.h>
      46  
      47  #include <fcntl.h>
      48  #include <time.h>
      49  
      50  #include <sys/wait.h>
      51  
      52  #include <dirent.h>
      53  #ifndef _D_EXACT_NAMLEN
      54  # define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
      55  #endif
      56  
      57  #include <stdlib.h>
      58  #define EXIT_TROUBLE 2
      59  
      60  #include <limits.h>
      61  #include <locale.h>
      62  #include <stddef.h>
      63  #include <inttypes.h>
      64  
      65  #include <string.h>
      66  #if ! HAVE_STRCASECOLL
      67  # if HAVE_STRICOLL || defined stricoll
      68  #  define strcasecoll(a, b) stricoll (a, b)
      69  # else
      70  #  define strcasecoll(a, b) strcasecmp (a, b) /* best we can do */
      71  # endif
      72  #endif
      73  #if ! (HAVE_STRCASECMP || defined strcasecmp)
      74  int strcasecmp (char const *, char const *);
      75  #endif
      76  
      77  #include <gettext.h>
      78  #if ! ENABLE_NLS
      79  # undef textdomain
      80  # define textdomain(Domainname) /* empty */
      81  # undef bindtextdomain
      82  # define bindtextdomain(Domainname, Dirname) /* empty */
      83  #endif
      84  
      85  #define _(msgid) gettext (msgid)
      86  #define N_(msgid) msgid
      87  
      88  #include <ctype.h>
      89  
      90  /* ISDIGIT differs from isdigit, as follows:
      91     - Its arg may be any int or unsigned int; it need not be an unsigned char.
      92     - It's guaranteed to evaluate its argument exactly once.
      93     - It's typically faster.
      94     POSIX 1003.1-2001 says that only '0' through '9' are digits.
      95     Prefer ISDIGIT to isdigit unless it's important to use the locale's
      96     definition of 'digit' even when the host does not conform to POSIX.  */
      97  #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
      98  
      99  #include <errno.h>
     100  
     101  #include <signal.h>
     102  #if !defined SIGCHLD && defined SIGCLD
     103  # define SIGCHLD SIGCLD
     104  #endif
     105  
     106  #undef MIN
     107  #undef MAX
     108  #define MIN(a, b) ((a) <= (b) ? (a) : (b))
     109  #define MAX(a, b) ((a) >= (b) ? (a) : (b))
     110  
     111  #include <attribute.h>
     112  #include <intprops.h>
     113  #include <propername.h>
     114  
     115  #include "version.h"
     116  
     117  /* Type used for fast comparison of several bytes at a time.
     118     This used to be uintmax_t, but changing it to size_t
     119     made plain 'cmp' 90% faster (GCC 4.8.1, x86).  */
     120  
     121  #ifndef word
     122  # define word size_t
     123  #endif
     124  
     125  /* The signed integer type of a line number.  Since files are read
     126     into main memory, ptrdiff_t should be wide enough.  pI is for
     127     printing line numbers.  */
     128  
     129  typedef ptrdiff_t lin;
     130  #define LIN_MAX PTRDIFF_MAX
     131  #define pI "t"
     132  
     133  /* Limit so that 2 * CONTEXT + 1 does not overflow.  */
     134  
     135  #define CONTEXT_MAX ((LIN_MAX - 1) / 2)
     136  
     137  
     138  /* This section contains POSIX-compliant defaults for macros
     139     that are meant to be overridden by hand in config.h as needed.  */
     140  
     141  #ifndef file_name_cmp
     142  # define file_name_cmp strcmp
     143  #endif
     144  
     145  #ifndef initialize_main
     146  # define initialize_main(argcp, argvp)
     147  #endif
     148  
     149  #ifndef NULL_DEVICE
     150  # define NULL_DEVICE "/dev/null"
     151  #endif
     152  
     153  /* Do struct stat *S, *T describe the same special file?  */
     154  #ifndef same_special_file
     155  # if HAVE_STRUCT_STAT_ST_RDEV && defined S_ISBLK && defined S_ISCHR
     156  #  define same_special_file(s, t) \
     157       (((S_ISBLK ((s)->st_mode) && S_ISBLK ((t)->st_mode)) \
     158         || (S_ISCHR ((s)->st_mode) && S_ISCHR ((t)->st_mode))) \
     159        && (s)->st_rdev == (t)->st_rdev)
     160  # else
     161  #  define same_special_file(s, t) 0
     162  # endif
     163  #endif
     164  
     165  /* Do struct stat *S, *T describe the same file?  Answer -1 if unknown.  */
     166  #ifndef same_file
     167  # define same_file(s, t) \
     168      ((((s)->st_ino == (t)->st_ino) && ((s)->st_dev == (t)->st_dev)) \
     169       || same_special_file (s, t))
     170  #endif
     171  
     172  /* Do struct stat *S, *T have the same file attributes?
     173  
     174     POSIX says that two files are identical if st_ino and st_dev are
     175     the same, but many file systems incorrectly assign the same (device,
     176     inode) pair to two distinct files, including:
     177  
     178     - GNU/Linux NFS servers that export all local file systems as a
     179       single NFS file system, if a local device number (st_dev) exceeds
     180       255, or if a local inode number (st_ino) exceeds 16777215.
     181  
     182     - Network Appliance NFS servers in snapshot directories; see
     183       Network Appliance bug #195.
     184  
     185     - ClearCase MVFS; see bug id ATRia04618.
     186  
     187     Check whether two files that purport to be the same have the same
     188     attributes, to work around instances of this common bug.  Do not
     189     inspect all attributes, only attributes useful in checking for this
     190     bug.
     191  
     192     It's possible for two distinct files on a buggy file system to have
     193     the same attributes, but it's not worth slowing down all
     194     implementations (or complicating the configuration) to cater to
     195     these rare cases in buggy implementations.  */
     196  
     197  #ifndef same_file_attributes
     198  # define same_file_attributes(s, t) \
     199     ((s)->st_mode == (t)->st_mode \
     200      && (s)->st_nlink == (t)->st_nlink \
     201      && (s)->st_uid == (t)->st_uid \
     202      && (s)->st_gid == (t)->st_gid \
     203      && (s)->st_size == (t)->st_size \
     204      && (s)->st_mtime == (t)->st_mtime \
     205      && (s)->st_ctime == (t)->st_ctime)
     206  #endif
     207  
     208  #define STREQ(a, b) (strcmp (a, b) == 0)