summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2015-03-28 10:55:27 -0700
committerGarrett D'Amore <garrett@damore.org>2015-04-05 09:35:41 -0700
commitde572d98af8238405c5d1292a788b1a85b0c68eb (patch)
tree670a8dc82f4647f9e8c5bf03d924431b4a7cb5fc
parent8c76e0763bcf0029556e106377da859f6492a7ee (diff)
downloadillumos-joyent-de572d98af8238405c5d1292a788b1a85b0c68eb.tar.gz
5293 desire symbol visibility test
Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Gordon Ross <gordon.w.ross@gmail.com>
-rw-r--r--usr/src/pkg/manifests/system-test-libctest.mf78
-rw-r--r--usr/src/test/libc-tests/Makefile2
-rw-r--r--usr/src/test/libc-tests/cfg/Makefile60
-rw-r--r--usr/src/test/libc-tests/cfg/README83
-rw-r--r--usr/src/test/libc-tests/cfg/compilation.cfg87
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/README72
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/ctype_h.cfg64
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/dirent_h.cfg69
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg62
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/locale_h.cfg64
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/math_h.cfg37
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/netdb_h.cfg53
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/pthread_h.cfg63
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/signal_h.cfg32
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg53
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg57
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/strings_h.cfg30
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/sys_stat_h.cfg58
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg42
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/sys_timeb_h.cfg30
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/ucontext_h.cfg30
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/unistd_h.cfg140
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/wchar_h.cfg83
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/wctype_h.cfg36
-rw-r--r--usr/src/test/libc-tests/runfiles/default.run23
-rw-r--r--usr/src/test/libc-tests/tests/Makefile4
-rw-r--r--usr/src/test/libc-tests/tests/Makefile.com8
-rw-r--r--usr/src/test/libc-tests/tests/common/test_common.c208
-rw-r--r--usr/src/test/libc-tests/tests/common/test_common.h11
-rw-r--r--usr/src/test/libc-tests/tests/symbols/Makefile47
-rwxr-xr-xusr/src/test/libc-tests/tests/symbols/setup.ksh75
-rw-r--r--usr/src/test/libc-tests/tests/symbols/symbols_test.c957
32 files changed, 2687 insertions, 31 deletions
diff --git a/usr/src/pkg/manifests/system-test-libctest.mf b/usr/src/pkg/manifests/system-test-libctest.mf
index b635e7c74b..7213eac98c 100644
--- a/usr/src/pkg/manifests/system-test-libctest.mf
+++ b/usr/src/pkg/manifests/system-test-libctest.mf
@@ -12,7 +12,7 @@
#
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
-# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
#
set name=pkg.fmri value=pkg:/system/test/libctest@$(PKGVERS)
@@ -23,36 +23,72 @@ set name=info.classification \
set name=variant.arch value=$(ARCH)
dir path=opt/libc-tests
dir path=opt/libc-tests/bin
+dir path=opt/libc-tests/cfg
+dir path=opt/libc-tests/cfg/symbols
dir path=opt/libc-tests/runfiles
dir path=opt/libc-tests/tests
+dir path=opt/libc-tests/tests
+dir path=opt/libc-tests/tests/symbols
file path=opt/libc-tests/README mode=0444
file path=opt/libc-tests/bin/libctest mode=0555
+file path=opt/libc-tests/cfg/README mode=0444
+file path=opt/libc-tests/cfg/compilation.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/README mode=0444
+file path=opt/libc-tests/cfg/symbols/ctype_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/dirent_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/fcntl_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/locale_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/math_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/netdb_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/pthread_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/signal_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/stdio_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/stdlib_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/strings_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/sys_stat_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/sys_time_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/sys_timeb_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/ucontext_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/unistd_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/wchar_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/wctype_h.cfg mode=0444
file path=opt/libc-tests/runfiles/default.run mode=0444
file path=opt/libc-tests/tests/fpround_test mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/fpround_test.amd64 mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/fpround_test.i386 mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/fpround_test.sparc mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/fpround_test.sparcv9 mode=0555
+file path=opt/libc-tests/tests/fpround_test.$(ARCH) mode=0555
+file path=opt/libc-tests/tests/fpround_test.$(ARCH64) mode=0555
file path=opt/libc-tests/tests/newlocale_test mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/newlocale_test.amd64 mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/newlocale_test.i386 mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/newlocale_test.sparc mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/newlocale_test.sparcv9 mode=0555
+file path=opt/libc-tests/tests/newlocale_test.$(ARCH) mode=0555
+file path=opt/libc-tests/tests/newlocale_test.$(ARCH64) mode=0555
file path=opt/libc-tests/tests/nl_langinfo_test mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/nl_langinfo_test.amd64 mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/nl_langinfo_test.i386 mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/nl_langinfo_test.sparc mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/nl_langinfo_test.sparcv9 mode=0555
+file path=opt/libc-tests/tests/nl_langinfo_test.$(ARCH) mode=0555
+file path=opt/libc-tests/tests/nl_langinfo_test.$(ARCH64) mode=0555
+file path=opt/libc-tests/tests/symbols/setup mode=0555
+file path=opt/libc-tests/tests/symbols/symbols_test.$(ARCH) mode=0555
+file path=opt/libc-tests/tests/symbols/symbols_test.$(ARCH64) mode=0555
file path=opt/libc-tests/tests/wcsrtombs_test mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/wcsrtombs_test.amd64 mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/wcsrtombs_test.i386 mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/wcsrtombs_test.sparc mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/wcsrtombs_test.sparcv9 mode=0555
+file path=opt/libc-tests/tests/wcsrtombs_test.$(ARCH) mode=0555
+file path=opt/libc-tests/tests/wcsrtombs_test.$(ARCH64) mode=0555
file path=opt/libc-tests/tests/wctype_test mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/wctype_test.amd64 mode=0555
-$(i386_ONLY)file path=opt/libc-tests/tests/wctype_test.i386 mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/wctype_test.sparc mode=0555
-$(sparc_ONLY)file path=opt/libc-tests/tests/wctype_test.sparcv9 mode=0555
+file path=opt/libc-tests/tests/wctype_test.$(ARCH) mode=0555
+file path=opt/libc-tests/tests/wctype_test.$(ARCH64) mode=0555
+hardlink path=opt/libc-tests/tests/symbols/ctype_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/dirent_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/fcntl_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/locale_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/math_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/netdb_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/pthread_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/signal_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/stdio_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/stdlib_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/strings_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/sys_stat_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/sys_time_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/sys_timeb_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/ucontext_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/unistd_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/wchar_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/wctype_h target=setup
license lic_CDDL license=lic_CDDL
depend fmri=locale/de type=require
depend fmri=locale/en type=require
diff --git a/usr/src/test/libc-tests/Makefile b/usr/src/test/libc-tests/Makefile
index 535d00744b..0a4b11f185 100644
--- a/usr/src/test/libc-tests/Makefile
+++ b/usr/src/test/libc-tests/Makefile
@@ -16,6 +16,6 @@
.PARALLEL: $(SUBDIRS)
-SUBDIRS = cmd runfiles tests doc
+SUBDIRS = cfg cmd runfiles tests doc
include $(SRC)/test/Makefile.com
diff --git a/usr/src/test/libc-tests/cfg/Makefile b/usr/src/test/libc-tests/cfg/Makefile
new file mode 100644
index 0000000000..e4c43f3d7c
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/Makefile
@@ -0,0 +1,60 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+CFGS = README \
+ compilation.cfg \
+ symbols/README \
+ symbols/ctype_h.cfg \
+ symbols/dirent_h.cfg \
+ symbols/fcntl_h.cfg \
+ symbols/locale_h.cfg \
+ symbols/math_h.cfg \
+ symbols/netdb_h.cfg \
+ symbols/pthread_h.cfg \
+ symbols/signal_h.cfg \
+ symbols/stdio_h.cfg \
+ symbols/stdlib_h.cfg \
+ symbols/strings_h.cfg \
+ symbols/sys_stat_h.cfg \
+ symbols/sys_time_h.cfg \
+ symbols/sys_timeb_h.cfg \
+ symbols/ucontext_h.cfg \
+ symbols/unistd_h.cfg \
+ symbols/wchar_h.cfg \
+ symbols/wctype_h.cfg
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+ROOTOPTPKGCFG = $(ROOT)/opt/libc-tests/cfg
+ROOTOPTPKGDIRS = $(ROOTOPTPKG) \
+ $(ROOTOPTPKGCFG) \
+ $(ROOTOPTPKGCFG)/symbols
+
+FILES = $(CFGS:%=$(ROOTOPTPKGCFG)/%)
+$(FILES) := FILEMODE = 0444
+
+all: $(CFGS)
+
+install: $(ROOTOPTPKG) $(ROOTOPTPKGCFG) $(FILES)
+
+clean lint clobber:
+
+$(ROOTOPTPKGDIRS):
+ $(INS.dir)
+
+$(ROOTOPTPKGCFG)/%: % $(ROOTOPTPKGDIRS)
+ $(INS.file)
diff --git a/usr/src/test/libc-tests/cfg/README b/usr/src/test/libc-tests/cfg/README
new file mode 100644
index 0000000000..8f9221bc4b
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/README
@@ -0,0 +1,83 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+The configuration files in this directory are structured as lines,
+where each line is made up of fields, separated by "|" characters,
+possibly surrounded by whitespace.
+
+New lines preceeded by backslashes are ignored, allowing for a continuation
+of lines, in the usual UNIX way.
+
+A line beginning with a hashmark is a comment, and is ignored, as are lines
+consisting solely of whitespace.
+
+The first field is always the "keyword", which determines the meaning and
+presence of any other fields.
+
+These files are parsed using the test_load_config() function. This
+function has the following prototype:
+
+ int test_load_config(test_t, const char *, ...);
+
+The variable arguments are the keywords and handling functions. These
+must be supplied in pairs and the list is terminated with a NULL, like this:
+
+ test_config_load(t, "myfile.cfg", "mykeyword", keywordcb, NULL);
+
+The test_config_load function will search for the named file (provided it
+is not an absolute path) in a few locations:
+
+ * relative to the current directory, exactly as specified
+ * relative to $STF_SUITE/cfg/ (if $STF_SUITE is defined)
+ * relative to ../../cfg/ (if $STF_SUITE is undefined)
+ * relative to cfg/
+
+The handling functions (keywordcb in the example above) have the following
+typedef:
+
+ typedef int (*test_cfg_func_t)(char **fields, int nfields, char **err);
+
+so for example, keywordcb should be declared thusly:
+
+ int keywordcb(char **fields, int nfields, char **err);
+
+These functions are called each time a paired keyword is seen in the file.
+"fields" is an array of fields, pre-split with surrounding whitespace removed,
+and contains "nfields" items. Internal whitespace is unaffected.
+
+The function should return 0 on successful handling, or -1 on failure. In
+the event of failure, it should record an error string in "err" using
+asprintf() or strdup(). ("err" should be unmodified otherwise.)
+
+This parser is rather simplistic, and it lacks support for embedding "|"
+fields in lines, and also doesn't support escaping, so you can't add "\"
+at the end of a line (if you need that, leave some trailing whitespace).
+
+There are also some internal limits on the length of lines (1K), and on the
+number of fields (20). As this is only used for these test suites, this
+should not be a significant limitation.
+
+Please see ../tests/symbols/symbols_test.c for an example of correct usage.
+
+Aside:
+
+ Astute readers may ask why invent a new configuration file, and why use
+ position based parsing instead of name value pairs. These files are
+ optimized for specific needs, and intended to support relatively dense
+ information in a format that is easy for humans to work with. JSON or XML
+ or even YAML could have served, but the overhead of a syntax was more than
+ we wanted to introduce. Test suites are free to use other formats if they
+ choose, but this simple format has the advantage of being built-in and
+ easy to use.
diff --git a/usr/src/test/libc-tests/cfg/compilation.cfg b/usr/src/test/libc-tests/cfg/compilation.cfg
new file mode 100644
index 0000000000..e39823bf3c
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/compilation.cfg
@@ -0,0 +1,87 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Compilation environments.
+#
+# Each compilation environment is declared using the keyword "env", like
+# this:
+#
+# env | <name> | <std> | <defs>
+#
+# <name> is just a symbolic name for environment.
+# <std> indicates either c89 or c99, i.e. which C standard to compile
+# under. This infuences choice of compiler and switches.
+# <defs> is a list of CPP style -D or -U flags to define C preprocessor
+# symbols.
+#
+# Groups of compilation environments can be named, using the "env_group"
+# keyword (this can also be used to create aliases):
+#
+# env_group | <name> | <envs>
+#
+# <name> is a name for the group or alias
+# <envs> is a whitespace separated list of previously declared environments
+# or environment groups (or aliases).
+#
+
+env | XPG3 | c89 | -D_XOPEN_SOURCE
+env | XPG4 | c89 | -D_XOPEN_SOURCE -D_XOPEN_VERSION=4
+env | SUSv1 | c89 | -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1
+env | SUSv2 | c89 | -D_XOPEN_SOURCE=500
+env | SUSv3 | c99 | -D_XOPEN_SOURCE=600
+env | SUSv4 | c99 | -D_XOPEN_SOURCE=700
+env | POSIX-1990 | c89 | -D_POSIX_SOURCE
+env | POSIX-1992 | c89 | -D_POSIX_SOURCE -D_POSIX_C_SOURCE=2
+env | POSIX-1993 | c89 | -D_POSIX_C_SOURCE=199309L
+env | POSIX-1995 | c89 | -D_POSIX_C_SOURCE=199506L
+env | POSIX-2001 | c99 | -D_POSIX_C_SOURCE=200112L
+env | POSIX-2008 | c99 | -D_POSIX_C_SOURCE=200809L
+env | C90 | c89 |
+env | C99 | c99 |
+
+#
+# These are ordered from less inclusive (most recent) to most inclusive.
+# This allows for us to "include" by reference.
+#
+env_group | POSIX-2008+ | POSIX-2008
+env_group | POSIX-2001+ | POSIX-2008+ POSIX-2001
+env_group | POSIX-1995+ | POSIX-2001+ POSIX-1995
+env_group | POSIX-1993+ | POSIX-1995+ POSIX-1993
+env_group | POSIX-1992+ | POSIX-1993+ POSIX-1992
+env_group | POSIX-1990+ | POSIX-1992+ POSIX-1990
+env_group | POSIX+ | POSIX-1990+
+env_group | SUSv4+ | SUSv4 POSIX-2008+
+env_group | SUSv3+ | SUSv3 SUSv4+ POSIX-2001+
+env_group | SUSv2+ | SUSv2 SUSv3+
+env_group | SUSv1+ | SUSv1 SUSv2+
+env_group | SUS+ | SUSv1+
+env_group | XPG4+ | XPG4 SUSv1+
+env_group | XPG3+ | XPG3 XPG4+
+env_group | C99+ | C99 POSIX-2001+ SUSv3+
+env_group | C+ | C90 C99 POSIX+ SUS+
+env_group | ALL | C+
+
+#
+# Aliases.
+#
+env_group | XPG4v2 | SUSv1
+env_group | XPG4v2+ | SUSv1+
+env_group | XPG5 | SUSv2
+env_group | XPG5+ | SUSv2+
+env_group | XPG6 | SUSv3
+env_group | XPG6+ | SUSv3+
+env_group | XPG7 | SUSv4
+env_group | XPG7+ | SUSv4+
diff --git a/usr/src/test/libc-tests/cfg/symbols/README b/usr/src/test/libc-tests/cfg/symbols/README
new file mode 100644
index 0000000000..3d86b68d5c
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/README
@@ -0,0 +1,72 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+The configuration files in this directory are structured using the
+syntax defined in the ../README file. They make use of the compilation
+environments declared in ../compilation.cfg, and are processed by the
+symbols test.
+
+We have organized the files by header file, that is the tests for symbols
+declared in a header file (e.g. <unistd.h> appear in a file based on that
+header file's name (e.g. unistd_h.cfg.) This is purely for convenience.
+
+Within these various declarations, we have the following field types:
+
+<envs> This is a list of compilation environments where the symbol
+ should be legal. To indicate that the symbol must not be legal
+ an environment group can be prefixed with "-". For example,
+ "SUS+ -SUSv4+" indicates a symbol that is legal in all SUS
+ environments up to SUSv3, and was removed in SUSv4 and subsequent
+ versions of SUS. As you can see, we can list multiple environments
+ or environment groups, and we can add or remove to previous groups
+ with subsequent ones.
+
+<name> This is a symbol name. It follows the rules for C symbol names.
+
+<header> This is a header file, for example, unistd.h. Conventionally,
+ the header files used should match the file where the test is
+ declared.
+
+<type> This is a C type. Function types can be declared without their
+ names, e.g. "void (*)(int)". Structures (e.g. "struct stat") and
+ pointer types (e.g. "pthead_t *") are legal as well.
+
+Here are the types of declarations in these files:
+
+type | <name> | <header> | <envs>
+
+ Tests for a C type with <name>. The test verifies that a variable with
+ this type can be declared when the <header> is included.
+
+value | <name> | <type> | <header> | <envs>
+
+ Tests for a value named <name>, of type <type>. The test attempts to
+ assign the given value to a scratch variable declared with the given
+ type. The value can be a macro or other C symbol.
+
+func | <name> | <type> | <type> [; <type> ]... | <header> | <envs>
+
+ Tests whether a function <name>, returning the first <type>, and
+ taking arguments of following <type> values, is declared. Note that
+ the argument types are separated by semicolons. For varargs style
+ functions, leave out the ... part. For function declarations
+ that have no declared arguments, either void can specified, or
+ the type list can be omitted.
+
+Examples:
+
+ type | size_t | sys/types.h | ALL
+ value | NULL | void * | stdlib.h | ALL
+ func strnlen | int | const char *; int | string.h | ALL
diff --git a/usr/src/test/libc-tests/cfg/symbols/ctype_h.cfg b/usr/src/test/libc-tests/cfg/symbols/ctype_h.cfg
new file mode 100644
index 0000000000..cf078d69d7
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/ctype_h.cfg
@@ -0,0 +1,64 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in ctype.h
+#
+
+#
+# Types.
+#
+type | locale_t | ctype.h | -ALL +SUSv4+
+
+#
+# Values.
+#
+
+#
+# Functions
+#
+func | isalnum | int | int | ctype.h | +ALL
+func | isalpha | int | int | ctype.h | +ALL
+func | isascii | int | int | ctype.h | -ALL +XPG3+
+func | isblank | int | int | ctype.h | -ALL +C99+
+func | iscntrl | int | int | ctype.h | +ALL
+func | isdigit | int | int | ctype.h | +ALL
+func | isgraph | int | int | ctype.h | +ALL
+func | islower | int | int | ctype.h | +ALL
+func | isprint | int | int | ctype.h | +ALL
+func | ispunct | int | int | ctype.h | +ALL
+func | isspace | int | int | ctype.h | +ALL
+func | isupper | int | int | ctype.h | +ALL
+func | isxdigit | int | int | ctype.h | +ALL
+func | toascii | int | int | ctype.h | -ALL +XPG3+
+func | tolower | int | int | ctype.h | +ALL
+func | toupper | int | int | ctype.h | +ALL
+func | _tolower | int | int | ctype.h | -ALL +XPG3+
+func | _toupper | int | int | ctype.h | -ALL +XPG3+
+
+func | isalnum_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isalpha_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isblank_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | iscntrl_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isdigit_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isgraph_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | islower_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isprint_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | ispunct_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isspace_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isupper_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | isxdigit_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | tolower_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
+func | toupper_l | int | int; locale_t | ctype.h | -ALL +SUSv4+
diff --git a/usr/src/test/libc-tests/cfg/symbols/dirent_h.cfg b/usr/src/test/libc-tests/cfg/symbols/dirent_h.cfg
new file mode 100644
index 0000000000..0ff030f3ef
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/dirent_h.cfg
@@ -0,0 +1,69 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in dirent.h
+#
+# Note that this header is not defined prior to the POSIX & XPG3
+# specifications. Therefore, applications which #include it in earlier
+# environments may reasonably obtain their contents, although such use
+# would not be conformant to those specifications.
+#
+# As a result, we only test the newer specifications.
+#
+
+#
+# Types.
+#
+type | DIR * | dirent.h | XPG3+ POSIX+
+type | struct dirent | dirent.h | XPG3+ POSIX+
+
+#
+# Values.
+#
+
+#
+# Functions
+#
+
+func | opendir |\
+ DIR * |\
+ const char * |\
+ dirent.h | POSIX+ XPG3+
+
+func | readdir |\
+ struct dirent * |\
+ DIR * |\
+ dirent.h | POSIX+ XPG3+
+
+# We are not going to test the draft interface.
+func | readdir_r |\
+ int |\
+ DIR *; struct dirent *; struct dirent ** |\
+ dirent.h | POSIX-1995+
+
+func | rewinddir |\
+ void |\
+ DIR * | dirent.h | POSIX+ XPG3+
+
+func | seekdir |\
+ void |\
+ DIR *; long |\
+ dirent.h | -POSIX+ XPG3+
+
+func | telldir |\
+ long |\
+ DIR * |\
+ dirent.h | -POSIX+ XPG3+
diff --git a/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg b/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg
new file mode 100644
index 0000000000..92806885bc
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg
@@ -0,0 +1,62 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in fcntl.h
+#
+
+#
+# Types.
+#
+type | mode_t | fcntl.h | ALL
+type | off_t | fcntl.h | ALL
+type | pid_t | fcntl.h | ALL
+type | struct flock | fcntl.h | ALL
+
+#
+# Values.
+#
+value | O_ACCMODE | int | fcntl.h | POSIX+ SUS+
+value | O_APPEND | int | fcntl.h | POSIX+ SUS+
+value | O_CLOEXEC | int | fcntl.h | POSIX+ SUS+
+value | O_CREAT | int | fcntl.h | POSIX+ SUS+
+value | O_DSYNC | int | fcntl.h | XPG3+ POSIX-1993+
+value | O_EXCL | int | fcntl.h | POSIX+ SUS+
+value | O_NDELAY | int | fcntl.h | -POSIX-1993+
+value | O_NOCTTY | int | fcntl.h | POSIX+ SUS+
+value | O_NONBLOCK | int | fcntl.h | POSIX+ SUS+
+value | O_RDONLY | int | fcntl.h | POSIX+ SUS+
+value | O_RDWR | int | fcntl.h | POSIX+ SUS+
+value | O_RSYNC | int | fcntl.h | XPG3+ POSIX-1993+
+value | O_SYNC | int | fcntl.h | XPG3+ POSIX-1993+
+value | O_WRONLY | int | fcntl.h | POSIX+ SUS+
+
+#
+# Functions
+#
+func | creat |\
+ int |\
+ const char *; mode_t |\
+ fcntl.h | ALL
+
+func | open |\
+ int |\
+ const char *; mode_t |\
+ fcntl.h | ALL
+
+func | fcntl |\
+ int |\
+ int; int |\
+ fcntl.h | ALL
diff --git a/usr/src/test/libc-tests/cfg/symbols/locale_h.cfg b/usr/src/test/libc-tests/cfg/symbols/locale_h.cfg
new file mode 100644
index 0000000000..604ded6477
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/locale_h.cfg
@@ -0,0 +1,64 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in locale.h
+#
+
+#
+# Types.
+#
+type | locale_t | locale.h | -ALL SUSv4+
+type | struct lconv | locale.h | ALL
+
+#
+# Values.
+#
+value | LC_CTYPE | int | locale.h | ALL
+value | LC_COLLATE | int | locale.h | ALL
+value | LC_TIME | int | locale.h | ALL
+value | LC_NUMERIC | int | locale.h | ALL
+value | LC_MONETARY | int | locale.h | ALL
+value | LC_MESSAGES | int | locale.h | ALL
+value | LC_GLOBAL_LOCALE | locale_t | locale.h | -ALL SUSv4+
+value | NULL | void * | locale.h | ALL
+
+#
+# Functions
+#
+func | duplocale |\
+ locale_t |\
+ locale_t |\
+ locale.h | -ALL SUSv4+
+
+func | newlocale |\
+ locale_t |\
+ int; const char *; locale_t |\
+ locale.h | -ALL SUSv4+
+
+func | freelocale |\
+ void |\
+ locale_t |\
+ locale.h | -ALL SUSv4+
+
+func | localeconv |\
+ struct lconv * |\
+ void |\
+ locale.h | ALL
+
+func | setlocale |\
+ char * |\
+ int; const char * |\
+ locale.h | ALL
diff --git a/usr/src/test/libc-tests/cfg/symbols/math_h.cfg b/usr/src/test/libc-tests/cfg/symbols/math_h.cfg
new file mode 100644
index 0000000000..60a219c431
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/math_h.cfg
@@ -0,0 +1,37 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in math.h
+#
+
+
+#
+# Types.
+#
+
+#
+# Values.
+#
+value | M_PI | double | math.h | SUS+
+value | INFINITY | float | math.h | C99+
+value | NAN | float | math.h | C99+
+value | FP_NAN | int | math.h | C99+
+
+#
+# Functions
+#
+func | cos | double | double | math.h | ALL
+func | cosf | float | float | math.h | -ALL +C99+
diff --git a/usr/src/test/libc-tests/cfg/symbols/netdb_h.cfg b/usr/src/test/libc-tests/cfg/symbols/netdb_h.cfg
new file mode 100644
index 0000000000..ae78f43a44
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/netdb_h.cfg
@@ -0,0 +1,53 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in netdb.h
+#
+
+#
+# Types.
+#
+
+#
+# Values.
+#
+#value | h_errno | int | netdb.h | -ALL SUS+ -SUSv4+
+#value | HOST_NOT_FOUND | int | netdb.h | -ALL SUS+ -SUSv4+
+#value | NO_DATA | int | netdb.h | -ALL SUS+ -SUSv4+
+#value | NO_RECOVERY | int | netdb.h | -ALL SUS+ -SUSv4+
+#value | TRY_AGAIN | int | netdb.h | -ALL SUS+ -SUSv4+
+
+#
+# Functions
+#
+
+func | endhostent |\
+ void |\
+ void |\
+ netdb.h |\
+ SUS+
+
+func | gethostent |\
+ struct hostent * |\
+ void |\
+ netdb.h |\
+ SUS+
+
+func | sethostent |\
+ void |\
+ int |\
+ netdb.h |\
+ SUS+
diff --git a/usr/src/test/libc-tests/cfg/symbols/pthread_h.cfg b/usr/src/test/libc-tests/cfg/symbols/pthread_h.cfg
new file mode 100644
index 0000000000..c5ba1bc12e
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/pthread_h.cfg
@@ -0,0 +1,63 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in pthread.h
+#
+# Note that this header is not defined prior to the POSIX 1995 & SUSv2
+# specifications. Therefore, applications which #include it in earlier
+# environments may reasonably obtain their contents, although such use
+# would not be conformant to those specifications.
+#
+# As a result, we only test the newer specifications.
+#
+
+#
+# Types.
+#
+type | pthread_t * | pthread.h | POSIX-1995+ SUSv2+
+
+#
+# Values.
+#
+value | PTHREAD_SCOPE_PROCESS | int | pthread.h | POSIX-1995+ SUSv2+
+value | PTHREAD_SCOPE_SYSTEM | int | pthread.h | POSIX-1995+ SUSv2+
+
+#
+# Functions
+#
+func | pthread_create |\
+ int |\
+ pthread_t *; const pthread_attr_t *; void *(*)(void *); void * |\
+ pthread.h |\
+ POSIX-1995+ SUSv2+
+
+func | pthread_self |\
+ pthread_t |\
+ void |\
+ pthread.h |\
+ POSIX-1995+ SUSv2+
+
+func | pthread_attr_getscope |\
+ int |\
+ const pthread_attr_t *; int * |\
+ pthread.h |\
+ POSIX-1995+ SUSv2+
+
+func | pthread_attr_setscope |\
+ int |\
+ pthread_attr_t *; int |\
+ pthread.h |\
+ POSIX-1995+ SUSv2+
diff --git a/usr/src/test/libc-tests/cfg/symbols/signal_h.cfg b/usr/src/test/libc-tests/cfg/symbols/signal_h.cfg
new file mode 100644
index 0000000000..66a4e72490
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/signal_h.cfg
@@ -0,0 +1,32 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in signal.h
+#
+
+#
+# Types.
+#
+type | ucontext_t | signal.h | -ALL SUS+
+
+#
+# Values.
+#
+value | SIG_DFL | void (*)(int) | signal.h | ALL
+
+#
+# Functions.
+#
diff --git a/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg
new file mode 100644
index 0000000000..3d624544d6
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg
@@ -0,0 +1,53 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in stdio.h
+#
+
+#
+# Types.
+#
+type | FILE | stdio.h | ALL
+type | fpos_t | stdio.h | ALL
+type | size_t | stdio.h | ALL
+
+#
+# Values.
+#
+value | BUFSIZ | int | stdio.h | ALL
+value | EOF | int | stdio.h | ALL
+value | NULL | void * | stdio.h | ALL
+value | stderr | FILE * | stdio.h | ALL
+value | stdin | FILE * | stdio.h | ALL
+value | stdout | FILE * | stdio.h | ALL
+value | optarg | char * | stdio.h | -ALL +XPG3+ -SUSv3+
+value | optind | int | stdio.h | -ALL +XPG3+ -SUSv3+
+value | opterr | int | stdio.h | -ALL +XPG3+ -SUSv3+
+value | optopt | int | stdio.h | -ALL +XPG3+ -SUSv3+
+
+#
+# Functions
+#
+
+func | printf |\
+ int |\
+ const char * |\
+ stdio.h | ALL
+
+func | rename |\
+ int |\
+ const char *; const char * |\
+ stdio.h | ALL
diff --git a/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg
new file mode 100644
index 0000000000..4559046430
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg
@@ -0,0 +1,57 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in stdlib.h
+#
+
+#
+# Types.
+#
+type | size_t | stdlib.h | ALL
+
+#
+# Values.
+#
+value | EXIT_FAILURE | int | stdlib.h | ALL
+value | EXIT_SUCCESS | int | stdlib.h | ALL
+value | NULL | void * | stdlib.h | ALL
+
+#
+# Functions
+#
+func | calloc |\
+ void * |\
+ size_t; size_t |\
+ stdlib.h |\
+ ALL
+
+func | exit |\
+ void |\
+ int |\
+ stdlib.h |\
+ ALL
+
+func | free |\
+ void |\
+ void * |\
+ stdlib.h |\
+ ALL
+
+func | malloc |\
+ void * |\
+ size_t |\
+ stdlib.h |\
+ ALL
diff --git a/usr/src/test/libc-tests/cfg/symbols/strings_h.cfg b/usr/src/test/libc-tests/cfg/symbols/strings_h.cfg
new file mode 100644
index 0000000000..b3acb7f1bd
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/strings_h.cfg
@@ -0,0 +1,30 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in strings.h
+#
+
+#
+# Types.
+#
+
+#
+# Values.
+#
+
+#
+# Functions
+#
diff --git a/usr/src/test/libc-tests/cfg/symbols/sys_stat_h.cfg b/usr/src/test/libc-tests/cfg/symbols/sys_stat_h.cfg
new file mode 100644
index 0000000000..a622d69a37
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/sys_stat_h.cfg
@@ -0,0 +1,58 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in sys/stat.h
+#
+
+#
+# Types.
+#
+type | mode_t | sys/stat.h | ALL
+type | struct stat | sys/stat.h | ALL
+
+#
+# Values.
+#
+value | S_IFMT | mode_t | sys/stat.h | ALL
+value | S_IFBLK | mode_t | sys/stat.h | ALL
+
+#
+# Functions
+#
+func | chmod |\
+ int |\
+ const char *; mode_t |\
+ sys/stat.h | POSIX+ XPG3+
+
+func | fchmod |\
+ int |\
+ int; mode_t |\
+ sys/stat.h | -POSIX+ -XPG3+ POSIX-1993+ SUS+
+
+func | fstat |\
+ int |\
+ int; struct stat * |\
+ sys/stat.h | XPG3+ POSIX+
+
+func | mkdir |\
+ int |\
+ const char *; mode_t |\
+ sys/stat.h | XPG3+ POSIX+
+
+func | mknod |\
+ int |\
+ const char *; mode_t; dev_t |\
+ sys/stat.h | -XPG3+ -POSIX+ SUS+
diff --git a/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg b/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg
new file mode 100644
index 0000000000..afed10a6bb
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg
@@ -0,0 +1,42 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in sys/time.h
+#
+
+#
+# Types.
+#
+#type | time_t | sys/timeb.h | -ALL SUS+ -SUSv4+
+#type | struct timeb | sys/timeb.h | -ALL SUS+ -SUSv4+
+
+#
+# Values.
+#
+
+#
+# Functions
+#
+func | futimesat |\
+ int |\
+ int; const char *; const struct timeval [2] |\
+ sys/time.h |\
+ -SUS+ -POSIX+
+
+func | utimes |\
+ int |\
+ const char *; const struct timeval [2] |\
+ sys/time.h | -POSIX+ -XPG3+ SUS+
diff --git a/usr/src/test/libc-tests/cfg/symbols/sys_timeb_h.cfg b/usr/src/test/libc-tests/cfg/symbols/sys_timeb_h.cfg
new file mode 100644
index 0000000000..2db734bfc8
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/sys_timeb_h.cfg
@@ -0,0 +1,30 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in sys/timeb.h
+#
+
+#
+# Types.
+#
+
+#
+# Values.
+#
+
+#
+# Functions
+#
diff --git a/usr/src/test/libc-tests/cfg/symbols/ucontext_h.cfg b/usr/src/test/libc-tests/cfg/symbols/ucontext_h.cfg
new file mode 100644
index 0000000000..f013b08228
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/ucontext_h.cfg
@@ -0,0 +1,30 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in ucontext.h
+#
+
+#
+# Types.
+#
+
+#
+# Values.
+#
+
+#
+# Functions
+#
diff --git a/usr/src/test/libc-tests/cfg/symbols/unistd_h.cfg b/usr/src/test/libc-tests/cfg/symbols/unistd_h.cfg
new file mode 100644
index 0000000000..fd7dabe772
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/unistd_h.cfg
@@ -0,0 +1,140 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in unistd.h
+#
+
+#
+# Types.
+#
+type | pid_t | unistd.h | POSIX+ SUS+
+
+#
+# Values.
+#
+# Note that the standard requires the user declare environ.
+# value | environ | char ** | unistd.h | POSIX+ SUS+
+value | _CS_PATH | int | unistd.h | SUS+
+
+value | _CS_POSIX_V6_ILP32_OFF32_CFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_ILP32_OFF32_LDFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_ILP32_OFF32_LIBS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_ILP32_OFFBIG_LIBS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_LP64_OFF64_CFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_LP64_OFF64_LDFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_LP64_OFF64_LIBS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_LPBIG_OFFBIG_LIBS | int | unistd.h | SUSv3+
+value | _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS | int | unistd.h | SUSv3+
+
+#
+# Functions
+#
+func | access |\
+ int |\
+ const char *; int |\
+ unistd.h | POSIX+ SUS+
+
+func | chown |\
+ int |\
+ const char *; uid_t; gid_t |\
+ unistd.h | POSIX+ SUS+
+
+func | execl |\
+ int |\
+ const char *; const char * |\
+ unistd.h | POSIX+ SUS+
+
+func | execle |\
+ int |\
+ const char *; const char *; char *; char *const [] |\
+ unistd.h | POSIX+ SUS+
+
+func | execlp |\
+ int |\
+ const char *; const char *; char * |\
+ unistd.h | POSIX+ SUS+
+
+func | execv |\
+ int |\
+ const char *; char *const [] |\
+ unistd.h | POSIX+ SUS+
+
+func | execve |\
+ int |\
+ const char *; char *const []; char *const [] |\
+ unistd.h | POSIX+ SUS+
+
+func | execvp |\
+ int |\
+ const char *; char *const [] |\
+ unistd.h | POSIX+ SUS+
+
+func | fchown |\
+ int |\
+ int; uid_t; gid_t |\
+ unistd.h | -POSIX+ SUS+
+
+func | getlogin |\
+ char * |\
+ void |\
+ unistd.h | POSIX+ SUS+
+
+func | getlogin_r |\
+ int |\
+ char *; size_t |\
+ unistd.h | -POSIX+ -SUS+ +POSIX-1995+ SUSv2+
+
+func | lchown |\
+ int |\
+ const char *; uid_t; gid_t |\
+ unistd.h | -POSIX+ SUS+
+
+func | link |\
+ int |\
+ const char *; const char * |\
+ unistd.h | POSIX+ SUS+
+
+# XPG3 may have put this here incorrectly (Open Group says no..., but...)
+# Probably this is actually our error, and we should kill it, but we can
+# do that when kill off XPG3 support altogether.
+func | rename |\
+ int |\
+ const char *; const char * |\
+ unistd.h | -POSIX+ +XPG3 -XPG4+
+
+func | symlink |\
+ int |\
+ const char *; const char * |\
+ unistd.h | -XPG3+ -POSIX+ SUS+
+
+func | ttyname |\
+ char * |\
+ int |\
+ unistd.h | POSIX+ SUS+
+
+func | ttyname_r |\
+ int |\
+ int; char *; size_t |\
+ unistd.h | -POSIX+ -SUS+ +POSIX-1995+ SUSv2+
+
+func | unlink |\
+ int |\
+ const char * |\
+ unistd.h | POSIX+ XPG3+
diff --git a/usr/src/test/libc-tests/cfg/symbols/wchar_h.cfg b/usr/src/test/libc-tests/cfg/symbols/wchar_h.cfg
new file mode 100644
index 0000000000..c73e240c8f
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/wchar_h.cfg
@@ -0,0 +1,83 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in wchar.h
+#
+
+#
+# Types.
+#
+type | locale_t | wchar.h | -ALL SUSv4+
+type | wctype_t | wchar.h | -ALL XPG3+
+
+#
+# Values.
+#
+value | NULL | void * | wchar.h | ALL
+
+#
+# Functions
+#
+func | wcpcpy |\
+ wchar_t * |\
+ wchar_t *; const wchar_t * |\
+ wchar.h | -ALL SUSv4+
+
+func | wcpncpy |\
+ wchar_t * |\
+ wchar_t *; const wchar_t *; size_t |\
+ wchar.h | -ALL SUSv4+
+
+func | wcsdup |\
+ wchar_t * |\
+ const wchar_t * |\
+ wchar.h | -ALL SUSv4+
+
+func | wcscasecmp |\
+ int |\
+ const wchar_t *; const wchar_t * |\
+ wchar.h | -ALL SUSv4+
+
+func | wcscasecmp_l |\
+ int |\
+ const wchar_t *; const wchar_t *; locale_t |\
+ wchar.h | -ALL SUSv4+
+
+# technically this is new in C90-Amd1, but we don't have a test for it.
+func | wcslen |\
+ size_t |\
+ const wchar_t * |\
+ wchar.h | ALL
+
+func | wcsncasecmp |\
+ int |\
+ const wchar_t *; const wchar_t *; size_t |\
+ wchar.h | -ALL SUSv4+
+
+func | wcsncasecmp_l |\
+ int |\
+ const wchar_t *; const wchar_t *; size_t; locale_t |\
+ wchar.h | -ALL SUSv4+
+
+func | wcsnlen |\
+ size_t |\
+ const wchar_t *; size_t |\
+ wchar.h | -ALL SUSv4+
+
+func | wcswcs |\
+ wchar_t * |\
+ const wchar_t *; const wchar_t * |\
+ wchar.h | -ALL XPG4+
diff --git a/usr/src/test/libc-tests/cfg/symbols/wctype_h.cfg b/usr/src/test/libc-tests/cfg/symbols/wctype_h.cfg
new file mode 100644
index 0000000000..fdfa96cd12
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/wctype_h.cfg
@@ -0,0 +1,36 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+#
+
+#
+# Definitions found in wctype.h
+#
+
+#
+# Types.
+#
+type | wint_t | wctype.h | ALL
+
+#
+# Values.
+#
+value | WEOF | wint_t | wctype.h | ALL -XPG4+ SUSv2+
+
+#
+# Functions
+#
+func | iswalnum |\
+ int |\
+ wint_t |\
+ wctype.h | ALL
diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run
index deadcb8c1c..36a78e07e4 100644
--- a/usr/src/test/libc-tests/runfiles/default.run
+++ b/usr/src/test/libc-tests/runfiles/default.run
@@ -31,3 +31,26 @@ outputdir = /var/tmp/test_results
[/opt/libc-tests/tests/wcsrtombs_test]
[/opt/libc-tests/tests/wctype_test]
+
+[/opt/libc-tests/tests/symbols]
+pre = setup
+tests = [
+ 'ctype_h',
+ 'dirent_h',
+ 'fcntl_h',
+ 'locale_h',
+ 'math_h',
+ 'netdb_h',
+ 'pthread_h',
+ 'signal_h',
+ 'stdio_h',
+ 'stdlib_h',
+ 'strings_h',
+ 'sys_stat_h',
+ 'sys_time_h',
+ 'sys_timeb_h',
+ 'ucontext_h',
+ 'unistd_h',
+ 'wchar_h',
+ 'wctype_h'
+ ]
diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile
index 0ce3902862..dda1e69a78 100644
--- a/usr/src/test/libc-tests/tests/Makefile
+++ b/usr/src/test/libc-tests/tests/Makefile
@@ -11,10 +11,10 @@
#
# Copyright (c) 2012 by Delphix. All rights reserved.
-# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright 2015 Garrett D'Amore <garrett@damore.org>
#
-SUBDIRS = fpround newlocale nl_langinfo wcsrtombs wctype
+SUBDIRS = fpround newlocale nl_langinfo symbols wcsrtombs wctype
include $(SRC)/Makefile.master
include $(SRC)/test/Makefile.com
diff --git a/usr/src/test/libc-tests/tests/Makefile.com b/usr/src/test/libc-tests/tests/Makefile.com
index 78f357257a..cdcd639620 100644
--- a/usr/src/test/libc-tests/tests/Makefile.com
+++ b/usr/src/test/libc-tests/tests/Makefile.com
@@ -29,13 +29,15 @@ $(OBJS_OVERRIDE)SRCS = $(PROG).c ../common/test_common.c
C99MODE = -xc99=%all
LINTFLAGS += -I../common -DARCH=\"ARCH\" -DLINT
-CPPFLAGS += -I../common
+CPPFLAGS += -I$(ROOT)/usr/include -I../common
ROOTOPTPKG = $(ROOT)/opt/libc-tests
-TESTDIR = $(ROOTOPTPKG)/tests
+TESTDIR = $(ROOTOPTPKG)/tests/$(TESTSUBDIR)
CMDS = $(PROG32:%=$(TESTDIR)/%) $(PROG64:%=$(TESTDIR)/%) \
- $(KSHPROG:%=$(TESTDIR)/%) $(ARCHPROG:%=$(TESTDIR)/%)
+ $(KSHPROG:%=$(TESTDIR)/%) $(ARCHPROG:%=$(TESTDIR)/%) \
+ $(EXTRAPROG:%=$(TESTDIR)/%)
+
$(CMDS) := FILEMODE = 0555
all: $(PROG32) $(PROG64) $(KSHPROG) $(ARCHPROG) $(SUBDIRS)
diff --git a/usr/src/test/libc-tests/tests/common/test_common.c b/usr/src/test/libc-tests/tests/common/test_common.c
index 21ecc018b9..973e6c6981 100644
--- a/usr/src/test/libc-tests/tests/common/test_common.c
+++ b/usr/src/test/libc-tests/tests/common/test_common.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2015 Garrett D'Amore <garrett@damore.org>
*/
/*
@@ -20,13 +20,21 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
#include <pthread.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/param.h>
#include "test_common.h"
static int debug = 0;
static int force = 0;
static pthread_mutex_t lk;
+static int passes;
+static int tests;
+
struct test {
char *name;
int ntids;
@@ -76,10 +84,12 @@ test_start(const char *format, ...)
test_passed(t);
test_set_debug();
test_set_force();
+ test_summary();
+ (void) test_load_config(t, NULL, NULL);
#endif
+ tests++;
return (t);
-
}
void
@@ -88,6 +98,16 @@ test_failed(test_t t, const char *format, ...)
va_list args;
(void) pthread_mutex_lock(&lk);
+ if (t == NULL) {
+ (void) printf("FAILURE: ");
+ va_start(args, format);
+ (void) vprintf(format, args);
+ va_end(args);
+ (void) printf("\n");
+ (void) fflush(stdout);
+ (void) pthread_mutex_unlock(&lk);
+ return;
+ }
if (force || (t->ntids > 0)) {
(void) printf("TEST FAILING %s: ", t->name);
} else {
@@ -114,6 +134,9 @@ test_failed(test_t t, const char *format, ...)
void
test_passed(test_t t)
{
+ if (t == NULL) {
+ return;
+ }
if (t->ntids > 0) {
if (debug) {
(void) pthread_mutex_lock(&lk);
@@ -124,6 +147,7 @@ test_passed(test_t t)
}
(void) pthread_mutex_lock(&lk);
if (t->fails == 0) {
+ passes++;
(void) printf("TEST PASS: %s\n", t->name);
} else {
(void) printf("TEST FAILED: %d failures\n", t->fails);
@@ -138,6 +162,17 @@ test_passed(test_t t)
}
void
+test_summary(void)
+{
+ if (passes == tests) {
+ (void) printf("TEST SUMMARY: %d / %d (ok)\n", passes, tests);
+ } else {
+ (void) printf("TEST SUMMARY: %d / %d (%d failing)\n",
+ passes, tests, tests - passes);
+ }
+}
+
+void
test_debugf(test_t t, const char *format, ...)
{
va_list args;
@@ -146,8 +181,11 @@ test_debugf(test_t t, const char *format, ...)
return;
(void) pthread_mutex_lock(&lk);
- (void) printf("TEST DEBUG %s: ", t->name);
-
+ if (t) {
+ (void) printf("TEST DEBUG %s: ", t->name);
+ } else {
+ (void) printf("TEST DEBUG: ");
+ }
va_start(args, format);
(void) vprintf(format, args);
va_end(args);
@@ -204,3 +242,165 @@ test_run(int nthr, void (*func)(test_t, void *), void *arg,
}
test_passed(t);
}
+
+void
+test_trim(char **ptr)
+{
+ char *p = *ptr;
+ while (isspace(*p)) {
+ p++;
+ }
+ *ptr = p;
+ p += strlen(p);
+ while ((--p >= *ptr) && (isspace(*p))) {
+ *p = 0;
+ }
+}
+
+#define MAXCB 20
+#define MAXFIELD 20
+
+int
+test_load_config(test_t t, const char *fname, ...)
+{
+ va_list va;
+ const char *keyws[MAXCB];
+ test_cfg_func_t callbs[MAXCB];
+ char *fields[MAXFIELD];
+ int nfields;
+
+ FILE *cfg;
+ char line[1024];
+ char buf[1024];
+ int done;
+ char *ptr;
+ char *tok;
+ char *err;
+ int lineno;
+ int rv;
+ int found;
+ char path[MAXPATHLEN];
+ int i;
+
+ va_start(va, fname);
+ for (i = 0; i < MAXCB; i++) {
+ keyws[i] = (const char *)va_arg(va, const char *);
+ if (keyws[i] == NULL)
+ break;
+ callbs[i] = (test_cfg_func_t)va_arg(va, test_cfg_func_t);
+ }
+ va_end(va);
+ if (i == MAXCB) {
+ test_debugf(t, "too many arguments to function >= %d", MAXCB);
+ }
+
+ found = 0;
+
+ if (access(fname, F_OK) == 0) {
+ found++;
+ }
+ if (!found && fname[0] != '/') {
+ char *stf = getenv("STF_SUITE");
+ if (stf == NULL) {
+ stf = "../..";
+ }
+ (void) snprintf(path, sizeof (path), "%s/cfg/%s", stf, fname);
+ if (access(path, F_OK) == 0) {
+ fname = path;
+ found++;
+ } else {
+ (void) snprintf(path, sizeof (path), "cfg/%s", fname);
+ if (access(path, F_OK) == 0) {
+ fname = path;
+ found++;
+ }
+ }
+ }
+
+ if ((cfg = fopen(fname, "r")) == NULL) {
+ test_failed(t, "open(%s): %s", fname, strerror(errno));
+ return (-1);
+ }
+
+ line[0] = 0;
+ done = 0;
+ lineno = 0;
+
+ while (!done) {
+
+ lineno++;
+
+ if (fgets(buf, sizeof (buf), cfg) == NULL) {
+ done++;
+ } else {
+ (void) strtok(buf, "\n");
+ if ((*buf != 0) && (buf[strlen(buf)-1] == '\\')) {
+ /*
+ * Continuation. This isn't quite right,
+ * as it doesn't allow for a "\" at the
+ * end of line (no escaping).
+ */
+ buf[strlen(buf)-1] = 0;
+ (void) strlcat(line, buf, sizeof (line));
+ continue;
+ }
+ (void) strlcat(line, buf, sizeof (line));
+ }
+
+ /* got a line */
+ ptr = line;
+ test_trim(&ptr);
+
+ /* skip comments and empty lines */
+ if (ptr[0] == 0 || ptr[0] == '#') {
+ line[0] = 0;
+ continue;
+ }
+
+ tok = strsep(&ptr, "|");
+ if (tok == NULL) {
+ break;
+ }
+ test_trim(&tok);
+
+ for (nfields = 0; nfields < MAXFIELD; nfields++) {
+ fields[nfields] = strsep(&ptr, "|");
+ if (fields[nfields] == NULL) {
+ break;
+ }
+ test_trim(&fields[nfields]);
+ }
+
+ found = 0;
+ rv = 0;
+
+ for (int i = 0; keyws[i] != NULL; i++) {
+ if (strcmp(tok, keyws[i]) == 0) {
+ found++;
+ err = NULL;
+ rv = callbs[i](fields, nfields, &err);
+ }
+ }
+ if (!found) {
+ rv = -1;
+ err = NULL;
+ (void) asprintf(&err, "unknown keyword %s", tok);
+ }
+ if (rv != 0) {
+ if (err) {
+ test_failed(t, "%s:%d: %s", fname,
+ lineno, err);
+ free(err);
+ } else {
+ test_failed(t, "%s:%d: unknown error",
+ fname, lineno);
+ }
+ (void) fclose(cfg);
+ return (rv);
+ }
+
+ line[0] = 0;
+ }
+ (void) fclose(cfg);
+ return (0);
+}
diff --git a/usr/src/test/libc-tests/tests/common/test_common.h b/usr/src/test/libc-tests/tests/common/test_common.h
index 9234bfac19..ce4813f7ac 100644
--- a/usr/src/test/libc-tests/tests/common/test_common.h
+++ b/usr/src/test/libc-tests/tests/common/test_common.h
@@ -34,6 +34,17 @@ extern void test_failed(test_t, const char *format, ...);
extern void test_passed(test_t);
extern void test_debugf(test_t, const char *format, ...);
extern void test_run(int nthr, test_func_t, void *arg, const char *, ...);
+extern void test_summary(void);
+
+extern void test_trim(char **);
+
+typedef int (*test_cfg_func_t)(char **fields, int nfields, char **err);
+
+/*
+ * Args list is array of pairs of const char *keyword, test_config_func_t,
+ * terminated by NULL.
+ */
+extern int test_load_config(test_t, const char *, ...);
#ifdef __cplusplus
}
diff --git a/usr/src/test/libc-tests/tests/symbols/Makefile b/usr/src/test/libc-tests/tests/symbols/Makefile
new file mode 100644
index 0000000000..9b9ceb0778
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/symbols/Makefile
@@ -0,0 +1,47 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+include $(SRC)/Makefile.master
+
+TESTSUBDIR = symbols
+PROG = symbols_test
+KSHPROG = setup
+SYMTESTS = \
+ ctype_h \
+ dirent_h \
+ fcntl_h \
+ locale_h \
+ math_h \
+ netdb_h \
+ pthread_h \
+ signal_h \
+ stdio_h \
+ stdlib_h \
+ strings_h \
+ sys_stat_h \
+ sys_time_h \
+ sys_timeb_h \
+ ucontext_h \
+ unistd_h \
+ wchar_h \
+ wctype_h
+
+EXTRAPROG += $(SYMTESTS)
+
+include ../Makefile.com
+
+$(SYMTESTS:%=$(TESTDIR)/%): $(TESTDIR)/setup
+ -$(RM) $@
+ $(LN) $(TESTDIR)/setup $@
diff --git a/usr/src/test/libc-tests/tests/symbols/setup.ksh b/usr/src/test/libc-tests/tests/symbols/setup.ksh
new file mode 100755
index 0000000000..c753ac53ed
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/symbols/setup.ksh
@@ -0,0 +1,75 @@
+#!/usr/bin/ksh
+#
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+export STF_SUITE=/opt/libc-tests
+
+# First we set $dir to dirname $0, using efficient ksh builtins.
+case $0 in
+*/*)
+ dir=${0%/*}
+ prog=${0##*/}
+ ;;
+*)
+ dir=.
+ prog=${0}
+ ;;
+esac
+
+cfg=symbols/${prog%.ksh}.cfg
+
+if [[ ! -f ${cfg} && $cfg == symbols/setup.cfg ]]
+then
+ # compiler check only
+ cfg=-C
+fi
+
+prog=symbols_test
+
+for a in $*
+do
+ if [[ $a == "-d" ]]
+ then
+ debug=yes
+ fi
+done
+
+# We look for architecture specific versions of the program,
+# searching in several candidate directories. We run each one as
+# we find it.
+for f in $(/usr/bin/isainfo)
+do
+ found=
+ [[ -n $debug ]] && print "Checking for arch $f:"
+ for p in \
+ ${dir}/${prog}.${f} \
+ ${dir}/${f}/${prog}.${f} \
+ ${dir}/${f}/${prog}
+ do
+ [[ -n $found ]] && continue
+ [[ -n $debug ]] && print -n " $p"
+ if [[ -f $p ]]; then
+ [[ -n $debug ]] && print " FOUND"
+ [[ -n $debug ]] && print "Executing $p $* ${cfg}"
+ found=yes
+ $p $* ${cfg} || exit 1
+ else
+ [[ -n $debug ]] && print
+ fi
+ done
+ [[ -z $found ]] && [[ -n $debug ]] && print "NOT PRESENT"
+done
+exit 0
diff --git a/usr/src/test/libc-tests/tests/symbols/symbols_test.c b/usr/src/test/libc-tests/tests/symbols/symbols_test.c
new file mode 100644
index 0000000000..fa96cfe73c
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/symbols/symbols_test.c
@@ -0,0 +1,957 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2015 Garrett D'Amore <garrett@damore.org>
+ */
+
+/*
+ * This program tests symbol visibility using the /usr/bin/c89 and
+ * /usr/bin/c99 programs.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <note.h>
+#include <sys/wait.h>
+#include "test_common.h"
+
+char *dname;
+char *cfile;
+char *ofile;
+char *lfile;
+char *efile;
+
+const char *sym = NULL;
+
+static int good_count = 0;
+static int fail_count = 0;
+static int full_count = 0;
+static int extra_debug = 0;
+static char *compilation = "compilation.cfg";
+
+#if defined(_LP64)
+#define MFLAG "-m64"
+#elif defined(_ILP32)
+#define MFLAG "-m32"
+#endif
+
+const char *compilers[] = {
+ "cc",
+ "gcc",
+ "/opt/SUNWspro/bin/cc",
+ "/opt/gcc/4.4.4/bin/gcc",
+ "/opt/sunstudio12.1/bin/cc",
+ "/opt/sfw/bin/gcc",
+ "/usr/local/bin/gcc",
+ NULL
+};
+
+char *compiler = NULL;
+const char *c89flags = NULL;
+const char *c99flags = NULL;
+
+#define MAXENV 64 /* maximum number of environments (bitmask width) */
+#define MAXHDR 10 /* maximum # headers to require to access symbol */
+#define MAXARG 20 /* maximum # of arguments */
+
+#define WS " \t"
+
+static int next_env = 0;
+
+struct compile_env {
+ char *ce_name;
+ char *ce_lang;
+ char *ce_defs;
+ int ce_index;
+};
+
+static struct compile_env compile_env[MAXENV];
+
+struct env_group {
+ char *eg_name;
+ uint64_t eg_mask;
+ struct env_group *eg_next;
+};
+
+typedef enum { SYM_TYPE, SYM_VALUE, SYM_FUNC } sym_type_t;
+
+struct sym_test {
+ char *st_name;
+ sym_type_t st_type;
+ char *st_hdrs[MAXHDR];
+ char *st_rtype;
+ char *st_atypes[MAXARG];
+ uint64_t st_test_mask;
+ uint64_t st_need_mask;
+ char *st_prog;
+ struct sym_test *st_next;
+};
+
+struct env_group *env_groups = NULL;
+
+struct sym_test *sym_tests = NULL;
+struct sym_test **sym_insert = &sym_tests;
+
+static char *
+mystrdup(const char *s)
+{
+ char *r;
+ if ((r = strdup(s)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+ return (r);
+}
+
+static void *
+myzalloc(size_t sz)
+{
+ void *buf;
+ if ((buf = calloc(1, sz)) == NULL) {
+ perror("calloc");
+ exit(1);
+ }
+ return (buf);
+}
+
+static void
+myasprintf(char **buf, const char *fmt, ...)
+{
+ int rv;
+ va_list va;
+ va_start(va, fmt);
+ rv = vasprintf(buf, fmt, va);
+ va_end(va);
+ if (rv < 0) {
+ perror("vasprintf");
+ exit(1);
+ }
+}
+
+static void
+append_sym_test(struct sym_test *st)
+{
+ *sym_insert = st;
+ sym_insert = &st->st_next;
+}
+
+static int
+find_env_mask(const char *name, uint64_t *mask)
+{
+ for (int i = 0; i < MAXENV; i++) {
+ if (compile_env[i].ce_name != NULL &&
+ strcmp(compile_env[i].ce_name, name) == 0) {
+ *mask |= (1ULL << i);
+ return (0);
+ }
+ }
+
+ for (struct env_group *eg = env_groups; eg != NULL; eg = eg->eg_next) {
+ if (strcmp(name, eg->eg_name) == 0) {
+ *mask |= eg->eg_mask;
+ return (0);
+ }
+ }
+ return (-1);
+}
+
+
+static int
+expand_env(char *list, uint64_t *mask, char **erritem)
+{
+ char *item;
+ for (item = strtok(list, WS); item != NULL; item = strtok(NULL, WS)) {
+ if (find_env_mask(item, mask) < 0) {
+ if (erritem != NULL) {
+ *erritem = item;
+ }
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+static int
+expand_env_list(char *list, uint64_t *test, uint64_t *need, char **erritem)
+{
+ uint64_t mask = 0;
+ int act;
+ char *item;
+ for (item = strtok(list, WS); item != NULL; item = strtok(NULL, WS)) {
+ switch (item[0]) {
+ case '+':
+ act = 1;
+ item++;
+ break;
+ case '-':
+ act = 0;
+ item++;
+ break;
+ default:
+ act = 1;
+ break;
+ }
+
+ mask = 0;
+ if (find_env_mask(item, &mask) < 0) {
+ if (erritem != NULL) {
+ *erritem = item;
+ }
+ return (-1);
+ }
+ *test |= mask;
+ if (act) {
+ *need |= mask;
+ } else {
+ *need &= ~(mask);
+ }
+ }
+ return (0);
+}
+
+static int
+do_env(char **fields, int nfields, char **err)
+{
+ char *name;
+ char *lang;
+ char *defs;
+
+ if (nfields != 3) {
+ myasprintf(err, "number of fields (%d) != 3", nfields);
+ return (-1);
+ }
+
+ if (next_env >= MAXENV) {
+ myasprintf(err, "too many environments");
+ return (-1);
+ }
+
+ name = fields[0];
+ lang = fields[1];
+ defs = fields[2];
+
+ compile_env[next_env].ce_name = mystrdup(name);
+ compile_env[next_env].ce_lang = mystrdup(lang);
+ compile_env[next_env].ce_defs = mystrdup(defs);
+ compile_env[next_env].ce_index = next_env;
+ next_env++;
+ return (0);
+}
+
+static int
+do_env_group(char **fields, int nfields, char **err)
+{
+ char *name;
+ char *list;
+ struct env_group *eg;
+ uint64_t mask;
+ char *item;
+
+ if (nfields != 2) {
+ myasprintf(err, "number of fields (%d) != 2", nfields);
+ return (-1);
+ }
+
+ name = fields[0];
+ list = fields[1];
+ mask = 0;
+
+ if (expand_env(list, &mask, &item) < 0) {
+ myasprintf(err, "reference to undefined env %s", item);
+ return (-1);
+ }
+
+ eg = myzalloc(sizeof (*eg));
+ eg->eg_name = mystrdup(name);
+ eg->eg_mask = mask;
+ eg->eg_next = env_groups;
+ env_groups = eg;
+ return (0);
+}
+
+static char *progbuf = NULL;
+size_t proglen = 0;
+size_t progsiz = 0;
+
+static void
+addprogch(char c)
+{
+ while (progsiz <= (proglen + 1)) {
+ progbuf = realloc(progbuf, progsiz + 4096);
+ if (progbuf == NULL) {
+ perror("realloc");
+ exit(1);
+ }
+ progsiz += 1024;
+ }
+ progbuf[proglen++] = c;
+ progbuf[proglen] = 0;
+}
+
+static void
+addprogstr(char *s)
+{
+ while (*s != NULL) {
+ addprogch(*s);
+ s++;
+ }
+}
+
+static void
+addprogfmt(const char *fmt, ...)
+{
+ va_list va;
+ char *buf = NULL;
+ va_start(va, fmt);
+ if (vasprintf(&buf, fmt, va) < 0) {
+ perror("vasprintf");
+ exit(1);
+ }
+ va_end(va);
+ addprogstr(buf);
+ free(buf);
+}
+
+static void
+mkprog(struct sym_test *st)
+{
+ char *s;
+
+ proglen = 0;
+
+ for (int i = 0; i < MAXHDR && st->st_hdrs[i] != NULL; i++) {
+ addprogfmt("#include <%s>\n", st->st_hdrs[i]);
+ }
+
+ for (s = st->st_rtype; *s; s++) {
+ addprogch(*s);
+ if (*s == '(') {
+ s++;
+ addprogch(*s);
+ s++;
+ break;
+ }
+ }
+ addprogch(' ');
+
+ /* for function pointers, s is closing suffix, otherwise empty */
+
+ switch (st->st_type) {
+ case SYM_TYPE:
+ addprogstr("test_type;");
+ break;
+
+ case SYM_VALUE:
+ addprogfmt("test_value%s;\n", s); /* s usually empty */
+ addprogstr("void\ntest_func(void)\n{\n");
+ addprogfmt("\ttest_value = %s;\n}", st->st_name);
+ break;
+
+ case SYM_FUNC:
+ addprogstr("\ntest_func(");
+ for (int i = 0; st->st_atypes[i] != NULL && i < MAXARG; i++) {
+ int didname = 0;
+ if (i > 0) {
+ addprogstr(", ");
+ }
+ if (strcmp(st->st_atypes[i], "void") == 0) {
+ didname = 1;
+ }
+ if (strcmp(st->st_atypes[i], "") == 0) {
+ didname = 1;
+ addprogstr("void");
+ }
+
+ /* print the argument list */
+ for (char *a = st->st_atypes[i]; *a; a++) {
+ if (*a == '(' && a[1] == '*' && !didname) {
+ addprogfmt("(*a%d", i);
+ didname = 1;
+ a++;
+ } else if (*a == '[' && !didname) {
+ addprogfmt("a%d[", i);
+ didname = 1;
+ } else {
+ addprogch(*a);
+ }
+ }
+ if (!didname) {
+ addprogfmt(" a%d", i);
+ }
+ }
+
+ if (st->st_atypes[0] == NULL) {
+ addprogstr("void");
+ }
+
+ /*
+ * Close argument list, and closing ")" for func ptrs.
+ * Note that for non-function pointers, s will be empty
+ * below, otherwise it points to the trailing argument
+ * list.
+ */
+ addprogfmt(")%s\n{\n\t", s);
+
+ if (strcmp(st->st_rtype, "") != 0 &&
+ strcmp(st->st_rtype, "void") != 0) {
+ addprogstr("return ");
+ }
+
+ /* add the function call */
+ addprogfmt("%s(", st->st_name);
+ for (int i = 0; st->st_atypes[i] != NULL && i < MAXARG; i++) {
+ if (strcmp(st->st_atypes[i], "") != 0 &&
+ strcmp(st->st_atypes[i], "void") != 0) {
+ addprogfmt("%sa%d", i > 0 ? ", " : "", i);
+ }
+ }
+
+ addprogstr(");\n}");
+ break;
+ }
+
+ addprogch('\n');
+
+ st->st_prog = progbuf;
+}
+
+static int
+add_envs(struct sym_test *st, char *envs, char **err)
+{
+ char *item;
+ if (expand_env_list(envs, &st->st_test_mask, &st->st_need_mask,
+ &item) < 0) {
+ myasprintf(err, "bad env action %s", item);
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+add_headers(struct sym_test *st, char *hdrs, char **err)
+{
+ int i = 0;
+
+ for (char *h = strsep(&hdrs, ";"); h != NULL; h = strsep(&hdrs, ";")) {
+ if (i >= MAXHDR) {
+ myasprintf(err, "too many headers");
+ return (-1);
+ }
+ test_trim(&h);
+ st->st_hdrs[i++] = mystrdup(h);
+ }
+
+ return (0);
+}
+
+static int
+add_arg_types(struct sym_test *st, char *atype, char **err)
+{
+ int i = 0;
+ char *a;
+ for (a = strsep(&atype, ";"); a != NULL; a = strsep(&atype, ";")) {
+ if (i >= MAXARG) {
+ myasprintf(err, "too many arguments");
+ return (-1);
+ }
+ test_trim(&a);
+ st->st_atypes[i++] = mystrdup(a);
+ }
+
+ return (0);
+}
+
+static int
+do_type(char **fields, int nfields, char **err)
+{
+ char *decl;
+ char *hdrs;
+ char *envs;
+ struct sym_test *st;
+
+ if (nfields != 3) {
+ myasprintf(err, "number of fields (%d) != 3", nfields);
+ return (-1);
+ }
+ decl = fields[0];
+ hdrs = fields[1];
+ envs = fields[2];
+
+ st = myzalloc(sizeof (*st));
+ st->st_type = SYM_TYPE;
+ st->st_name = mystrdup(decl);
+ st->st_rtype = mystrdup(decl);
+
+ if ((add_envs(st, envs, err) < 0) ||
+ (add_headers(st, hdrs, err) < 0)) {
+ return (-1);
+ }
+ append_sym_test(st);
+
+ return (0);
+}
+
+static int
+do_value(char **fields, int nfields, char **err)
+{
+ char *name;
+ char *type;
+ char *hdrs;
+ char *envs;
+ struct sym_test *st;
+
+ if (nfields != 4) {
+ myasprintf(err, "number of fields (%d) != 4", nfields);
+ return (-1);
+ }
+ name = fields[0];
+ type = fields[1];
+ hdrs = fields[2];
+ envs = fields[3];
+
+ st = myzalloc(sizeof (*st));
+ st->st_type = SYM_VALUE;
+ st->st_name = mystrdup(name);
+ st->st_rtype = mystrdup(type);
+
+ if ((add_envs(st, envs, err) < 0) ||
+ (add_headers(st, hdrs, err) < 0)) {
+ return (-1);
+ }
+ append_sym_test(st);
+
+ return (0);
+}
+
+static int
+do_func(char **fields, int nfields, char **err)
+{
+ char *name;
+ char *rtype;
+ char *atype;
+ char *hdrs;
+ char *envs;
+ struct sym_test *st;
+
+ if (nfields != 5) {
+ myasprintf(err, "number of fields (%d) != 5", nfields);
+ return (-1);
+ }
+ name = fields[0];
+ rtype = fields[1];
+ atype = fields[2];
+ hdrs = fields[3];
+ envs = fields[4];
+
+ st = myzalloc(sizeof (*st));
+ st->st_type = SYM_FUNC;
+ st->st_name = mystrdup(name);
+ st->st_rtype = mystrdup(rtype);
+
+ if ((add_envs(st, envs, err) < 0) ||
+ (add_headers(st, hdrs, err) < 0) ||
+ (add_arg_types(st, atype, err) < 0)) {
+ return (-1);
+ }
+ append_sym_test(st);
+
+ return (0);
+}
+
+struct sym_test *
+next_sym_test(struct sym_test *st)
+{
+ return (st == NULL ? sym_tests : st->st_next);
+}
+
+const char *
+sym_test_prog(struct sym_test *st)
+{
+ if (st->st_prog == NULL) {
+ mkprog(st);
+ }
+ return (st->st_prog);
+}
+
+const char *
+sym_test_name(struct sym_test *st)
+{
+ return (st->st_name);
+}
+
+/*
+ * Iterate through tests. Pass in NULL for cenv to begin the iteration. For
+ * subsequent iterations, use the return value from the previous iteration.
+ * Returns NULL when there are no more environments.
+ */
+struct compile_env *
+sym_test_env(struct sym_test *st, struct compile_env *cenv, int *need)
+{
+ int i = cenv ? cenv->ce_index + 1: 0;
+ uint64_t b = 1ULL << i;
+
+ while ((i < MAXENV) && (b != 0)) {
+ cenv = &compile_env[i];
+ if (b & st->st_test_mask) {
+ *need = (st->st_need_mask & b) ? 1 : 0;
+ return (cenv);
+ }
+ b <<= 1;
+ i++;
+ }
+ return (NULL);
+}
+
+const char *
+env_name(struct compile_env *cenv)
+{
+ return (cenv->ce_name);
+}
+
+const char *
+env_lang(struct compile_env *cenv)
+{
+ return (cenv->ce_lang);
+}
+
+const char *
+env_defs(struct compile_env *cenv)
+{
+ return (cenv->ce_defs);
+}
+
+static void
+show_file(test_t t, const char *path)
+{
+ FILE *f;
+ char *buf = NULL;
+ size_t cap = 0;
+ int line = 1;
+
+ f = fopen(path, "r");
+ if (f == NULL) {
+ test_debugf(t, "fopen(%s): %s", path, strerror(errno));
+ return;
+ }
+
+ test_debugf(t, "----->> begin (%s) <<------", path);
+ while (getline(&buf, &cap, f) >= 0) {
+ (void) strtok(buf, "\r\n");
+ test_debugf(t, "%d: %s", line, buf);
+ line++;
+ }
+ test_debugf(t, "----->> end (%s) <<------", path);
+ (void) fclose(f);
+}
+
+static void
+cleanup(void)
+{
+ if (ofile != NULL) {
+ (void) unlink(ofile);
+ free(ofile);
+ ofile = NULL;
+ }
+ if (lfile != NULL) {
+ (void) unlink(lfile);
+ free(lfile);
+ lfile = NULL;
+ }
+ if (cfile != NULL) {
+ (void) unlink(cfile);
+ free(cfile);
+ cfile = NULL;
+ }
+ if (efile != NULL) {
+ (void) unlink(efile);
+ free(efile);
+ efile = NULL;
+ }
+ if (dname) {
+ (void) rmdir(dname);
+ free(dname);
+ dname = NULL;
+ }
+}
+
+static int
+mkworkdir(void)
+{
+ char b[32];
+ char *d;
+
+ cleanup();
+
+ (void) strlcpy(b, "/tmp/symbols_testXXXXXX", sizeof (b));
+ if ((d = mkdtemp(b)) == NULL) {
+ perror("mkdtemp");
+ return (-1);
+ }
+ dname = mystrdup(d);
+ myasprintf(&cfile, "%s/compile_test.c", d);
+ myasprintf(&ofile, "%s/compile_test.o", d);
+ myasprintf(&lfile, "%s/compile_test.log", d);
+ myasprintf(&efile, "%s/compile_test.exe", d);
+ return (0);
+}
+
+void
+find_compiler(void)
+{
+ test_t t;
+ int i;
+ FILE *cf;
+
+ t = test_start("finding compiler");
+
+ if ((cf = fopen(cfile, "w+")) == NULL) {
+ test_failed(t, "Unable to open %s for write: %s", cfile,
+ strerror(errno));
+ return;
+ }
+ (void) fprintf(cf, "#include <stdio.h>\n");
+ (void) fprintf(cf, "int main(int argc, char **argv) {\n");
+ (void) fprintf(cf, "#if defined(__SUNPRO_C)\n");
+ (void) fprintf(cf, "exit(51);\n");
+ (void) fprintf(cf, "#elif defined(__GNUC__)\n");
+ (void) fprintf(cf, "exit(52);\n");
+ (void) fprintf(cf, "#else\n");
+ (void) fprintf(cf, "exit(99)\n");
+ (void) fprintf(cf, "#endif\n}\n");
+ (void) fclose(cf);
+
+ for (i = 0; compilers[i] != NULL; i++) {
+ char cmd[256];
+ int rv;
+
+ (void) snprintf(cmd, sizeof (cmd),
+ "%s %s %s -o %s >/dev/null 2>&1",
+ compilers[i], MFLAG, cfile, efile);
+ test_debugf(t, "trying %s", cmd);
+ rv = system(cmd);
+
+ test_debugf(t, "result: %d", rv);
+
+ if ((rv < 0) || !WIFEXITED(rv) || WEXITSTATUS(rv) != 0)
+ continue;
+
+ rv = system(efile);
+ if (rv >= 0 && WIFEXITED(rv)) {
+ rv = WEXITSTATUS(rv);
+ } else {
+ rv = -1;
+ }
+
+ switch (rv) {
+ case 51: /* STUDIO */
+ test_debugf(t, "Found Studio C");
+ c89flags = "-Xc -errwarn=%all -v -xc99=%none " MFLAG;
+ c99flags = "-Xc -errwarn=%all -v -xc99=%all " MFLAG;
+ if (extra_debug) {
+ test_debugf(t, "c89flags: %s", c89flags);
+ test_debugf(t, "c99flags: %s", c99flags);
+ }
+ test_passed(t);
+ break;
+ case 52: /* GCC */
+ test_debugf(t, "Found GNU C");
+ c89flags = "-Wall -Werror -std=c89 " MFLAG;
+ c99flags = "-Wall -Werror -std=c99 " MFLAG;
+ if (extra_debug) {
+ test_debugf(t, "c89flags: %s", c89flags);
+ test_debugf(t, "c99flags: %s", c99flags);
+ }
+ test_passed(t);
+ break;
+ case 99:
+ test_debugf(t, "Found unknown (unsupported) compiler");
+ continue;
+ default:
+ continue;
+ }
+ myasprintf(&compiler, "%s", compilers[i]);
+ test_debugf(t, "compiler: %s", compiler);
+ return;
+ }
+ test_failed(t, "No compiler found.");
+}
+
+int
+do_compile(test_t t, struct sym_test *st, struct compile_env *cenv, int need)
+{
+ char *cmd;
+ FILE *logf;
+ FILE *dotc;
+ const char *prog;
+
+ full_count++;
+
+ if ((dotc = fopen(cfile, "w+")) == NULL) {
+ test_failed(t, "fopen(%s): %s", cfile, strerror(errno));
+ return (-1);
+ }
+ prog = sym_test_prog(st);
+ if (fwrite(prog, 1, strlen(prog), dotc) < strlen(prog)) {
+ test_failed(t, "fwrite: %s", strerror(errno));
+ (void) fclose(dotc);
+ return (-1);
+ }
+ if (fclose(dotc) < 0) {
+ test_failed(t, "fclose: %s", strerror(errno));
+ return (-1);
+ }
+
+ (void) unlink(ofile);
+
+ myasprintf(&cmd, "%s %s %s -c %s -o %s >>%s 2>&1",
+ compiler, strcmp(env_lang(cenv), "c99") == 0 ? c99flags : c89flags,
+ env_defs(cenv), cfile, ofile, lfile);
+
+ if (extra_debug) {
+ test_debugf(t, "command: %s", cmd);
+ }
+
+ if ((logf = fopen(lfile, "w+")) == NULL) {
+ test_failed(t, "fopen: %s", strerror(errno));
+ return (-1);
+ }
+ (void) fprintf(logf, "===================\n");
+ (void) fprintf(logf, "PROGRAM:\n%s\n", sym_test_prog(st));
+ (void) fprintf(logf, "COMMAND: %s\n", cmd);
+ (void) fprintf(logf, "EXPECT: %s\n", need ? "OK" : "FAIL");
+ (void) fclose(logf);
+
+ switch (system(cmd)) {
+ case -1:
+ test_failed(t, "error compiling in %s: %s", env_name(cenv),
+ strerror(errno));
+ return (-1);
+ case 0:
+ if (!need) {
+ fail_count++;
+ show_file(t, lfile);
+ test_failed(t, "symbol visible in %s", env_name(cenv));
+ return (-1);
+ }
+ break;
+ default:
+ if (need) {
+ fail_count++;
+ show_file(t, lfile);
+ test_failed(t, "error compiling in %s", env_name(cenv));
+ return (-1);
+ }
+ break;
+ }
+ good_count++;
+ return (0);
+}
+
+void
+test_compile(void)
+{
+ struct sym_test *st;
+ struct compile_env *cenv;
+ test_t t;
+ int need;
+
+ for (st = next_sym_test(NULL); st; st = next_sym_test(st)) {
+ if ((sym != NULL) && strcmp(sym, sym_test_name(st))) {
+ continue;
+ }
+ /* XXX: we really want a sym_test_desc() */
+ for (cenv = sym_test_env(st, NULL, &need);
+ cenv != NULL;
+ cenv = sym_test_env(st, cenv, &need)) {
+ t = test_start("%s : %c%s", sym_test_name(st),
+ need ? '+' : '-', env_name(cenv));
+ if (do_compile(t, st, cenv, need) == 0) {
+ test_passed(t);
+ }
+ }
+ }
+
+ if (full_count > 0) {
+ test_summary();
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int optc;
+ int optC = 0;
+
+ while ((optc = getopt(argc, argv, "DdfCs:c:")) != EOF) {
+ switch (optc) {
+ case 'd':
+ test_set_debug();
+ break;
+ case 'f':
+ test_set_force();
+ break;
+ case 'D':
+ test_set_debug();
+ extra_debug++;
+ break;
+ case 'c':
+ compilation = optarg;
+ break;
+ case 'C':
+ optC++;
+ break;
+ case 's':
+ sym = optarg;
+ break;
+ default:
+ (void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]);
+ exit(1);
+ }
+ }
+
+ if (test_load_config(NULL, compilation,
+ "env", do_env, "env_group", do_env_group, NULL) < 0) {
+ exit(1);
+ }
+
+ while (optind < argc) {
+ if (test_load_config(NULL, argv[optind++],
+ "type", do_type,
+ "value", do_value,
+ "func", do_func,
+ NULL) < 0) {
+ exit(1);
+ }
+ }
+
+ if (atexit(cleanup) != 0) {
+ perror("atexit");
+ exit(1);
+ }
+
+ if (mkworkdir() < 0) {
+ perror("mkdir");
+ exit(1);
+ }
+
+ find_compiler();
+ if (!optC)
+ test_compile();
+
+ exit(0);
+}