xref: /dragonfly/contrib/diffutils/src/system.h (revision 7ff0fc30)
1 /* System dependent declarations.
2 
3    Copyright (C) 1988-1989, 1992-1995, 1998, 2001-2002, 2004, 2006, 2009-2013,
4    2015-2018 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 lint
25 # define IF_LINT(Code) Code
26 #else
27 # define IF_LINT(Code) /* empty */
28 #endif
29 
30 /* Define '__attribute__' and 'volatile' first
31    so that they're used consistently in all system includes.  */
32 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
33 # define __attribute__(x)
34 #endif
35 
36 #include <verify.h>
37 
38 #include <sys/types.h>
39 
40 #include <sys/stat.h>
41 #include "stat-macros.h"
42 
43 #ifndef STAT_BLOCKSIZE
44 # if HAVE_STRUCT_STAT_ST_BLKSIZE
45 #  define STAT_BLOCKSIZE(s) ((s).st_blksize)
46 # else
47 #  define STAT_BLOCKSIZE(s) (8 * 1024)
48 # endif
49 #endif
50 
51 #include <unistd.h>
52 
53 #include <fcntl.h>
54 #include <time.h>
55 
56 #include <sys/wait.h>
57 
58 #include <dirent.h>
59 #ifndef _D_EXACT_NAMLEN
60 # define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
61 #endif
62 
63 #include <stdlib.h>
64 #define EXIT_TROUBLE 2
65 
66 #include <limits.h>
67 #include <locale.h>
68 #include <stddef.h>
69 #include <inttypes.h>
70 
71 #include <string.h>
72 #if ! HAVE_STRCASECOLL
73 # if HAVE_STRICOLL || defined stricoll
74 #  define strcasecoll(a, b) stricoll (a, b)
75 # else
76 #  define strcasecoll(a, b) strcasecmp (a, b) /* best we can do */
77 # endif
78 #endif
79 #if ! (HAVE_STRCASECMP || defined strcasecmp)
80 int strcasecmp (char const *, char const *);
81 #endif
82 
83 #include <gettext.h>
84 #if ! ENABLE_NLS
85 # undef textdomain
86 # define textdomain(Domainname) /* empty */
87 # undef bindtextdomain
88 # define bindtextdomain(Domainname, Dirname) /* empty */
89 #endif
90 
91 #define _(msgid) gettext (msgid)
92 #define N_(msgid) msgid
93 
94 #include <ctype.h>
95 
96 /* ISDIGIT differs from isdigit, as follows:
97    - Its arg may be any int or unsigned int; it need not be an unsigned char.
98    - It's guaranteed to evaluate its argument exactly once.
99    - It's typically faster.
100    POSIX 1003.1-2001 says that only '0' through '9' are digits.
101    Prefer ISDIGIT to isdigit unless it's important to use the locale's
102    definition of 'digit' even when the host does not conform to POSIX.  */
103 #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
104 
105 #include <errno.h>
106 
107 #include <signal.h>
108 #if !defined SIGCHLD && defined SIGCLD
109 # define SIGCHLD SIGCLD
110 #endif
111 
112 #undef MIN
113 #undef MAX
114 #define MIN(a, b) ((a) <= (b) ? (a) : (b))
115 #define MAX(a, b) ((a) >= (b) ? (a) : (b))
116 
117 #include <stdbool.h>
118 #include <intprops.h>
119 #include "propername.h"
120 #include "version.h"
121 
122 /* Type used for fast comparison of several bytes at a time.
123    This used to be uintmax_t, but changing it to size_t
124    made plain 'cmp' 90% faster (GCC 4.8.1, x86).  */
125 
126 #ifndef word
127 # define word size_t
128 #endif
129 
130 /* The signed integer type of a line number.  Since files are read
131    into main memory, ptrdiff_t should be wide enough.  */
132 
133 typedef ptrdiff_t lin;
134 #define LIN_MAX PTRDIFF_MAX
135 
136 /* The signed integer type for printing line numbers, and its printf
137    length modifier.  This is not simply ptrdiff_t, to cater to older
138    and/or nonstandard C libraries where "l" works but "ll" and "t" do
139    not, or where 'long' is too narrow and "ll" works but "t" does not.  */
140 
141 #if LIN_MAX <= LONG_MAX
142 typedef long int printint;
143 # define pI "l"
144 #elif LIN_MAX <= LLONG_MAX
145 typedef long long int printint;
146 # define pI "ll"
147 #else
148 typedef ptrdiff_t printint;
149 # define pI "t"
150 #endif
151 
152 verify (TYPE_SIGNED (lin));
153 verify (TYPE_SIGNED (printint));
154 verify (LIN_MAX == TYPE_MAXIMUM (lin));
155 verify (LIN_MAX <= TYPE_MAXIMUM (printint));
156 
157 /* Limit so that 2 * CONTEXT + 1 does not overflow.  */
158 
159 #define CONTEXT_MAX ((LIN_MAX - 1) / 2)
160 
161 
162 /* This section contains POSIX-compliant defaults for macros
163    that are meant to be overridden by hand in config.h as needed.  */
164 
165 #ifndef file_name_cmp
166 # define file_name_cmp strcmp
167 #endif
168 
169 #ifndef initialize_main
170 # define initialize_main(argcp, argvp)
171 #endif
172 
173 #ifndef NULL_DEVICE
174 # define NULL_DEVICE "/dev/null"
175 #endif
176 
177 /* Do struct stat *S, *T describe the same special file?  */
178 #ifndef same_special_file
179 # if HAVE_STRUCT_STAT_ST_RDEV && defined S_ISBLK && defined S_ISCHR
180 #  define same_special_file(s, t) \
181      (((S_ISBLK ((s)->st_mode) && S_ISBLK ((t)->st_mode)) \
182        || (S_ISCHR ((s)->st_mode) && S_ISCHR ((t)->st_mode))) \
183       && (s)->st_rdev == (t)->st_rdev)
184 # else
185 #  define same_special_file(s, t) 0
186 # endif
187 #endif
188 
189 /* Do struct stat *S, *T describe the same file?  Answer -1 if unknown.  */
190 #ifndef same_file
191 # define same_file(s, t) \
192     ((((s)->st_ino == (t)->st_ino) && ((s)->st_dev == (t)->st_dev)) \
193      || same_special_file (s, t))
194 #endif
195 
196 /* Do struct stat *S, *T have the same file attributes?
197 
198    POSIX says that two files are identical if st_ino and st_dev are
199    the same, but many file systems incorrectly assign the same (device,
200    inode) pair to two distinct files, including:
201 
202    - GNU/Linux NFS servers that export all local file systems as a
203      single NFS file system, if a local device number (st_dev) exceeds
204      255, or if a local inode number (st_ino) exceeds 16777215.
205 
206    - Network Appliance NFS servers in snapshot directories; see
207      Network Appliance bug #195.
208 
209    - ClearCase MVFS; see bug id ATRia04618.
210 
211    Check whether two files that purport to be the same have the same
212    attributes, to work around instances of this common bug.  Do not
213    inspect all attributes, only attributes useful in checking for this
214    bug.
215 
216    It's possible for two distinct files on a buggy file system to have
217    the same attributes, but it's not worth slowing down all
218    implementations (or complicating the configuration) to cater to
219    these rare cases in buggy implementations.  */
220 
221 #ifndef same_file_attributes
222 # define same_file_attributes(s, t) \
223    ((s)->st_mode == (t)->st_mode \
224     && (s)->st_nlink == (t)->st_nlink \
225     && (s)->st_uid == (t)->st_uid \
226     && (s)->st_gid == (t)->st_gid \
227     && (s)->st_size == (t)->st_size \
228     && (s)->st_mtime == (t)->st_mtime \
229     && (s)->st_ctime == (t)->st_ctime)
230 #endif
231 
232 #define STREQ(a, b) (strcmp (a, b) == 0)
233 
234 #ifndef FALLTHROUGH
235 # if __GNUC__ < 7
236 #  define FALLTHROUGH ((void) 0)
237 # else
238 #  define FALLTHROUGH __attribute__ ((__fallthrough__))
239 # endif
240 #endif
241