system.h revision 26801
1/* system-dependent definitions for CVS.
2   Copyright (C) 1989-1992 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.  */
13
14#include <sys/types.h>
15#include <sys/stat.h>
16
17#ifdef STAT_MACROS_BROKEN
18#undef S_ISBLK
19#undef S_ISCHR
20#undef S_ISDIR
21#undef S_ISREG
22#undef S_ISFIFO
23#undef S_ISLNK
24#undef S_ISSOCK
25#undef S_ISMPB
26#undef S_ISMPC
27#undef S_ISNWK
28#endif
29
30/* Not all systems have S_IFMT, but we probably want to use it if we
31   do.  See ChangeLog for a more detailed discussion. */
32
33#if !defined(S_ISBLK) && defined(S_IFBLK)
34# if defined(S_IFMT)
35# define	S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
36# else
37# define S_ISBLK(m) ((m) & S_IFBLK)
38# endif
39#endif
40
41#if !defined(S_ISCHR) && defined(S_IFCHR)
42# if defined(S_IFMT)
43# define	S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
44# else
45# define S_ISCHR(m) ((m) & S_IFCHR)
46# endif
47#endif
48
49#if !defined(S_ISDIR) && defined(S_IFDIR)
50# if defined(S_IFMT)
51# define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
52# else
53# define S_ISDIR(m) ((m) & S_IFDIR)
54# endif
55#endif
56
57#if !defined(S_ISREG) && defined(S_IFREG)
58# if defined(S_IFMT)
59# define	S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
60# else
61# define S_ISREG(m) ((m) & S_IFREG)
62# endif
63#endif
64
65#if !defined(S_ISFIFO) && defined(S_IFIFO)
66# if defined(S_IFMT)
67# define	S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
68# else
69# define S_ISFIFO(m) ((m) & S_IFIFO)
70# endif
71#endif
72
73#if !defined(S_ISLNK) && defined(S_IFLNK)
74# if defined(S_IFMT)
75# define	S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
76# else
77# define S_ISLNK(m) ((m) & S_IFLNK)
78# endif
79#endif
80
81#if !defined(S_ISSOCK) && defined(S_IFSOCK)
82# if defined(S_IFMT)
83# define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
84# else
85# define S_ISSOCK(m) ((m) & S_IFSOCK)
86# endif
87#endif
88
89#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
90# if defined(S_IFMT)
91# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
92# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
93# else
94# define S_ISMPB(m) ((m) & S_IFMPB)
95# define S_ISMPC(m) ((m) & S_IFMPC)
96# endif
97#endif
98
99#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
100# if defined(S_IFMT)
101# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
102# else
103# define S_ISNWK(m) ((m) & S_IFNWK)
104# endif
105#endif
106
107#ifdef NEED_DECOY_PERMISSIONS        /* OS/2, really */
108
109#define	S_IRUSR S_IREAD
110#define	S_IWUSR S_IWRITE
111#define	S_IXUSR S_IEXEC
112#define	S_IRWXU	(S_IRUSR | S_IWUSR | S_IXUSR)
113#define	S_IRGRP S_IREAD
114#define	S_IWGRP S_IWRITE
115#define	S_IXGRP S_IEXEC
116#define	S_IRWXG	(S_IRGRP | S_IWGRP | S_IXGRP)
117#define	S_IROTH S_IREAD
118#define	S_IWOTH S_IWRITE
119#define	S_IXOTH S_IEXEC
120#define	S_IRWXO	(S_IROTH | S_IWOTH | S_IXOTH)
121
122#else /* ! NEED_DECOY_PERMISSIONS */
123
124#ifndef S_IRUSR
125#define	S_IRUSR 0400
126#define	S_IWUSR 0200
127#define	S_IXUSR 0100
128/* Read, write, and execute by owner.  */
129#define	S_IRWXU	(S_IRUSR|S_IWUSR|S_IXUSR)
130
131#define	S_IRGRP	(S_IRUSR >> 3)	/* Read by group.  */
132#define	S_IWGRP	(S_IWUSR >> 3)	/* Write by group.  */
133#define	S_IXGRP	(S_IXUSR >> 3)	/* Execute by group.  */
134/* Read, write, and execute by group.  */
135#define	S_IRWXG	(S_IRWXU >> 3)
136
137#define	S_IROTH	(S_IRGRP >> 3)	/* Read by others.  */
138#define	S_IWOTH	(S_IWGRP >> 3)	/* Write by others.  */
139#define	S_IXOTH	(S_IXGRP >> 3)	/* Execute by others.  */
140/* Read, write, and execute by others.  */
141#define	S_IRWXO	(S_IRWXG >> 3)
142#endif /* !def S_IRUSR */
143#endif /* NEED_DECOY_PERMISSIONS */
144
145#if defined(POSIX) || defined(HAVE_UNISTD_H)
146#include <unistd.h>
147#include <limits.h>
148#else
149off_t lseek ();
150#endif
151
152#if TIME_WITH_SYS_TIME
153# include <sys/time.h>
154# include <time.h>
155#else
156# if HAVE_SYS_TIME_H
157#  include <sys/time.h>
158# else
159#  include <time.h>
160# endif
161#endif
162
163#ifdef HAVE_IO_H
164#include <io.h>
165#endif
166
167#ifdef HAVE_DIRECT_H
168#include <direct.h>
169#endif
170
171#ifdef timezone
172#undef timezone /* needed for sgi */
173#endif
174
175#ifdef HAVE_SYS_TIMEB_H
176#include <sys/timeb.h>
177#else
178struct timeb {
179    time_t		time;		/* Seconds since the epoch	*/
180    unsigned short	millitm;	/* Field not used		*/
181    short		timezone;
182    short		dstflag;	/* Field not used		*/
183};
184#endif
185
186#if !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE)
187#if !defined(timezone)
188extern long timezone;
189#endif
190#endif
191
192
193/*
194**  MAXPATHLEN and PATH_MAX
195**
196**     On most systems MAXPATHLEN is defined in sys/param.h to be 1024. Of
197**     those that this is not true, again most define PATH_MAX in limits.h
198**     or sys/limits.h which usually gets included by limits.h. On the few
199**     remaining systems that neither statement is true, _POSIX_PATH_MAX
200**     is defined.
201**
202**     So:
203**         1. If PATH_MAX is defined just use it.
204**         2. If MAXPATHLEN is defined but not PATH_MAX, then define
205**            PATH_MAX in terms of MAXPATHLEN.
206**         3. If neither is defined, include limits.h and check for
207**            PATH_MAX again.
208**         3.1 If we now have PATHSIZE, define PATH_MAX in terms of that.
209**             and ignore the rest.  Since _POSIX_PATH_MAX (checked for
210**             next) is the *most* restrictive (smallest) value, if we
211**             trust _POSIX_PATH_MAX, several of our buffers are too small.
212**         4. If PATH_MAX is still not defined but _POSIX_PATH_MAX is,
213**            then define PATH_MAX in terms of _POSIX_PATH_MAX.
214**         5. And if even _POSIX_PATH_MAX doesn't exist just put in
215**            a reasonable value.
216**         *. All in all, this is an excellent argument for using pathconf()
217**            when at all possible.  Or better yet, dynamically allocate
218**            our buffers and use getcwd() not getwd().
219**
220**     This works on:
221**         Sun Sparc 10        SunOS 4.1.3  &  Solaris 1.2
222**         HP 9000/700         HP/UX 8.07   &  HP/UX 9.01
223**         Tektronix XD88/10   UTekV 3.2e
224**         IBM RS6000          AIX 3.2
225**         Dec Alpha           OSF 1 ????
226**         Intel 386           BSDI BSD/386
227**         Intel 386           SCO OpenServer Release 5
228**         Apollo              Domain 10.4
229**         NEC                 SVR4
230*/
231
232/* On MOST systems this will get you MAXPATHLEN.
233   Windows NT doesn't have this file, tho.  */
234#ifdef HAVE_SYS_PARAM_H
235#include <sys/param.h>
236#endif
237
238#ifndef PATH_MAX
239#  ifdef MAXPATHLEN
240#    define PATH_MAX                 MAXPATHLEN
241#  else
242#    include <limits.h>
243#    ifndef PATH_MAX
244#      ifdef PATHSIZE
245#         define PATH_MAX               PATHSIZE
246#      else /* no PATHSIZE */
247#        ifdef _POSIX_PATH_MAX
248#          define PATH_MAX             _POSIX_PATH_MAX
249#        else
250#          define PATH_MAX             1024
251#        endif  /* no _POSIX_PATH_MAX */
252#      endif  /* no PATHSIZE */
253#    endif /* no PATH_MAX   */
254#  endif  /* MAXPATHLEN */
255#endif  /* PATH_MAX   */
256
257
258/* The NeXT (without _POSIX_SOURCE, which we don't want) has a utime.h
259   which doesn't define anything.  It would be cleaner to have configure
260   check for struct utimbuf, but for now I'm checking NeXT here (so I don't
261   have to debug the configure check across all the machines).  */
262#if defined (HAVE_UTIME_H) && !defined (NeXT)
263#  include <utime.h>
264#else
265#  if defined (HAVE_SYS_UTIME_H)
266#    include <sys/utime.h>
267#  else
268#    ifndef ALTOS
269struct utimbuf
270{
271  long actime;
272  long modtime;
273};
274#    endif
275int utime ();
276#  endif
277#endif
278
279#if STDC_HEADERS || HAVE_STRING_H
280#  include <string.h>
281   /* An ANSI string.h and pre-ANSI memory.h might conflict. */
282#  if !STDC_HEADERS && HAVE_MEMORY_H
283#    include <memory.h>
284#  endif /* not STDC_HEADERS and HAVE_MEMORY_H */
285#else /* not STDC_HEADERS and not HAVE_STRING_H */
286#  include <strings.h>
287   /* memory.h and strings.h conflict on some systems. */
288#endif /* not STDC_HEADERS and not HAVE_STRING_H */
289
290#ifndef ERRNO_H_MISSING
291#include <errno.h>
292#endif
293
294/* Not all systems set the same error code on a non-existent-file
295   error.  This tries to ask the question somewhat portably.
296   On systems that don't have ENOTEXIST, this should behave just like
297   x == ENOENT.  "x" is probably errno, of course. */
298
299#ifdef ENOTEXIST
300#  ifdef EOS2ERR
301#    define existence_error(x) \
302     (((x) == ENOTEXIST) || ((x) == ENOENT) || ((x) == EOS2ERR))
303#  else
304#    define existence_error(x) \
305     (((x) == ENOTEXIST) || ((x) == ENOENT))
306#  endif
307#else
308#  ifdef EVMSERR
309#     define existence_error(x) \
310((x) == ENOENT || (x) == EINVAL || (x) == EVMSERR)
311#  else
312#    define existence_error(x) ((x) == ENOENT)
313#  endif
314#endif
315
316
317#ifdef STDC_HEADERS
318#include <stdlib.h>
319#else
320char *getenv ();
321char *malloc ();
322char *realloc ();
323char *calloc ();
324extern int errno;
325#endif
326
327/* SunOS4 apparently does not define this in stdlib.h.  */
328#ifndef EXIT_FAILURE
329#define EXIT_FAILURE 1
330#endif
331
332#if defined(USG) || defined(POSIX)
333char *getcwd ();
334#else
335char *getwd ();
336#endif
337
338/* check for POSIX signals */
339#if defined(HAVE_SIGACTION) && defined(HAVE_SIGPROCMASK)
340# define POSIX_SIGNALS
341#endif
342
343/* MINIX 1.6 doesn't properly support sigaction */
344#if defined(_MINIX)
345# undef POSIX_SIGNALS
346#endif
347
348/* If !POSIX, try for BSD.. Reason: 4.4BSD implements these as wrappers */
349#if !defined(POSIX_SIGNALS)
350# if defined(HAVE_SIGVEC) && defined(HAVE_SIGSETMASK) && defined(HAVE_SIGBLOCK)
351#  define BSD_SIGNALS
352# endif
353#endif
354
355/* Under OS/2, this must be included _after_ stdio.h; that's why we do
356   it here. */
357#ifdef USE_OWN_TCPIP_H
358#include "tcpip.h"
359#endif
360
361#ifdef HAVE_FCNTL_H
362#include <fcntl.h>
363#else
364#include <sys/file.h>
365#endif
366
367#ifndef SEEK_SET
368#define SEEK_SET 0
369#define SEEK_CUR 1
370#define SEEK_END 2
371#endif
372
373#ifndef F_OK
374#define F_OK 0
375#define X_OK 1
376#define W_OK 2
377#define R_OK 4
378#endif
379
380#if HAVE_DIRENT_H
381# include <dirent.h>
382# define NAMLEN(dirent) strlen((dirent)->d_name)
383#else
384# define dirent direct
385# define NAMLEN(dirent) (dirent)->d_namlen
386# if HAVE_SYS_NDIR_H
387#  include <sys/ndir.h>
388# endif
389# if HAVE_SYS_DIR_H
390#  include <sys/dir.h>
391# endif
392# if HAVE_NDIR_H
393#  include <ndir.h>
394# endif
395#endif
396
397/* Convert B 512-byte blocks to kilobytes if K is nonzero,
398   otherwise return it unchanged. */
399#define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b))
400
401#ifndef S_ISLNK
402#define lstat stat
403#endif
404
405/*
406 * Some UNIX distributions don't include these in their stat.h Defined here
407 * because "config.h" is always included last.
408 */
409#ifndef S_IWRITE
410#define	S_IWRITE	0000200		/* write permission, owner */
411#endif
412#ifndef S_IWGRP
413#define	S_IWGRP		0000020		/* write permission, grougroup */
414#endif
415#ifndef S_IWOTH
416#define	S_IWOTH		0000002		/* write permission, other */
417#endif
418
419/* Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many filesystem
420   calls take  only one argument; permission is handled very differently on
421   those systems than in Unix.  So we leave such systems a hook on which they
422   can hang their own definitions.  */
423
424#ifndef CVS_ACCESS
425#define CVS_ACCESS access
426#endif
427
428#ifndef CVS_CHDIR
429#define CVS_CHDIR chdir
430#endif
431
432#ifndef CVS_CREAT
433#define CVS_CREAT creat
434#endif
435
436#ifndef CVS_FOPEN
437#define CVS_FOPEN fopen
438#endif
439
440#ifndef CVS_MKDIR
441#define CVS_MKDIR mkdir
442#endif
443
444#ifndef CVS_OPEN
445#define CVS_OPEN open
446#endif
447
448#ifndef CVS_OPENDIR
449#define CVS_OPENDIR opendir
450#endif
451
452#ifndef CVS_RENAME
453#define CVS_RENAME rename
454#endif
455
456#ifndef CVS_RMDIR
457#define CVS_RMDIR rmdir
458#endif
459
460#ifndef CVS_STAT
461#define CVS_STAT stat
462#endif
463
464#ifndef CVS_UNLINK
465#define CVS_UNLINK unlink
466#endif
467
468/* Wildcard matcher.  Should be case-insensitive if the system is.  */
469#ifndef CVS_FNMATCH
470#define CVS_FNMATCH fnmatch
471#endif
472
473/* Some file systems are case-insensitive.  If FOLD_FN_CHAR is
474   #defined, it maps the character C onto its "canonical" form.  In a
475   case-insensitive system, it would map all alphanumeric characters
476   to lower case.  Under Windows NT, / and \ are both path component
477   separators, so FOLD_FN_CHAR would map them both to /.  */
478#ifndef FOLD_FN_CHAR
479#define FOLD_FN_CHAR(c) (c)
480#define fnfold(filename) (filename)
481#define fncmp strcmp
482#endif
483
484/* Different file systems have different path component separators.
485   For the VMS port we might need to abstract further back than this.  */
486#ifndef ISDIRSEP
487#define ISDIRSEP(c) ((c) == '/')
488#endif
489
490
491/* On some systems, lines in text files should be terminated with CRLF,
492   not just LF, and the read and write routines do this translation
493   for you.  LINES_CRLF_TERMINATED is #defined on such systems.
494   - OPEN_BINARY is the flag to pass to the open function for
495     untranslated I/O.
496   - FOPEN_BINARY_READ is the string to pass to fopen to get
497     untranslated reading.
498   - FOPEN_BINARY_WRITE is the string to pass to fopen to get
499     untranslated writing.  */
500#if LINES_CRLF_TERMINATED
501#define OPEN_BINARY (O_BINARY)
502#define FOPEN_BINARY_READ ("rb")
503#define FOPEN_BINARY_WRITE ("wb")
504#else
505#define OPEN_BINARY (0)
506#define FOPEN_BINARY_READ ("r")
507#define FOPEN_BINARY_WRITE ("w")
508#endif
509