NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: standards/58275: tentative fix
The following reply was made to PR standards/58275; it has been noted by GNATS.
From: Guilherme Janczak <guilherme.janczak%yandex.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: standards/58275: tentative fix
Date: Fri, 24 May 2024 19:34:47 +0000
I'm working on a fix. It's incomplete and I haven't tested it at all, so
it's certainly not ready for merge, but before going further, I'd like a
NetBSD developer's opinion.
The idea of this diff follows the gist of my suggested fix, learn from
FreeBSD and OpenBSD's solutions.
We define __$standard_VISIBLE internal use macros corresponding to
NetBSD, X/Open, POSIX, and C which are set according to the feature test
macros defined by the user, making sure that broader standards imply
narrower ones:
If the user defines _NETBSD_SOURCE, __NBSD_VISIBLE is defined
internally. If __NBSD_VISIBLE is defined, the latest __XOPEN_VISIBLE is
implied. If __XOPEN_VISIBLE is defined, it implies a respective
__POSIX_VISIBLE value. If __POSIX_VISIBLE is defined, it implies a
respective __ISO_C_VISIBLE value.
Likewise, Defining a narrower feature test macro such as
_POSIX_C_SOURCE will define appropriate __POSIX_VISIBLE
and __ISO_C_VISIBLE values.
This means that headers only need to check for the narrowest standard
that defines a symbol, unless a a narrower standard adopts a function
from a broader standard, then you need to check if either is the
appropriate version. The rest is implicit. Edge cases like functions
removed from standards but kept in NetBSD are easy to handle, simply
check if either the appropriate standard visibility is within a certain
range or __NBSD_VISIBLE is defined. Conflicts between NetBSD and
standards are checked by looking at which standard feature test macros
the user defined explicitly. Here are some examples:
setegid() was added in POSIX-2001. There is no need to check for
__XOPEN_VISIBLE or __NETBSD_VISIBLE here because they imply appropriate
__POSIX_VISIBLE values:
#if __POSIX_VISIBLE >= 200112
int setegid(gid_t);
#endif
symlink() was added in XPGv4.2 and adopted as part of the POSIX base
standard in POSIX-2001. We need to check for both __XOPEN_VISIBLE and
__POSIX_VISIBLE here because the function was initially added by X/Open,
and later made mandatory in POSIX:
#if __XOPEN_VISIBLE >= 420 || __POSIX_VISIBLE >= 200112
int symlink(const char *, const char *);
#endif
gethostid() was added in XPGv4.2 and remains part of the XSI option in
POSIX. We only check for __XOPEN_VISIBLE, we don't need to check for
__NETBSD_VISIBLE because it implies the latest __XOPEN_VISIBLE:
#if __XOPEN_VISIBLE >= 420
long gethostid(void);
#endif
ualarm() was added in XPG4.2, became part of the XSI option from POSIX
in POSIX-2001, and was removed from POSIX in POSIX-2008. NetBSD retains
it:
#if __XOPEN_VISIBLE >= 420 && __XOPEN_VISIBLE < 700 || defined(__NBSD_VISIBLE)
useconds_t ualarm(useconds_t, useconds_t);
#endif
NetBSD contains standard and nonstandard versions of lchown().
We first check if the function should be visible. Then we peek into the
standard feature test macros to see why they're visible, and pick
between the standard or NetBSD standard version as appropriate:
+#if __XOPEN_VISIBLE >= 420 || __POSIX_VISIBLE >= 200809
#if defined(_XOPEN_SOURCE) || defined(_POSIX_C_SOURCE)
int lchown(const char *, uid_t, gid_t) __RENAME(__posix_lchown);
#else
int lchown(const char *, uid_t, gid_t);
#endif
This diff already fixes a LOT of bugs as is. Many, many functions aren't
visible when they should, or are visible when they shouldn't. The
comment explaining standard feature test macros in sys/sys/featuretest.h
contained incorrect information. There are lots of other inconsequential
changes, for instance, I commented the code that figures out which
standards to make available with links to free and legal online copies
of the standards; some of the visibility bugs suggest the developers
relied on 2nd sourced information or haven't read the standards (finding
them can definitely be hard and some weren't originally available for
free), so those links are vital.
I think it's evident this new approach is a lot simpler and less error
prone than the current one. It should also be less lines of code once
more headers are migrated to the new approach.
I'd like to ask if this design needs any changes and if there's any bug
for bug compatibility I need to keep. For instance, I already noticed
NetBSD lacks a standards-compliant version of setpgrp(), using the
NetBSD version isn't even binary compatible with the standard one:
NetBSD: int setpgrp(pid_t, pid_t);
POSIX: pid_t setpgrp(void);
NetBSD declares its nonstandard version where a standard one should be,
I made it so it's only declared if _NETBSD_SOURCE is defined by the
user.
If i get the go ahead I'll figure out how to test this (I guess
compiling all of NetBSD's base is a good start?) and try to get the
processs started with just unistd.h and featuretest.h, other headers to
follow later so maybe other people can have a hand at it too, I'm not
sure if I even have the skills to do this for all headers.
Index: include/unistd.h
===================================================================
RCS file: /cvsroot/src/include/unistd.h,v
retrieving revision 1.164
diff -u -p -u -p -r1.164 unistd.h
--- include/unistd.h 19 Jan 2024 18:40:35 -0000 1.164
+++ include/unistd.h 24 May 2024 17:48:42 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: unistd.h,v 1.164 2024/01/19 18:40:35 christos Exp $ */
+/* $NetBSD: unistd.h,v 1.166 2024/05/20 01:30:33 christos Exp $ */
/*-
* Copyright (c) 1998, 1999, 2008 The NetBSD Foundation, Inc.
@@ -81,25 +81,175 @@
#define STDOUT_FILENO 1 /* standard output file descriptor */
#define STDERR_FILENO 2 /* standard error file descriptor */
+#define F_ULOCK 0
+#define F_LOCK 1
+#define F_TLOCK 2
+#define F_TEST 3
+
#include <sys/null.h>
__BEGIN_DECLS
+
+#if __POSIX_VISIBLE >= 200809
+int linkat(int, const char *, int, const char *, int);
+int renameat(int, const char *, int, const char *);
+int faccessat(int, const char *, int, int);
+int fchownat(int, const char *, uid_t, gid_t, int);
+ssize_t readlinkat(int, const char *, char *, size_t);
+int symlinkat(const char *, int, const char *);
+int unlinkat(int, const char *, int);
+int fexecve(int, char * const *, char * const *);
+#endif
+
+#if __POSIX_VISIBLE >= 200112
+int setegid(gid_t);
+int seteuid(uid_t);
+
+# ifndef _BSD_INTPTR_T_
+# define _BSD_INTPTR_T_
+typedef __intptr_t intptr_t;
+# endif
+#endif
+
+#if __XOPEN_VISIBLE >= 520
+int gethostname(char *, size_t);
+#endif
+
+#if __XOPEN_VISIBLE >= 500 || __POSIX_VISIBLE >= 200809L
+ssize_t pread(int, void *, size_t, off_t);
+ssize_t pwrite(int, const void *, size_t, off_t);
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+int getlogin_r(char *, size_t);
+int ttyname_r(int, char *, size_t);
+int fdatasync(int);
+
+# ifndef __PTHREAD_ATFORK_DECLARED
+# define __PTHREAD_ATFORK_DECLARED
+int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+# endif
+#endif /* __POSIX_VISIBLE >= 199506 */
+
+#if __XOPEN_VISIBLE >= 420 || __POSIX_VISIBLE >= 200809
+pid_t getsid(pid_t);
+int fchdir(int);
+pid_t getpgid(pid_t);
+# if defined(_XOPEN_SOURCE) || defined(_POSIX_C_SOURCE)
+int lchown(const char *, uid_t, gid_t) __RENAME(__posix_lchown);
+# else
+int lchown(const char *, uid_t, gid_t);
+# endif
+#endif
+
+
+#if __XOPEN_VISIBLE >= 420 || __POSIX_VISIBLE >= 200112
+int symlink(const char *, const char *);
+void sync(void);
+
+# if defined(_XOPEN_SOURCE) || defined(_POSIX_C_SOURCE)
+int fchown(int, uid_t, gid_t) __RENAME(__posix_fchown);
+# else
+int fchown(int, uid_t, gid_t);
+# endif
+
+# if __SSP_FORTIFY_LEVEL == 0
+ssize_t readlink(const char * __restrict, char * __restrict, size_t);
+# endif
+#endif /* __XOPEN_VISIBLE >= 420 || __POSIX_VISIBLE >= 200112 */
+
+#if __XOPEN_VISIBLE >= 420
+long gethostid(void);
+int lockf(int, int, off_t);
+int setregid(gid_t, gid_t);
+int setreuid(uid_t, uid_t);
+#endif
+
+#if __XOPEN_VISIBLE >= 420 && __XOPEN_VISIBLE < 700 || defined(__NBSD_VISIBLE)
+useconds_t ualarm(useconds_t, useconds_t);
+int usleep(useconds_t);
+
+# ifndef __LIBC12_SOURCE__
+pid_t vfork(void) __RENAME(__vfork14) __returns_twice;
+# endif
+# ifndef __AUDIT__
+char *getwd(char *); /* obsoleted by getcwd() */
+# endif
+#endif /* __XOPEN_VISIBLE >= 420 && __XOPEN_VISIBLE < 700 || __NBSD_VISIBLE */
+
+/*
+ * The following three syscalls are also defined in <sys/types.h>
+ * We protect them against double declarations.
+ */
+#ifndef __OFF_T_SYSCALLS_DECLARED
+#define __OFF_T_SYSCALLS_DECLARED
+off_t lseek(int, off_t, int);
+int truncate(const char *, off_t);
+
+# if __XOPEN_VISIBLE >= 420 || __POSIX_VISIBLE >= 199309
+int ftruncate(int, off_t);
+# endif
+#endif /* !defined(__OFF_T_SYSCALLS_DECLARED) */
+
+#if __POSIX_VISIBLE >= 199200
+size_t confstr(int, char *, size_t);
+#endif
+
+#if __POSIX_VISIBLE >= 199012 && __POSIX_VISIBLE < 200112 || \
+ defined(__NBSD_VISIBLE)
+# ifndef __CUSERID_DECLARED
+# define __CUSERID_DECLARED
+/* also declared in stdio.h */
+char *cuserid(char *);
+# endif
+#endif
+
+#if __POSIX_VISIBLE >= 199012 && \
+ (defined(_POSIX_C_SOURCE) || defined(_POSIX_SOURCE) || \
+ defined(_XOPEN_SOURCE))
+int chown(const char *, uid_t, gid_t) __RENAME(__posix_chown);
+#else
+int chown(const char *, uid_t, gid_t);
+#endif
+
+#if __XOPEN_VISIBLE >= 300 || __POSIX_VISIBLE >= 199309
+int fsync(int);
+#endif
+
+#if __XOPEN_VISIBLE >= 420 && __XOPEN_VISIBLE < 600 || defined(__NBSD_VISIBLE)
+int brk(void *);
+int getdtablesize(void);
+void *sbrk(intptr_t);
+#endif
+
+#if __XOPEN_VISIBLE >= 100
+int nice(int);
+__aconst char *crypt(const char *, const char *);
+int encrypt(char *, int);
+void swab(const void * __restrict, void * __restrict, ssize_t);
+#endif
+
+#if __XOPEN_VISIBLE >= 100 && __XOPEN_VISIBLE < 600 || defined(__NBSD_VISIBLE)
+int chroot(const char *);
+char *getpass(const char *);
+#endif
+
+#if __SSP_FORTIFY_LEVEL == 0
+char *getcwd(char *, size_t);
+ssize_t read(int, void *, size_t);
+#endif
+
+/* POSIX 1990 or 1988 functions below. */
+
+int getopt(int, char * const [], const char *);
+extern char *optarg; /* getopt(3) external variables */
+extern int opterr, optind, optopt;
+
__dead void _exit(int);
int access(const char *, int);
unsigned int alarm(unsigned int);
int chdir(const char *);
-#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE)
-int chown(const char *, uid_t, gid_t) __RENAME(__posix_chown);
-#else
-int chown(const char *, uid_t, gid_t);
-#endif /* defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) */
int close(int);
-size_t confstr(int, char *, size_t);
-#ifndef __CUSERID_DECLARED
-#define __CUSERID_DECLARED
-/* also declared in stdio.h */
-char *cuserid(char *); /* obsolete */
-#endif /* __CUSERID_DECLARED */
int dup(int);
int dup2(int, int);
int execl(const char *, const char *, ...) __null_sentinel;
@@ -110,15 +260,11 @@ int execve(const char *, char * const *
int execvp(const char *, char * const *);
pid_t fork(void);
long fpathconf(int, int);
-#if __SSP_FORTIFY_LEVEL == 0
-char *getcwd(char *, size_t);
-#endif
gid_t getegid(void);
uid_t geteuid(void);
gid_t getgid(void);
int getgroups(int, gid_t []);
__aconst char *getlogin(void);
-int getlogin_r(char *, size_t);
pid_t getpgrp(void);
pid_t getpid(void);
pid_t getppid(void);
@@ -128,9 +274,6 @@ int link(const char *, const char *);
long pathconf(const char *, int);
int pause(void);
int pipe(int *);
-#if __SSP_FORTIFY_LEVEL == 0
-ssize_t read(int, void *, size_t);
-#endif
int rmdir(const char *);
int setgid(gid_t);
int setpgid(pid_t, pid_t);
@@ -144,192 +287,18 @@ __aconst char *ttyname(int);
int unlink(const char *);
ssize_t write(int, const void *, size_t);
-
-/*
- * IEEE Std 1003.2-92, adopted in X/Open Portability Guide Issue 4 and later
- */
-#if (_POSIX_C_SOURCE - 0) >= 2 || defined(_XOPEN_SOURCE) || \
- defined(_NETBSD_SOURCE)
-int getopt(int, char * const [], const char *);
-
-extern char *optarg; /* getopt(3) external variables */
-extern int opterr;
-extern int optind;
-extern int optopt;
-#endif
-
-/*
- * The Open Group Base Specifications, Issue 5; IEEE Std 1003.1-2001 (POSIX)
- */
-#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 500 || \
- defined(_NETBSD_SOURCE)
-#if __SSP_FORTIFY_LEVEL == 0
-ssize_t readlink(const char * __restrict, char * __restrict, size_t);
-#endif
-#endif
-
-/*
- * The Open Group Base Specifications, Issue 6; IEEE Std 1003.1-2001 (POSIX)
- */
-#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 600 || \
- defined(_NETBSD_SOURCE)
-int setegid(gid_t);
-int seteuid(uid_t);
-#endif
-
-/*
- * The following three syscalls are also defined in <sys/types.h>
- * We protect them against double declarations.
- */
-#ifndef __OFF_T_SYSCALLS_DECLARED
-#define __OFF_T_SYSCALLS_DECLARED
-off_t lseek(int, off_t, int);
-int truncate(const char *, off_t);
-/*
- * IEEE Std 1003.1b-93,
- * also found in X/Open Portability Guide >= Issue 4 Version 2
- */
-#if (_POSIX_C_SOURCE - 0) >= 199309L || \
- (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \
- (_XOPEN_SOURCE - 0) >= 500 || defined(_NETBSD_SOURCE)
-int ftruncate(int, off_t);
-#endif
-#endif /* __OFF_T_SYSCALLS_DECLARED */
-
-
-/*
- * IEEE Std 1003.1b-93, adopted in X/Open CAE Specification Issue 5 Version 2
- */
-#if (_POSIX_C_SOURCE - 0) >= 199309L || (_XOPEN_SOURCE - 0) >= 500 || \
- defined(_NETBSD_SOURCE)
-int fdatasync(int);
-int fsync(int);
-#endif
-
-
-/*
- * IEEE Std 1003.1c-95, also adopted by X/Open CAE Spec Issue 5 Version 2
- */
-#if (_POSIX_C_SOURCE - 0) >= 199506L || (_XOPEN_SOURCE - 0) >= 500 || \
- defined(_REENTRANT) || defined(_NETBSD_SOURCE)
-int ttyname_r(int, char *, size_t);
-#ifndef __PTHREAD_ATFORK_DECLARED
-#define __PTHREAD_ATFORK_DECLARED
-int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
-#endif
-#endif
-
-/*
- * X/Open Portability Guide, all issues
- */
-#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
-int chroot(const char *);
-int nice(int);
-#endif
-
-
-/*
- * X/Open Portability Guide >= Issue 4
- */
-#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
-__aconst char *crypt(const char *, const char *);
-int encrypt(char *, int);
-char *getpass(const char *);
-#endif
-#if defined(_XOPEN_SOURCE) || (_POSIX_C_SOURCE - 0) >= 200809L || \
- defined(_NETBSD_SOURCE)
-pid_t getsid(pid_t);
-#endif
-
-
-/*
- * X/Open Portability Guide >= Issue 4 Version 2
- */
-#if (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \
- (_XOPEN_SOURCE - 0) >= 500 || defined(_NETBSD_SOURCE)
-#ifndef _BSD_INTPTR_T_
-typedef __intptr_t intptr_t;
-#define _BSD_INTPTR_T_
-#endif
-
-#define F_ULOCK 0
-#define F_LOCK 1
-#define F_TLOCK 2
-#define F_TEST 3
-
-int brk(void *);
-int fchdir(int);
-#if defined(_XOPEN_SOURCE)
-int fchown(int, uid_t, gid_t) __RENAME(__posix_fchown);
-#else
-int fchown(int, uid_t, gid_t);
-#endif
-int getdtablesize(void);
-long gethostid(void);
-int gethostname(char *, size_t);
-__pure int
- getpagesize(void); /* legacy */
-pid_t getpgid(pid_t);
-#if defined(_XOPEN_SOURCE)
-int lchown(const char *, uid_t, gid_t) __RENAME(__posix_lchown);
-#else
-int lchown(const char *, uid_t, gid_t);
-#endif
-int lockf(int, int, off_t);
-void *sbrk(intptr_t);
-/* XXX prototype wrong! */
-int setpgrp(pid_t, pid_t); /* obsoleted by setpgid() */
-int setregid(gid_t, gid_t);
-int setreuid(uid_t, uid_t);
-void swab(const void * __restrict, void * __restrict, ssize_t);
-int symlink(const char *, const char *);
-void sync(void);
-useconds_t ualarm(useconds_t, useconds_t);
-int usleep(useconds_t);
-#ifndef __LIBC12_SOURCE__
-pid_t vfork(void) __RENAME(__vfork14) __returns_twice;
-#endif
-
-#ifndef __AUDIT__
-char *getwd(char *); /* obsoleted by getcwd() */
-#endif
-#endif /* _XOPEN_SOURCE_EXTENDED || _XOPEN_SOURCE >= 500 || _NETBSD_SOURCE */
-
-
-/*
- * X/Open CAE Specification Issue 5 Version 2
- */
-#if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 500 || \
- defined(_NETBSD_SOURCE)
-ssize_t pread(int, void *, size_t, off_t);
-ssize_t pwrite(int, const void *, size_t, off_t);
-#endif /* (_POSIX_C_SOURCE - 0) >= 200112L || ... */
-
-/*
- * X/Open Extended API set 2 (a.k.a. C063)
- */
-#if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0 >= 700) || \
- defined(_NETBSD_SOURCE)
-int linkat(int, const char *, int, const char *, int);
-int renameat(int, const char *, int, const char *);
-int faccessat(int, const char *, int, int);
-int fchownat(int, const char *, uid_t, gid_t, int);
-ssize_t readlinkat(int, const char *, char *, size_t);
-int symlinkat(const char *, int, const char *);
-int unlinkat(int, const char *, int);
-int fexecve(int, char * const *, char * const *);
-#endif
-
-
/*
* Implementation-defined extensions
*/
-#if defined(_NETBSD_SOURCE)
+#ifdef __NBSD_VISIBLE
+int setpgrp(pid_t, pid_t); /* obsoleted by setpgid() */
int acct(const char *);
int closefrom(int);
int des_cipher(const char *, char *, long, int);
int des_setkey(const char *);
-int dup3(int, int, int);
+#ifndef __LIBC12_SOURCE__
+int dup3(int, int, int) __RENAME(__dup3100);
+#endif
void endusershell(void);
int exect(const char *, char * const *, char * const *);
int execvpe(const char *, char * const *, char * const *);
@@ -412,7 +381,7 @@ extern const char *const *sys_siglist __
#endif /* __SYS_SIGLIST_DECLARED */
extern int optreset; /* getopt(3) external variable */
extern char *suboptarg; /* getsubopt(3) external variable */
-#endif
+#endif /* defined(__NBSD_VISIBLE) */
#ifdef _LIBC_INTERNAL
pid_t __fork(void);
@@ -420,4 +389,5 @@ pid_t __locked_fork(int *) __weak;
#endif
__END_DECLS
+
#endif /* !_UNISTD_H_ */
Index: sys/sys/featuretest.h
===================================================================
RCS file: /cvsroot/src/sys/sys/featuretest.h,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 featuretest.h
--- sys/sys/featuretest.h 26 Apr 2013 18:29:06 -0000 1.10
+++ sys/sys/featuretest.h 24 May 2024 17:49:05 -0000
@@ -4,12 +4,32 @@
* Written by Klaus Klein <kleink%NetBSD.org@localhost>, February 2, 1998.
* Public domain.
*
- * NOTE: Do not protect this header against multiple inclusion. Doing
+ * NOTE: Do not protect these definitions against multiple inclusion. Doing
* so can have subtle side-effects due to header file inclusion order
* and testing of e.g. _POSIX_SOURCE vs. _POSIX_C_SOURCE. Instead,
* protect each CPP macro that we want to supply.
+ *
+ * The definitions which aren't currently protected by header guards are being
+ * phased out. Don't add any new unprotected code, and do not try to protect the
+ * unprotected code.
*/
+#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 1L
+#endif
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) && \
+ !defined(_XOPEN_SOURCE) && !defined(_NETBSD_SOURCE)
+#define _NETBSD_SOURCE 1
+#endif
+
+#if ((_POSIX_C_SOURCE - 0) >= 199506L || (_XOPEN_SOURCE - 0) >= 500) && \
+ !defined(_REENTRANT)
+#define _REENTRANT
+#endif
+
+#ifndef _SYS_FEATURETEST_H_
+#define _SYS_FEATURETEST_H_
/*
* Feature-test macros are defined by several standards, and allow an
* application to specify what symbols they want the system headers to
@@ -18,36 +38,36 @@
* specify complete standards, and if one of these is defined, header
* files will try to conform to the relevant standard. They are:
*
- * ANSI macros:
- * _ANSI_SOURCE ANSI C89
- *
- * POSIX macros:
- * _POSIX_SOURCE == 1 IEEE Std 1003.1 (version?)
- * _POSIX_C_SOURCE == 1 IEEE Std 1003.1-1990
- * _POSIX_C_SOURCE == 2 IEEE Std 1003.2-1992
- * _POSIX_C_SOURCE == 199309L IEEE Std 1003.1b-1993
- * _POSIX_C_SOURCE == 199506L ISO/IEC 9945-1:1996
- * _POSIX_C_SOURCE == 200112L IEEE Std 1003.1-2001
- * _POSIX_C_SOURCE == 200809L IEEE Std 1003.1-2008
+ * NetBSD macros:
+ * _NETBSD_SOURCE == 1 Declare all NetBSD symbols except strtonum().
+ * _OPENBSD_SOURCE == 1 Declare strtonum().
+ * _ANSI_SOURCE Declare only ANSI C89 symbols.
*
* X/Open macros:
- * _XOPEN_SOURCE System Interfaces and Headers, Issue 4, Ver 2
- * _XOPEN_SOURCE_EXTENDED == 1 XSH4.2 UNIX extensions
- * _XOPEN_SOURCE == 500 System Interfaces and Headers, Issue 5
- * _XOPEN_SOURCE == 520 Networking Services (XNS), Issue 5.2
- * _XOPEN_SOURCE == 600 IEEE Std 1003.1-2001, XSI option
* _XOPEN_SOURCE == 700 IEEE Std 1003.1-2008, XSI option
+ * _XOPEN_SOURCE == 600 IEEE Std 1003.1-2001, XSI option
+ * _XOPEN_SOURCE == 520 Networking Services (XNS), Issue 5.2 Draft 2.0
+ * _XOPEN_SOURCE == 500 System Interfaces and Headers Issue 5
+ * _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1
+ * System Interfaces and Headers Issue 4, Ver 2
+ * _XOPEN_SOURCE System Interfaces and Headers Issue 4
*
- * NetBSD macros:
- * _NETBSD_SOURCE == 1 Make all NetBSD features available.
+ * POSIX macros:
+ * _POSIX_C_SOURCE == 200809L IEEE Std 1003.1-2008
+ * _POSIX_C_SOURCE == 200112L IEEE Std 1003.1-2001
+ * _POSIX_C_SOURCE == 199506L ISO/IEC 9945-1:1996
+ * _POSIX_C_SOURCE == 199309L IEEE Std 1003.1b-1993
+ * _POSIX_C_SOURCE == 2 IEEE Std 1003.2-1992
+ * _POSIX_C_SOURCE == 1 IEEE Std 1003.1-1992 without new 1992 interfaces
+ * _POSIX_SOURCE == 1 IEEE Std 1003.1-1990, IEEE Std 1003.1-1988
*
- * If more than one of these "major" feature-test macros is defined,
- * then the set of facilities provided (and namespace used) is the
- * union of that specified by the relevant standards, and in case of
- * conflict, the earlier standard in the above list has precedence (so
- * if both _POSIX_C_SOURCE and _NETBSD_SOURCE are defined, the version
- * of rename() that's used is the POSIX one). If none of the "major"
- * feature-test macros is defined, _NETBSD_SOURCE is assumed.
+ * If more than one of these "major" feature-test macros is defined, then the
+ * set of facilities provided (and namespace used) is the union of that
+ * specified by the relevant standards, and in case of conflict, X/Open and
+ * POSIX have precedence over NetBSD (so if both _POSIX_C_SOURCE and
+ * _NETBSD_SOURCE are defined, the version of rename() that's used is the POSIX
+ * one). If none of the "major" feature-test macros is defined, _NETBSD_SOURCE
+ * is assumed.
*
* There are also "minor" feature-test macros, which enable extra
* functionality in addition to some base standard. They should be
@@ -61,16 +81,129 @@
* <http://ftp.sas.com/standards/large.file/x_open.20Mar96.html>
*/
-#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 1L
+#if defined(__NBSD_VISIBLE) || defined(__XOPEN_VISIBLE) || \
+ defined(__POSIX_VISIBLE) || defined(__ISO_C_VISIBLE)
+#error "__*_VISIBLE aren't feature test macros. Use NetBSD or standard macros."
#endif
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) && \
- !defined(_XOPEN_SOURCE) && !defined(_NETBSD_SOURCE)
-#define _NETBSD_SOURCE 1
+#if (!defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE) && \
+ !defined(_POSIX_SOURCE) && !defined(_ANSI_SOURCE)) || \
+ defined(_NETBSD_SOURCE)
+# define __NBSD_VISIBLE
#endif
-#if ((_POSIX_C_SOURCE - 0) >= 199506L || (_XOPEN_SOURCE - 0) >= 500) && \
- !defined(_REENTRANT)
-#define _REENTRANT
+#ifdef __NBSD_VISIBLE
+# define __XOPEN_VISIBLE 700
#endif
+
+#ifdef _XOPEN_SOURCE
+/*
+ * The Open Group Base Specifications Issue 7, 2018 edition
+ * https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/
+ */
+# if _XOPEN_SOURCE - 0 >= 700
+# define __XOPEN_VISIBLE 700
+/*
+ * The Open Group Base Specifications Issue 6
+ * https://pubs.opengroup.org/onlinepubs/009695399/
+ */
+# elif _XOPEN_SOURCE - 0 >= 600
+# define __XOPEN_VISIBLE 600
+/*
+ * Networking Services (XNS), Issue 5.2 Draft 2.0:
+ * https://pubs.opengroup.org/onlinepubs/009619199/
+ */
+# elif _XOPEN_SOURCE - 0 >= 520
+# define __XOPEN_VISIBLE 520
+/*
+ * System Interfaces and Headers Issue 5
+ * https://pubs.opengroup.org/onlinepubs/009639399/toc.pdf
+ *
+ * Web conversions of this standard lack markings like EX (extension), don't
+ * read web coversions.
+ */
+# elif _XOPEN_SOURCE - 0 >= 500
+# define __XOPEN_VISIBLE 500
+/*
+ * System Interfaces and Headers Issue 4, Version 2
+ * https://pubs.opengroup.org/onlinepubs/9695969499/toc.pdf
+ */
+# elif _XOPEN_SOURCE_EXTENDED - 0 == 1
+# define __XOPEN_VISIBLE 420
+/*
+ * I can't get my hands on XPG older than XPGv4.2. However, XPGv4.2 explains
+ * _XOPEN_SOURCE_EXTENDED was added in XPGv4.2 and _XOPEN_SOURCE was added in
+ * XPGv4.0, so it appears there is no feature test macro for older versions, and
+ * we provide no way to request an older standard.
+ */
+# else
+# define __XOPEN_VISIBLE 400
+# endif
+#endif
+
+#if defined(_POSIX_C_SOURCE) || defined(__XOPEN_VISIBLE)
+# if _POSIX_C_SOURCE - 0 >= 200809L || __XOPEN_VISIBLE >= 700
+# define __POSIX_VISIBLE 200809
+# elif _POSIX_C_SOURCE - 0 >= 200112L || __XOPEN_VISIBLE >= 600
+# define __POSIX_VISIBLE 200112
+/* POSIX.1c: Threads extensions (IEEE Std 1003.1c-1995) */
+# elif _POSIX_C_SOURCE - 0 >= 199506L || __XOPEN_VISIBLE >= 500
+# define __POSIX_VISIBLE 199506
+/* POSIX.1b: Real-time extensions (IEEE Std 1003.1b-1993) */
+# elif _POSIX_C_SOURCE - 0 >= 199309L
+# define __POSIX_VISIBLE 199309
+/*
+ * POSIX.2: Shell and Utilities (IEEE Std 1003.2-1992)
+ *
+ * IEEE P1003.2 Draft 11.2:
+ * https://mirror.math.princeton.edu/pub/oldlinux/Linux.old/Ref-docs/POSIX/all.pdf
+ * XXX: Careful, the link is a draft. Figure out if any organization bought the
+ * right to publish the final standard for free.
+ */
+# elif _POSIX_C_SOURCE - 0 >= 2 || __XOPEN_VISIBLE >= 400
+# define __POSIX_VISIBLE 199200
+# elif _POSIX_C_SOURCE - 0 == 1
+/*
+ * POSIX 1990 doesn't define _POSIX_C_SOURCE. However, 1992 states that if
+ * _POSIX_C_SOURCE == 1, that is the same as defining _POSIX_SOURCE.
+ */
+# define __POSIX_VISIBLE 199012
+# endif
+#endif
+
+#ifdef _POSIX_SOURCE
+/*
+ * NIST adopted these, we can have them for free.
+ * IEEE Std 1003.1, 1990:
+ * https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub151-2.pdf
+ * IEEE Std 1003.1, 1988:
+ * https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub151-1.pdf
+ *
+ * There doesn't seem to be a way to differentiate between 1990 and 1988, so we
+ * assume 1990.
+ */
+# define __POSIX_VISIBLE 199012
+#endif
+
+#if defined(_ISOC11_SOURCE) || defined(__NBSD_VISIBLE)
+# define __ISO_C_VISIBLE 2011
+#elif defined(_ISOC99_SOURCE) || __POSIX_VISIBLE >= 200112
+# define __ISO_C_VISIBLE 1999
+#else
+# define __ISO_C_VISIBLE 1990
+#endif
+
+/* Otherwise, define the visibilities of standards with an invalid value so we
+ * can check with `__VISIBLE >= 1` instead of the uglier `__VISIBLE - 0 >= 1`
+ */
+#ifndef __XOPEN_VISIBLE
+# define __XOPEN_VISIBLE -1
+#endif
+#ifndef __POSIX_VISIBLE
+# define __POSIX_VISIBLE -1
+#endif
+#ifndef __ISO_C_VISIBLE
+# define __ISO_C_VISIBLE -1
+#endif
+
+#endif /* defined(_SYS_FEATURETEST_H_) */
Home |
Main Index |
Thread Index |
Old Index