diff options
64 files changed, 1630 insertions, 276 deletions
diff --git a/test/Makefile b/test/Makefile index a7376941a..4505e8959 100644 --- a/test/Makefile +++ b/test/Makefile @@ -30,7 +30,12 @@ ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y) DIRS += $(filter-out tls nptl,$(DIRS)) endif -test check all: subdirs + +test check all: run + +run: compile subdirs_run + +compile:subdirs_compile tags: ctags -R @@ -38,12 +43,20 @@ tags: clean: subdirs_clean subdirs: $(patsubst %, _dir_%, $(DIRS)) +subdirs_compile: $(patsubst %, _dircompile_%, $(DIRS)) +subdirs_run: $(patsubst %, _dirrun_%, $(DIRS)) subdirs_clean: $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) $(patsubst %, _dir_%, $(DIRS)) : dummy $(Q)$(MAKE) -C $(patsubst _dir_%, %, $@) +$(patsubst %, _dirrun_%, $(DIRS)) : dummy + $(Q)$(MAKE) -C $(patsubst _dirrun_%, %, $@) run + +$(patsubst %, _dircompile_%, $(DIRS)) : dummy + $(Q)$(MAKE) -C $(patsubst _dircompile_%, %, $@) compile + $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) : dummy $(Q)$(MAKE) -C $(patsubst _dirclean_%, %, $@) clean -.PHONY: all check clean dummy subdirs subdirs_clean test +.PHONY: all check clean dummy subdirs_compile subdirs_run subdirs subdirs_clean test run compile diff --git a/test/README b/test/README index fe07a53f5..b59945c54 100644 --- a/test/README +++ b/test/README @@ -1,14 +1,29 @@ ----------- For: User ----------- +Following make targets are avaialable + +make compile + +This will compile and link the tests + +make run + +This will check for binaries if they are not there it +will call 'compile' target then it will execute all the +tests. + +make check +make all + +This will build and run tests. The following make variables may help you in testing: - UCLIBC_ONLY - only run tests against uClibc - GLIBC_ONLY - only run tests against glibc - - COMPILE_ONLY - just build the tests, don't run them - - CHECK_ONLY - only run the tests, don't compile or link them - V / VERBOSE - run tests with a lot of output - + - TEST_INSTALLED_UCLIBC - Test installed libraries + under /lib and /usr/lib. So, to just run the uClibc tests, try this: make check UCLIBC_ONLY=1 diff --git a/test/Rules.mak b/test/Rules.mak index eb8745f05..714a9786a 100644 --- a/test/Rules.mak +++ b/test/Rules.mak @@ -10,10 +10,11 @@ # top_builddir ?= ../ + TESTDIR=$(top_builddir)test/ include $(top_builddir)/Rules.mak - +ifndef TEST_INSTALLED_UCLIBC ifdef UCLIBC_LDSO ifeq (,$(findstring /,$(UCLIBC_LDSO))) UCLIBC_LDSO := $(top_builddir)lib/$(UCLIBC_LDSO) @@ -21,7 +22,7 @@ endif else UCLIBC_LDSO := $(firstword $(wildcard $(top_builddir)lib/ld*)) endif - +endif #-------------------------------------------------------- # Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc. LC_ALL:= C @@ -38,6 +39,7 @@ TARGET_ARCH:=$(shell $(CC) -dumpmachine | sed -e s'/-.*//' \ -e 's/sh[234]/sh/' \ -e 's/mips.*/mips/' \ -e 's/cris.*/cris/' \ + -e 's/xtensa.*/xtensa/' \ ) endif export TARGET_ARCH @@ -85,11 +87,11 @@ LDFLAGS := $(CPU_LDFLAGS) ifeq ($(DODEBUG),y) CFLAGS += -g HOST_CFLAGS += -g - LDFLAGS += -g -Wl,-warn-common - HOST_LDFLAGS += -g -Wl,-warn-common + LDFLAGS += -g + HOST_LDFLAGS += -g else - LDFLAGS += -s -Wl,-warn-common - HOST_LDFLAGS += -s -Wl,-warn-common + LDFLAGS += -s + HOST_LDFLAGS += -s endif ifeq ($(strip $(UCLIBC_STATIC)),y) @@ -97,8 +99,14 @@ ifeq ($(strip $(UCLIBC_STATIC)),y) HOST_LDFLAGS += -static endif LDFLAGS += -B$(top_builddir)lib -Wl,-rpath,$(top_builddir)lib -Wl,-rpath-link,$(top_builddir)lib +UCLIBC_LDSO_ABSPATH=$(shell pwd) +ifdef TEST_INSTALLED_UCLIBC +LDFLAGS += -Wl,-rpath,./ +UCLIBC_LDSO_ABSPATH=/lib +endif + ifeq ($(findstring -static,$(STATIC_LDFLAGS)),) -LDFLAGS += -Wl,--dynamic-linker,$(UCLIBC_LDSO) + LDFLAGS += -Wl,--dynamic-linker,$(UCLIBC_LDSO_ABSPATH)/$(UCLIBC_LDSO) endif ifeq ($(LDSO_GNU_HASH_SUPPORT),y) @@ -129,7 +137,7 @@ banner := --------------------------------- pur_showclean = echo " "CLEAN $(notdir $(CURDIR)) pur_showdiff = echo " "TEST_DIFF $(notdir $(CURDIR))/ pur_showlink = echo " "TEST_LINK $(notdir $(CURDIR))/ $@ -pur_showtest = echo " "TEST_EXEC $(notdir $(CURDIR))/ $@ +pur_showtest = echo " "TEST_EXEC $(notdir $(CURDIR))/ $(patsubst %.exe,%,$@) sil_showclean = sil_showdiff = true sil_showlink = true @@ -137,7 +145,7 @@ sil_showtest = true ver_showclean = ver_showdiff = true echo ver_showlink = true echo -ver_showtest = printf "\n$(banner)\nTEST $(notdir $(PWD))/ $@\n$(banner)\n" +ver_showtest = printf "\n$(banner)\nTEST $(notdir $(PWD))/ $(patsubst %.exe,%,$@)\n$(banner)\n" do_showclean = $($(DISP)_showclean) do_showdiff = $($(DISP)_showdiff) do_showlink = $($(DISP)_showlink) diff --git a/test/Test.mak b/test/Test.mak index 34e8a5308..69291a61e 100644 --- a/test/Test.mak +++ b/test/Test.mak @@ -23,10 +23,7 @@ include ../Rules.mak U_TARGETS := $(TESTS) G_TARGETS := $(patsubst %,%_glibc,$(U_TARGETS)) -U_TARGETS += $(U_TESTS) -G_TARGETS += $(G_TESTS) -TARGETS := $(SHELL_TESTS) ifeq ($(GLIBC_ONLY),) TARGETS += $(U_TARGETS) endif @@ -34,70 +31,77 @@ ifeq ($(UCLIBC_ONLY),) TARGETS += $(G_TARGETS) endif CLEAN_TARGETS := $(U_TARGETS) $(G_TARGETS) +COMPILE_TARGETS := $(TARGETS) +TARGETS += $(SHELL_TESTS) +RUN_TARGETS := $(patsubst %,%.exe,$(TARGETS)) -test check all: $(TARGETS) - -$(TARGETS): Makefile $(TESTDIR)Makefile $(TESTDIR)Rules.mak $(TESTDIR)Test.mak -$(U_TARGETS): $(patsubst %,%.c,$(U_TARGETS)) -$(G_TARGETS): $(patsubst %_glibc,%.c,$(G_TARGETS)) +define binary_name +$(patsubst %.exe,%,$@) +endef define diff_test $(Q)\ - for x in "$@.out" "$(patsubst %_glibc,%,$@).out" ; do \ - test -e "$$x.good" && $(do_showdiff) "$@.out" "$$x.good" && exec diff -u "$@.out" "$$x.good" ; \ + for x in "$(binary_name).out" "$(patsubst %_glibc,%,$(binary_name)).out" ; do \ + test -e "$$x.good" && $(do_showdiff) "$(binary_name).out" "$$x.good" && exec diff -u "$(binary_name).out" "$$x.good" ; \ done ; \ true endef define uclibc_glibc_diff_test $(Q)\ - test -z "$(DODIFF_$(patsubst %_glibc,%,$@))" && exec true ; \ - uclibc_out="$@.out" ; \ - glibc_out="$(patsubst %_glibc,%,$@).out" ; \ + test -z "$(DODIFF_$(patsubst %_glibc,%,$(binary_name)))" && exec true ; \ + uclibc_out="$(binary_name).out" ; \ + glibc_out="$(patsubst %_glibc,%,$(binary_name)).out" ; \ $(do_showdiff) $$uclibc_out $$glibc_out ; \ exec diff -u "$$uclibc_out" "$$glibc_out" endef define exec_test $(showtest) $(Q)\ - $(WRAPPER) $(WRAPPER_$(patsubst %_glibc,%,$@)) \ - ./$@ $(OPTS) $(OPTS_$(patsubst %_glibc,%,$@)) &> "$@.out" ; \ + $(WRAPPER) $(WRAPPER_$(patsubst %_glibc,%,$(binary_name))) \ + ./$(binary_name) $(OPTS) $(OPTS_$(patsubst %_glibc,%,$(binary_name))) &> "$(binary_name).out" ; \ ret=$$? ; \ - expected_ret="$(RET_$(patsubst %_glibc,%,$@))" ; \ + expected_ret="$(RET_$(patsubst %_glibc,%,$(binary_name)))" ; \ test -z "$$expected_ret" && export expected_ret=0 ; \ if ! test $$ret -eq $$expected_ret ; then \ - $(RM) $@ ; \ - cat "$@.out" ; \ - exec false ; \ + echo "ret == $$ret ; expected_ret == $$expected_ret" ; \ + cat "$(binary_name).out" ; \ + exit 1 ; \ fi - $(SCAT) "$@.out" + $(SCAT) "$(binary_name).out" endef -$(U_TARGETS): -ifeq ($(CHECK_ONLY),) - $(showlink) - $(Q)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c $@.c -o $@.o - $(Q)$(CC) $(STATIC_LDFLAGS) $(LDFLAGS) $@.o -o $@ $(LDFLAGS_$@) $(EXTRA_LDFLAGS) -endif -ifeq ($(COMPILE_ONLY),) +test check all: run +run: $(RUN_TARGETS) compile +$(RUN_TARGETS): $(TARGETS) +ifeq ($(shell echo "$(SHELL_TESTS)"|grep "$(binary_name)"),) $(exec_test) $(diff_test) +ifeq ($(UCLIBC_ONLY),) + $(uclibc_glibc_diff_test) +endif endif -$(G_TARGETS): +compile: $(COMPILE_TARGETS) + +G_TARGET_SRCS := $(patsubst %,%.c,$(G_TARGETS)) +U_TARGET_SRCS := $(patsubst %,%.c,$(U_TARGETS)) + +$(MAKE_SRCS): Makefile $(TESTDIR)Makefile $(TESTDIR)Rules.mak $(TESTDIR)Test.mak + +$(U_TARGETS): $(U_TARGET_SRCS) $(MAKE_SRCS) + $(showlink) + $(Q)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c $@.c -o $@.o + $(Q)$(CC) $(LDFLAGS) $@.o -o $@ $(EXTRA_LDFLAGS) $(LDFLAGS_$@) + +$(G_TARGETS): $(U_TARGET_SRCS) $(MAKE_SRCS) $(showlink) $(Q)$(HOSTCC) $(HOST_CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(patsubst %_glibc,%,$@)) -c $(patsubst %_glibc,%,$@).c -o $@.o $(Q)$(HOSTCC) $(HOST_LDFLAGS) $@.o -o $@ $(EXTRA_LDFLAGS) $(LDFLAGS_$(patsubst %_glibc,%,$@)) -ifeq ($(COMPILE_ONLY),) - $(exec_test) - $(diff_test) - $(uclibc_glibc_diff_test) -endif + shell_%: -ifeq ($(COMPILE_ONLY),) $(showtest) - $(Q)$(SHELL) $(patsubst shell_%,%.sh,$@) -endif + $(Q)$(SHELL) $(patsubst shell_%,%.sh,$(binary_name)) %.so: %.c $(showlink) @@ -110,4 +114,4 @@ clean: $(showclean) $(Q)$(RM) *.a *.o *.so *~ core *.out *.gdb $(CLEAN_TARGETS) $(EXTRA_CLEAN) -.PHONY: all check clean test +.PHONY: all check clean test run compile diff --git a/test/assert/assert.c b/test/assert/assert.c index b0f54c625..c7058ff59 100644 --- a/test/assert/assert.c +++ b/test/assert/assert.c @@ -6,6 +6,8 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ +#undef NDEBUG + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -14,7 +16,7 @@ int got_abort; -void aborthandler(int junk) +static void aborthandler(int junk) { got_abort = 1; } @@ -29,9 +31,7 @@ int main(int argc, char *argv[]) assert(0 == 0); TEST_NUMERIC(got_abort, 0); -#ifndef NDEBUG -# define NDEBUG -#endif +#define NDEBUG got_abort = 0; printf("Don't worry -- This next test is supposed to print an assert message:\n"); fprintf(stderr, "\t"); diff --git a/test/build/check_config_options.sh b/test/build/check_config_options.sh index 56d09244b..086131f38 100644 --- a/test/build/check_config_options.sh +++ b/test/build/check_config_options.sh @@ -4,14 +4,15 @@ ret=0 # Make sure nothing uses the ARCH_HAS_MMU option anymore result=$( -grep -rsHI \ - __ARCH_HAS_MMU__ ../.. \ +find ../.. \ | grep -v \ -e include/bits/uClibc_config.h \ - -e test/build/check_config_options.sh \ - -e /.svn/ + -e /test/ \ + -e /.svn/ \ + | xargs grep -sHI \ + __ARCH_HAS_MMU__ ) -if test -n "$result" ; then +if [ -n "$result" ] ; then echo "The build system is incorrectly using ARCH_HAS_MMU:" echo "$result" ret=1 diff --git a/test/dlopen/Makefile b/test/dlopen/Makefile index 8f1b8330b..55231b8e8 100644 --- a/test/dlopen/Makefile +++ b/test/dlopen/Makefile @@ -4,7 +4,7 @@ # rules need a little love to work with glibc ... export UCLIBC_ONLY := 1 -TESTS := dltest dltest2 test1 test2 test3 dladdr +TESTS := dltest dltest2 dlstatic test1 test2 test3 dlundef dlafk dladdr ifeq ($(UCLIBC_STATIC),y) TESTS_DISABLED := test3 @@ -13,21 +13,29 @@ endif include ../Test.mak -CFLAGS_dltest := -DLIBNAME="\"./libtest.so\"" -CFLAGS_dltest2 := -DLIBNAME="\"./libtest3.so\"" +CFLAGS_dltest := -DLIBNAME="\"./libtest.so\"" +CFLAGS_dltest2 := -DLIBNAME="\"./libtest3.so\"" -LDFLAGS_dltest := -ldl -lpthread -LDFLAGS_dltest2 := -ldl -lpthread -LDFLAGS_test1 := -ldl -LDFLAGS_test2 := -ldl -LDFLAGS_test3 := -ldl ./libtest1.so ./libtest2.so -Wl,-rpath,. -LDFLAGS_dladdr := -ldl +LDFLAGS_dlstatic := -ldl +LDFLAGS_dltest := -ldl -lpthread +LDFLAGS_dltest2 := -ldl -lpthread +LDFLAGS_dlundef := -ldl +LDFLAGS_dlafk := -ldl ./libafk.so -Wl,-rpath,. +LDFLAGS_test1 := -ldl +LDFLAGS_test2 := -ldl +LDFLAGS_test3 := -ldl ./libtest1.so ./libtest2.so -Wl,-rpath,. +LDFLAGS_dladdr := -ldl DEBUG_LIBS := X WRAPPER := env $(DEBUG_LIBS)=all LD_LIBRARY_PATH="$$PWD:.:$(LD_LIBRARY_PATH)" dltest: libtest.so dltest2: libtest3.so +dlstatic: libstatic.so +dlundef: libundef.so +dlafk: libafk.so +libafk.so: libafk-temp.so +LDFLAGS_libafk.so := ./libafk-temp.so -Wl,-rpath,. test1: libtest1.so test2: libtest1.so libtest2.so test3: libtest1.so libtest2.so diff --git a/test/dlopen/dladdr.c b/test/dlopen/dladdr.c index b64c000bc..47ecea1da 100644 --- a/test/dlopen/dladdr.c +++ b/test/dlopen/dladdr.c @@ -1,25 +1,25 @@ -#include <dlfcn.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -int main(int argc, char **argv) -{ - Dl_info info; - int res = 0; - - memset(&info, '\0', sizeof(Dl_info)); - res = dladdr((void *)1, &info); - if (res != 0) { - fprintf(stderr, "dladdr() should fail\n"); - fprintf(stderr, "dli_fname = %s\n", info.dli_fname); - fprintf(stderr, "dli_fbase = 0x%08x\n", (unsigned int)info.dli_fbase); - fprintf(stderr, "dli_sname = %s\n", info.dli_sname); - fprintf(stderr, "dli_saddr = 0x%08x\n", (unsigned int)info.dli_saddr); - exit(1); - } - - fprintf(stderr, "dladdr() failed as expected\n"); - return EXIT_SUCCESS; -} - +#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ Dl_info info;
+ int res = 0;
+
+ memset(&info, '\0', sizeof(Dl_info));
+ res = dladdr((void *)1, &info);
+ if (res != 0) {
+ fprintf(stderr, "dladdr() should fail\n");
+ fprintf(stderr, "dli_fname = %s\n", info.dli_fname);
+ fprintf(stderr, "dli_fbase = 0x%08x\n", (unsigned int)info.dli_fbase);
+ fprintf(stderr, "dli_sname = %s\n", info.dli_sname);
+ fprintf(stderr, "dli_saddr = 0x%08x\n", (unsigned int)info.dli_saddr);
+ exit(1);
+ }
+
+ fprintf(stderr, "dladdr() failed as expected\n");
+ return EXIT_SUCCESS;
+}
+
diff --git a/test/dlopen/dlafk.c b/test/dlopen/dlafk.c new file mode 100644 index 000000000..2eac4afb2 --- /dev/null +++ b/test/dlopen/dlafk.c @@ -0,0 +1,36 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#define LIBNAME "libafk.so" + +#define LIBAFK "libafk-temp.so" +#define LIBAFK_BAK ".libafk-temp.so.temp" + +int main(int argc, char **argv) +{ + void *handle; + + if (rename(LIBAFK, LIBAFK_BAK)) { + fprintf(stderr, "Unable to rename %s: %s\n", LIBAFK, strerror(errno)); + return EXIT_FAILURE; + } + + handle = dlopen(LIBNAME, RTLD_NOW); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + return EXIT_FAILURE; + } + + if (rename(LIBAFK_BAK, LIBAFK)) { + fprintf(stderr, "Unable to rename %s: %s\n", LIBAFK_BAK, strerror(errno)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/test/dlopen/dlstatic.c b/test/dlopen/dlstatic.c new file mode 100644 index 000000000..57c8c5dd1 --- /dev/null +++ b/test/dlopen/dlstatic.c @@ -0,0 +1,43 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> + +#define LIBNAME "libstatic.so" + +int load_and_test(void) +{ + void *handle; + int (*mystatic)(void); + + handle = dlopen(LIBNAME, RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + return 1; + } + + mystatic = dlsym(handle, "static_test"); + if (mystatic == NULL) { + fprintf(stderr, "Could not locate symbol 'static_test': %s\n", dlerror()); + return 1; + } + + if (!mystatic()) { + fprintf(stderr, "mystatic() failed: static vars were not setup properly\n"); + return 1; + } + + dlclose(handle); + + return 0; +} + +int main(int argc, char **argv) +{ + int count = 5; + while (count-- > 0) + if (load_and_test()) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/test/dlopen/dltest.c b/test/dlopen/dltest.c index 230f7fd1d..6bec6e00e 100644 --- a/test/dlopen/dltest.c +++ b/test/dlopen/dltest.c @@ -4,11 +4,7 @@ #include <dlfcn.h> #include <stdint.h> -#ifdef __UCLIBC__ -extern void _dlinfo(void); -#endif - -int main(int argc, char **argv) +int main(int argc, char **argv) { int ret = EXIT_SUCCESS; void *handle; @@ -18,7 +14,7 @@ int main(int argc, char **argv) handle = dlopen (LIBNAME, RTLD_LAZY); if (!handle) { - fprintf(stderr, "Could not open ./libtest.so: %s\n", dlerror()); + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); exit(1); } diff --git a/test/dlopen/dlundef.c b/test/dlopen/dlundef.c new file mode 100644 index 000000000..cefd93318 --- /dev/null +++ b/test/dlopen/dlundef.c @@ -0,0 +1,29 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> + +#define LIBNAME "libundef.so" + +int main(int argc, char **argv) +{ + void *handle; + int (*myundefined)(void); + + handle = dlopen(LIBNAME, RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + return EXIT_FAILURE; + } + + myundefined = dlsym(handle, "__booga_booga_you_cant_touch_this__"); + if (myundefined != NULL) { + fprintf(stderr, "dlsym() found a symbol that does not exist!\n"); + return EXIT_FAILURE; + } + + dlclose(handle); + + return EXIT_SUCCESS; +} diff --git a/test/dlopen/libafk-temp.c b/test/dlopen/libafk-temp.c new file mode 100644 index 000000000..39b58df27 --- /dev/null +++ b/test/dlopen/libafk-temp.c @@ -0,0 +1 @@ +/* the actual contents doesnt matter */ diff --git a/test/dlopen/libafk.c b/test/dlopen/libafk.c new file mode 100644 index 000000000..39b58df27 --- /dev/null +++ b/test/dlopen/libafk.c @@ -0,0 +1 @@ +/* the actual contents doesnt matter */ diff --git a/test/dlopen/libstatic.c b/test/dlopen/libstatic.c new file mode 100644 index 000000000..bf44c3c68 --- /dev/null +++ b/test/dlopen/libstatic.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +static int global_static = -1; + +int static_test(void) +{ + static int local_static = -2; + + if (global_static != -1) + printf("FAIL: global_static is not -1\n"); + if (local_static != -2) + printf("FAIL: local_static is not -2\n"); + + return (global_static == -1 && local_static == -2); +} diff --git a/test/dlopen/libtest.c b/test/dlopen/libtest.c index e37f77981..a306e4bf7 100644 --- a/test/dlopen/libtest.c +++ b/test/dlopen/libtest.c @@ -4,6 +4,7 @@ extern int __pthread_once(void); +void dltest(uint32_t **value1, uint32_t **value2); void dltest(uint32_t **value1, uint32_t **value2) { *value1 = (uint32_t *) __pthread_once; diff --git a/test/dlopen/libtest1.c b/test/dlopen/libtest1.c index f0dc9f537..a2f7dcdc0 100644 --- a/test/dlopen/libtest1.c +++ b/test/dlopen/libtest1.c @@ -2,28 +2,31 @@ extern int libtest2_func(const char *s); - -void __attribute__((constructor)) libtest1_ctor(void) +void __attribute__((constructor)) libtest1_ctor(void); +void libtest1_ctor(void) { printf("libtest1: constructor!\n"); } -void __attribute__((destructor)) libtest1_dtor(void) +void __attribute__((destructor)) libtest1_dtor(void); +void libtest1_dtor(void) { printf("libtest1: destructor!\n"); } -void __attribute__((weak)) function1(void) +void __attribute__((weak)) function1(void); +void function1(void) { printf("libtest1: I am weak function1!\n"); } +void function2(void); void function2(void) { printf("libtest1: I am function2!\n"); } - +int dltest(const char *s); int dltest(const char *s) { printf( "libtest1: function1 = %p\n" diff --git a/test/dlopen/libtest2.c b/test/dlopen/libtest2.c index 529f8bb66..526150666 100644 --- a/test/dlopen/libtest2.c +++ b/test/dlopen/libtest2.c @@ -1,27 +1,32 @@ #include <stdio.h> #include <pthread.h> -void __attribute__((constructor)) libtest2_ctor(void) +void __attribute__((constructor)) libtest2_ctor(void); +void libtest2_ctor(void) { printf("libtest2: constructor!\n"); } -void __attribute__((destructor)) libtest2_dtor(void) +void __attribute__((destructor)) libtest2_dtor(void); +void libtest2_dtor(void) { printf("libtest2: destructor!\n"); } +void function1(void); void function1(void) { printf("libtest2: I am function1!\n"); } -void __attribute__((weak)) function2(void) +void __attribute__((weak)) function2(void); +void function2(void) { printf("libtest2: I am weak function2!\n"); } +int libtest2_func(const char *s); int libtest2_func(const char *s) { printf( "libtest2: function1 = %p\n" diff --git a/test/dlopen/libundef.c b/test/dlopen/libundef.c new file mode 100644 index 000000000..39b58df27 --- /dev/null +++ b/test/dlopen/libundef.c @@ -0,0 +1 @@ +/* the actual contents doesnt matter */ diff --git a/test/inet/gethost_r-align.c b/test/inet/gethost_r-align.c new file mode 100644 index 000000000..53ce93acd --- /dev/null +++ b/test/inet/gethost_r-align.c @@ -0,0 +1,50 @@ +/* Since the reentrant gethost functions take a char * buffer, + * we have to make sure they internally do not assume alignment. + * The actual return values are not relevant. If the test fails, + * it'll be due to an alignment exception which means the test + * app is killed by the kernel. + */ + +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +int main(int argc, char *argv[]) +{ + size_t i; + char buf[1024]; + in_addr_t addr; + + addr = inet_addr("127.0.0.1"); + + for (i = 0; i < sizeof(size_t) * 2; ++i) { + struct hostent hent, *hentres; + int ret, herr; + + printf("Testing misalignment of %2zi bytes: ", i); + + memset(&hent, 0x00, sizeof(hent)); + ret = gethostent_r(&hent, buf + i, sizeof(buf) - i, &hentres, &herr); + printf("%sgethostent_r() ", (ret ? "!!!" : "")); + + memset(&hent, 0x00, sizeof(hent)); + ret = gethostbyname_r("localhost", &hent, buf + i, sizeof(buf) - i, &hentres, &herr); + printf("%sgethostbyname_r() ", (ret ? "!!!" : "")); + + memset(&hent, 0x00, sizeof(hent)); + ret = gethostbyname2_r("localhost", AF_INET, &hent, buf + i, sizeof(buf) - i, &hentres, &herr); + printf("%sgethostbyname2_r() ", (ret ? "!!!" : "")); + + memset(&hent, 0x00, sizeof(hent)); + ret = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &hent, buf + i, sizeof(buf) - i, &hentres, &herr); + printf("%sgethostbyaddr_r() ", (ret ? "!!!" : "")); + + puts("OK!"); + } + + return 0; +} diff --git a/test/inet/if_nameindex.c b/test/inet/if_nameindex.c index 069d96d99..126c5bab4 100644 --- a/test/inet/if_nameindex.c +++ b/test/inet/if_nameindex.c @@ -11,7 +11,7 @@ static char ifname[IF_NAMESIZE]; -void test_if_nameindex(void) +static void test_if_nameindex(void) { size_t i; struct if_nameindex *ret; @@ -30,7 +30,7 @@ void test_if_nameindex(void) if_freenameindex(ret); } -void test_if_indextoname(void) +static void test_if_indextoname(void) { if (if_indextoname(1, ifname) == NULL) { perror("if_nameindex()"); @@ -40,7 +40,7 @@ void test_if_indextoname(void) printf("if_indextoname(1) = %s\n", ifname); } -void test_if_nametoindex(void) +static void test_if_nametoindex(void) { int ifindex = if_nametoindex(ifname); diff --git a/test/inet/tst-network.c b/test/inet/tst-network.c index 428388805..259863733 100644 --- a/test/inet/tst-network.c +++ b/test/inet/tst-network.c @@ -43,7 +43,38 @@ struct {"1.1410.", INADDR_NONE}, {"1.1410", INADDR_NONE}, {"141.76.1111", INADDR_NONE}, - {"141.76.1111.", INADDR_NONE} + {"141.76.1111.", INADDR_NONE}, + {"1.1.1.257", INADDR_NONE}, + /* Now some from BSD */ + {"0x12", 0x00000012}, + {"127.1", 0x00007f01}, + {"127.1.2.3", 0x7f010203}, + {"0x123456", INADDR_NONE}, + {"0x12.0x34", 0x00001234}, + {"0x12.0x345", INADDR_NONE}, + {"1.2.3.4.5", INADDR_NONE}, + {"1..3.4", INADDR_NONE}, + {".", INADDR_NONE}, + {"1.", INADDR_NONE}, + {".1", INADDR_NONE}, + {"x", INADDR_NONE}, + {"0x", INADDR_NONE}, + {"0", 0x00000000}, + {"0x0", 0x00000000}, + {"01.02.07.077", 0x0102073f}, + {"0x1.23.045.0", 0x01172500}, + {"", INADDR_NONE}, + {" ", INADDR_NONE}, + {"bar", INADDR_NONE}, + {"1.2bar", INADDR_NONE}, + {"1.", INADDR_NONE}, + {"ÊÃÕËÅÎ", INADDR_NONE}, + {"255.255.255.255", INADDR_NONE}, + {"x", INADDR_NONE}, + {"0X12", 0x00000012}, + {"078", INADDR_NONE}, + {"1 bar", INADDR_NONE}, + {"127.0xfff", INADDR_NONE}, }; @@ -61,6 +92,7 @@ main (void) if (res != tests[i].number) { + ++errors; printf ("Test failed for inet_network (\"%s\"):\n", tests[i].network); printf ("Expected return value %u (0x%x) but got %u (0x%x).\n", diff --git a/test/malloc/malloc-standard-alignment.c b/test/malloc/malloc-standard-alignment.c new file mode 100644 index 000000000..71e5023ae --- /dev/null +++ b/test/malloc/malloc-standard-alignment.c @@ -0,0 +1,42 @@ +/* exercise a bug found in malloc-standard when alignment + * values are out of whack and cause a small overflow into + * actual user data. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#define ok(p) ((void*)p > (void*)0x1000) +#define x \ + do { \ + printf("%i: phead = %p, phead->link @ %p = %p %s\n", \ + __LINE__, phead, \ + ok(phead) ? &phead->link : 0, \ + ok(phead) ? phead->link : 0, \ + ok(phead) ? phead->link == 0 ? "" : "!!!!!!!!!!!" : ""); \ + if (phead->link != NULL) exit(1); \ + } while (0); + +struct llist_s { + void *data; + struct llist_s *link; +} *phead; + +int main(int argc, char *argv[]) +{ + char *line, *reg; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + phead = malloc(sizeof(*phead)); + phead->link = NULL; + +x line = malloc(80); +x line = realloc(line, 2); +x reg = malloc(32); +x free(line); + +x return 0; +} diff --git a/test/malloc/realloc-can-shrink.c b/test/malloc/realloc-can-shrink.c new file mode 100644 index 000000000..33249db42 --- /dev/null +++ b/test/malloc/realloc-can-shrink.c @@ -0,0 +1,17 @@ +/* make sure that realloc() can properly shrink buffers */ + +#include <stdlib.h> + +#define LARGE_BUFFER (1 << 20) /* idea is to span a lot of pages */ + +int main(int argc, char *argv[]) +{ + int count = 20; + char *ptr = NULL; + while (count--) { + ptr = realloc(ptr, LARGE_BUFFER); + ptr = realloc(ptr, 1); + } + free(ptr); + return 0; +} diff --git a/test/math/libm-test.inc b/test/math/libm-test.inc index c0cb6be52..be6312930 100644 --- a/test/math/libm-test.inc +++ b/test/math/libm-test.inc @@ -310,7 +310,7 @@ fpstack_test (const char *test_name) static int old_stack; int sw; - asm ("fnstsw" : "=a" (sw)); + __asm__ ("fnstsw" : "=a" (sw)); sw >>= 11; sw &= 7; diff --git a/test/misc/bug-glob2.c b/test/misc/bug-glob2.c index 424ff4f48..9e8be983b 100644 --- a/test/misc/bug-glob2.c +++ b/test/misc/bug-glob2.c @@ -264,7 +264,7 @@ init_glob_altdirfuncs (glob_t *pglob) } -int +static int do_test (void) { glob_t gl; @@ -295,7 +295,7 @@ do_test (void) return 0; } #else -int do_test (void) { return 0; } +static int do_test (void) { return 0; } #endif #define TEST_FUNCTION do_test () diff --git a/test/misc/seek.c b/test/misc/seek.c index 919894501..c5edb94c9 100644 --- a/test/misc/seek.c +++ b/test/misc/seek.c @@ -23,6 +23,7 @@ int main(void) off_t ret; int i, fd; FILE *fp; + int tmp; fd = open("lseek.out", O_RDWR|O_CREAT, 0600); if (fd == -1) { @@ -44,11 +45,10 @@ int main(void) return 1; } - ret = fseeko(fp, 1024, SEEK_SET); - assert(ret == 0); - ret = fseeko(fp, (off_t)-16, SEEK_CUR); - assert(ret == 0); - + tmp = fseeko(fp, 1024, SEEK_SET); + assert(tmp == 0); + tmp = fseeko(fp, (off_t)-16, SEEK_CUR); + assert(tmp == 0); ret = ftell(fp); if (ret != (1024-16)) { fprintf(stderr, "ftell() failed, we wanted pos %i but got %li: ", (1024-16), (long)ret); diff --git a/test/misc/stdarg.c b/test/misc/stdarg.c index 561fd2c3b..1566e0ce8 100644 --- a/test/misc/stdarg.c +++ b/test/misc/stdarg.c @@ -5,7 +5,7 @@ #include <string.h> #include <sys/types.h> #include <stdarg.h> -int foo(const char *format, ...) +static int foo(const char *format, ...) { va_list ap; size_t len; diff --git a/test/misc/tst-seekdir.c b/test/misc/tst-seekdir.c index 5a2810abd..7dd5d2e85 100644 --- a/test/misc/tst-seekdir.c +++ b/test/misc/tst-seekdir.c @@ -13,8 +13,7 @@ main (int argc, char *argv[]) int i = 0; int result = 0; struct dirent *dp; - long int save0; - long int rewind; + off_t save0, rewind_ret; dirp = opendir ("."); if (dirp == NULL) @@ -63,13 +62,13 @@ main (int argc, char *argv[]) /* Check rewinddir */ rewinddir (dirp); - rewind = telldir (dirp); - if (rewind == -1) + rewind_ret = telldir (dirp); + if (rewind_ret == -1) { printf ("telldir failed: %s\n", strerror(errno)); result = 1; } - else if (save0 != rewind) + else if (save0 != rewind_ret) { printf ("rewinddir didn't reset directory stream\n"); result = 1; diff --git a/test/mmap/mmap2.c b/test/mmap/mmap2.c new file mode 100644 index 000000000..b9a8f9ac4 --- /dev/null +++ b/test/mmap/mmap2.c @@ -0,0 +1,41 @@ +/* When trying to map /dev/mem with offset 0xFFFFF000 on the ARM platform, mmap + * returns -EOVERFLOW. + * + * Since off_t is defined as a long int and the sign bit is set in the address, + * the shift operation shifts in ones instead of zeroes + * from the left. This results the offset sent to the kernel function becomes + * 0xFFFFFFFF instead of 0x000FFFFF with MMAP2_PAGE_SHIFT set to 12. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> + +#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ + __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0) + +#define MAP_SIZE 4096UL +#define MAP_MASK (MAP_SIZE - 1) + +int main(int argc, char **argv) { + void* map_base = 0; + int fd; + off_t target = 0xfffff000; + if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL; + printf("/dev/mem opened.\n"); + fflush(stdout); + + /* Map one page */ + map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, target & ~MAP_MASK); + if(map_base == (void *) -1) FATAL; + printf("Memory mapped at address %p.\n", map_base); + fflush(stdout); + if(munmap(map_base, MAP_SIZE) == -1) FATAL; + close(fd); + return 0; +} diff --git a/test/pthread/Makefile b/test/pthread/Makefile index 560a424cb..ef924ad1a 100644 --- a/test/pthread/Makefile +++ b/test/pthread/Makefile @@ -4,3 +4,5 @@ include ../Test.mak EXTRA_LDFLAGS := -lpthread + +LDFLAGS_cancellation-points := -lrt diff --git a/test/pthread/cancellation-points.c b/test/pthread/cancellation-points.c new file mode 100644 index 000000000..3fe49fcaa --- /dev/null +++ b/test/pthread/cancellation-points.c @@ -0,0 +1,280 @@ +/* + * Make sure functions marked as cancellation points actually are. + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html#tag_02_09_05 + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <features.h> +#include <sys/ipc.h> +#include <sys/mman.h> +#include <sys/msg.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <mqueue.h> +#include <poll.h> +#include <pthread.h> +#include <semaphore.h> +#include <signal.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <time.h> +#include <unistd.h> + +/* take care of optional things ... */ +#define STUB(func, args) static void func args { sleep(0); } +#if !defined(__UCLIBC__) || defined(__UCLIBC_AIO__) +# include <aio.h> +#else +STUB(aio_suspend, (void *p, int n, const void *p2)) +#endif +#if !defined(__UCLIBC__) || defined(__UCLIBC_STROPTS__) +# include <stropts.h> +#else +STUB(getmsg, (int f, void *p, void *p2, void *p3)) +STUB(getpmsg, (int f, void *p, void *p2, void *p3, void *p4)) +STUB(putmsg, (int f, void *p, void *p2, void *p3)) +STUB(putpmsg, (int f, void *p, void *p2, void *p3, void *p4)) +#endif +#if defined(__UCLIBC__) +STUB(clock_nanosleep, (int i, int f, const void *p, void *p2)) +#endif + +int cnt; +bool ready; + +void cancel_timeout(int sig) +{ + ready = false; +} +void cancel_thread_cleanup(void *arg) +{ + ready = false; +} + +/* some funcs need some help as they wont take NULL args ... */ +const struct timespec zero_sec = { .tv_sec = 0, .tv_nsec = 0 }; + +sem_t sem; +void help_sem_setup(void) +{ + if (sem_init(&sem, 0, 1) == -1) { + perror("sem_init() failed"); + exit(-1); + } +} + +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_mutex_t mutex; +void help_pthread_setup(void) +{ + pthread_mutex_init(&mutex, NULL); + pthread_mutex_lock(&mutex); +} + +/* the pthread function that will call the cancellable function over and over */ +#define _MAKE_CANCEL_THREAD_FUNC_EX(func, sysfunc, args, setup) \ +void *cancel_thread_##func(void *arg) \ +{ \ + if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { \ + perror("unable to set cancel type to deferred; something is seriously broken"); \ + exit(-1); \ + } \ + pthread_cleanup_push(cancel_thread_cleanup, NULL); \ + setup; \ + ready = true; \ + while (ready) \ + sysfunc args; \ + pthread_cleanup_pop(1); \ + return NULL; \ +} +#define MAKE_CANCEL_THREAD_FUNC_RE(func, sysfunc, args) _MAKE_CANCEL_THREAD_FUNC_EX(func, sysfunc, args, (void)0) +#define MAKE_CANCEL_THREAD_FUNC_EX(func, args, setup) _MAKE_CANCEL_THREAD_FUNC_EX(func, func, args, setup) +#define MAKE_CANCEL_THREAD_FUNC(func, args) _MAKE_CANCEL_THREAD_FUNC_EX(func, func, args, (void)0) + +MAKE_CANCEL_THREAD_FUNC(accept, (-1, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(aio_suspend, (NULL, 0, &zero_sec)) +MAKE_CANCEL_THREAD_FUNC(clock_nanosleep, (0, 0, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(close, (-1)) +MAKE_CANCEL_THREAD_FUNC(connect, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(creat, ("", 0)) +MAKE_CANCEL_THREAD_FUNC(fcntl, (0, F_SETLKW, NULL)) +MAKE_CANCEL_THREAD_FUNC(fdatasync, (-1)) +MAKE_CANCEL_THREAD_FUNC(fsync, (0)) +MAKE_CANCEL_THREAD_FUNC(getmsg, (-1, NULL, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(getpmsg, (-1, NULL, NULL, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(lockf, (-1, F_TEST, 0)) +MAKE_CANCEL_THREAD_FUNC(mq_receive, (0, NULL, 0, NULL)) +MAKE_CANCEL_THREAD_FUNC(mq_send, (0, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(mq_timedreceive, (0, NULL, 0, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(mq_timedsend, (0, NULL, 0, 0, NULL)) +MAKE_CANCEL_THREAD_FUNC(msgrcv, (-1, NULL, 0, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(msgsnd, (-1, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(msync, (NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(nanosleep, (NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(open, ("", 0)) +MAKE_CANCEL_THREAD_FUNC(pause, ()) +MAKE_CANCEL_THREAD_FUNC(poll, (NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(pread, (-1, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(pselect, (0, NULL, NULL, NULL, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC_EX(pthread_cond_timedwait, (&cond, &mutex, &zero_sec), help_pthread_setup()) +MAKE_CANCEL_THREAD_FUNC_EX(pthread_cond_wait, (&cond, &mutex), help_pthread_setup()) +/*MAKE_CANCEL_THREAD_FUNC_EX(pthread_join, (0, NULL))*/ +MAKE_CANCEL_THREAD_FUNC(pthread_testcancel, ()) +MAKE_CANCEL_THREAD_FUNC(putmsg, (-1, NULL, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(putpmsg, (-1, NULL, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(pwrite, (-1, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(read, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(readv, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(recv, (-1, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(recvfrom, (-1, NULL, 0, 0, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(recvmsg, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(select, (0, NULL, NULL, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC_EX(sem_timedwait, (&sem, &zero_sec), help_sem_setup()) +MAKE_CANCEL_THREAD_FUNC_EX(sem_wait, (&sem), help_sem_setup()) +MAKE_CANCEL_THREAD_FUNC(send, (-1, NULL, 0, 0)) +MAKE_CANCEL_THREAD_FUNC(sendmsg, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(sendto, (-1, NULL, 0, 0, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(sigpause, (0)) +MAKE_CANCEL_THREAD_FUNC(sigsuspend, (NULL)) +MAKE_CANCEL_THREAD_FUNC(sigtimedwait, (NULL, NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(sigwait, (NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(sigwaitinfo, (NULL, NULL)) +MAKE_CANCEL_THREAD_FUNC(sleep, (0)) +MAKE_CANCEL_THREAD_FUNC(system, ("")) +MAKE_CANCEL_THREAD_FUNC(tcdrain, (-1)) +MAKE_CANCEL_THREAD_FUNC(usleep, (0)) +MAKE_CANCEL_THREAD_FUNC(wait, (NULL)) +MAKE_CANCEL_THREAD_FUNC(waitid, (0, 0, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(waitpid, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(write, (-1, NULL, 0)) +MAKE_CANCEL_THREAD_FUNC(writev, (-1, NULL, 0)) + +/* test a few variations that should not cancel ... */ +MAKE_CANCEL_THREAD_FUNC_RE(fcntl_another, fcntl, (0, F_GETFD)) + +/* main test that creates thread, cancels it, etc... */ +int _test_func(const char *func_name, void *(*func)(void*), const int should_cancel) +{ + int ret; + pthread_t cancel_thread_id; + + ++cnt; + + printf("testing %-30s ", func_name); + + printf("."); + if (signal(SIGALRM, cancel_timeout) == SIG_ERR) { + perror("unable to bind SIGALRM"); + exit(-1); + } + + printf("."); + ready = false; + pthread_create(&cancel_thread_id, NULL, func, NULL); + + printf("."); + while (!ready) + sched_yield(); + + printf("."); + if (pthread_cancel(cancel_thread_id)) { + perror("unable to cancel thread"); + exit(-1); + } + + printf("."); + alarm(5); + while (ready) + sched_yield(); + + printf("."); + ret = (!!!alarm(0) == should_cancel); + + if (ret) + printf(" failed ;(\n"); + else + printf(" OK!\n"); + + return ret; +} +#define TEST_FUNC(f) _test_func(#f, cancel_thread_##f, 1) +#define TEST_FUNC_RE(f) _test_func(#f, cancel_thread_##f, 0) + +int main(int argc, char *argv[]) +{ + int ret = 0; + setbuf(stdout, NULL); + cnt = 0; + + ret += TEST_FUNC(accept); + ret += TEST_FUNC(aio_suspend); + ret += TEST_FUNC(clock_nanosleep); + ret += TEST_FUNC(close); + ret += TEST_FUNC(connect); + ret += TEST_FUNC(creat); + ret += TEST_FUNC(fcntl); + ret += TEST_FUNC(fdatasync); + ret += TEST_FUNC(fsync); + ret += TEST_FUNC(getmsg); + ret += TEST_FUNC(getpmsg); + ret += TEST_FUNC(lockf); + ret += TEST_FUNC(mq_receive); + ret += TEST_FUNC(mq_send); + ret += TEST_FUNC(mq_timedreceive); + ret += TEST_FUNC(mq_timedsend); + ret += TEST_FUNC(msgrcv); + ret += TEST_FUNC(msgsnd); + ret += TEST_FUNC(msync); + ret += TEST_FUNC(nanosleep); + ret += TEST_FUNC(open); + ret += TEST_FUNC(pause); + ret += TEST_FUNC(poll); + ret += TEST_FUNC(pread); + ret += TEST_FUNC(pselect); + ret += TEST_FUNC(pthread_cond_timedwait); + ret += TEST_FUNC(pthread_cond_wait); + /*ret += TEST_FUNC(pthread_join);*/ + ret += TEST_FUNC(pthread_testcancel); + ret += TEST_FUNC(putmsg); + ret += TEST_FUNC(putpmsg); + ret += TEST_FUNC(pwrite); + ret += TEST_FUNC(read); + ret += TEST_FUNC(readv); + ret += TEST_FUNC(recv); + ret += TEST_FUNC(recvfrom); + ret += TEST_FUNC(recvmsg); + ret += TEST_FUNC(select); + ret += TEST_FUNC(sem_timedwait); + ret += TEST_FUNC(sem_wait); + ret += TEST_FUNC(send); + ret += TEST_FUNC(sendmsg); + ret += TEST_FUNC(sendto); + ret += TEST_FUNC(sigpause); + ret += TEST_FUNC(sigsuspend); + ret += TEST_FUNC(sigtimedwait); + ret += TEST_FUNC(sigwait); + ret += TEST_FUNC(sigwaitinfo); + ret += TEST_FUNC(sleep); + ret += TEST_FUNC(system); + ret += TEST_FUNC(tcdrain); + ret += TEST_FUNC(usleep); + ret += TEST_FUNC(wait); + ret += TEST_FUNC(waitid); + ret += TEST_FUNC(waitpid); + ret += TEST_FUNC(write); + ret += TEST_FUNC(writev); + + ret += TEST_FUNC_RE(fcntl_another); + + if (ret) + printf("!!! %i / %i tests failed\n", ret, cnt); + + return ret; +} diff --git a/test/pthread/ex1.c b/test/pthread/ex1.c index a1b24c31a..4d9de03d8 100644 --- a/test/pthread/ex1.c +++ b/test/pthread/ex1.c @@ -7,7 +7,7 @@ #include <unistd.h> #include "pthread.h" -void *process(void * arg) +static void *process(void * arg) { int i; printf("Starting process %s\n", (char *)arg); diff --git a/test/pthread/ex2.c b/test/pthread/ex2.c index 70cb6b398..98bd4b347 100644 --- a/test/pthread/ex2.c +++ b/test/pthread/ex2.c @@ -20,7 +20,7 @@ struct prodcons { /* Initialize a buffer */ -void init(struct prodcons * b) +static void init(struct prodcons * b) { pthread_mutex_init(&b->lock, NULL); pthread_cond_init(&b->notempty, NULL); @@ -31,7 +31,7 @@ void init(struct prodcons * b) /* Store an integer in the buffer */ -void put(struct prodcons * b, int data) +static void put(struct prodcons * b, int data) { pthread_mutex_lock(&b->lock); /* Wait until buffer is not full */ @@ -50,7 +50,7 @@ void put(struct prodcons * b, int data) /* Read and remove an integer from the buffer */ -int get(struct prodcons * b) +static int get(struct prodcons * b) { int data; pthread_mutex_lock(&b->lock); @@ -75,7 +75,7 @@ int get(struct prodcons * b) struct prodcons buffer; -void * producer(void * data) +static void * producer(void * data) { int n; for (n = 0; n < 10000; n++) { @@ -86,7 +86,7 @@ void * producer(void * data) return NULL; } -void * consumer(void * data) +static void * consumer(void * data) { int d; while (1) { diff --git a/test/pthread/ex4.c b/test/pthread/ex4.c index 11a09f013..cf4cf1d69 100644 --- a/test/pthread/ex4.c +++ b/test/pthread/ex4.c @@ -14,7 +14,7 @@ #if 0 -char * str_accumulate(char * s) +static char * str_accumulate(char * s) { static char accu[1024] = { 0 }; strcat(accu, s); @@ -40,7 +40,7 @@ static void str_alloc_destroy_accu(void * accu); /* Thread-safe version of str_accumulate */ -char * str_accumulate(const char * s) +static char * str_accumulate(const char * s) { char * accu; @@ -81,7 +81,7 @@ static void str_alloc_destroy_accu(void * accu) /* Test program */ -void * process(void * arg) +static void * process(void * arg) { char * res; res = str_accumulate("Result of "); diff --git a/test/pthread/ex5.c b/test/pthread/ex5.c index 475de0e0c..7a293eb01 100644 --- a/test/pthread/ex5.c +++ b/test/pthread/ex5.c @@ -19,7 +19,7 @@ struct prodcons { /* Initialize a buffer */ -void init(struct prodcons * b) +static void init(struct prodcons * b) { sem_init(&b->sem_write, 0, BUFFER_SIZE - 1); sem_init(&b->sem_read, 0, 0); @@ -29,7 +29,7 @@ void init(struct prodcons * b) /* Store an integer in the buffer */ -void put(struct prodcons * b, int data) +static void put(struct prodcons * b, int data) { /* Wait until buffer is not full */ sem_wait(&b->sem_write); @@ -43,7 +43,7 @@ void put(struct prodcons * b, int data) /* Read and remove an integer from the buffer */ -int get(struct prodcons * b) +static int get(struct prodcons * b) { int data; /* Wait until buffer is not empty */ @@ -64,7 +64,7 @@ int get(struct prodcons * b) struct prodcons buffer; -void * producer(void * data) +static void * producer(void * data) { int n; for (n = 0; n < 10000; n++) { @@ -75,7 +75,7 @@ void * producer(void * data) return NULL; } -void * consumer(void * data) +static void * consumer(void * data) { int d; while (1) { diff --git a/test/pthread/ex6.c b/test/pthread/ex6.c index 15914ce85..bb96ca5fa 100644 --- a/test/pthread/ex6.c +++ b/test/pthread/ex6.c @@ -4,7 +4,7 @@ #include <pthread.h> #include <unistd.h> -void * +static void * test_thread (void *v_param) { return NULL; diff --git a/test/pthread/ex7.c b/test/pthread/ex7.c index bda2ca9eb..9cf30aa19 100644 --- a/test/pthread/ex7.c +++ b/test/pthread/ex7.c @@ -22,12 +22,12 @@ typedef struct { event_t main_event; -void * +static void * test_thread (void *ms_param) { unsigned long status = 0; event_t foo; - struct timespec time; + struct timespec timeout; struct timeval now; long ms = (long) ms_param; @@ -39,13 +39,13 @@ test_thread (void *ms_param) /* set the time out value */ printf("waiting %ld ms ...\n", ms); gettimeofday(&now, NULL); - time.tv_sec = now.tv_sec + ms/1000 + (now.tv_usec + (ms%1000)*1000)/1000000; - time.tv_nsec = ((now.tv_usec + (ms%1000)*1000) % 1000000) * 1000; + timeout.tv_sec = now.tv_sec + ms/1000 + (now.tv_usec + (ms%1000)*1000)/1000000; + timeout.tv_nsec = ((now.tv_usec + (ms%1000)*1000) % 1000000) * 1000; /* Just use this to test the time out. The cond var is never signaled. */ pthread_mutex_lock(&foo.mutex); while (foo.flag == 0 && status != ETIMEDOUT) { - status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time); + status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &timeout); } pthread_mutex_unlock(&foo.mutex); diff --git a/test/pthread/tst-too-many-cleanups.c b/test/pthread/tst-too-many-cleanups.c new file mode 100644 index 000000000..7828c5036 --- /dev/null +++ b/test/pthread/tst-too-many-cleanups.c @@ -0,0 +1,104 @@ +/* + * This illustrates the bug where the cleanup function + * of a thread may be called too many times. + * + * main thread: + * - grab mutex + * - spawn thread1 + * - go to sleep + * thread1: + * - register cleanup handler via pthread_cleanup_push() + * - try to grab mutex and sleep + * main: + * - kill thread1 + * - go to sleep + * thread1 cleanup handler: + * - try to grab mutex and sleep + * main: + * - kill thread1 + * - go to sleep + * thread1 cleanup handler: + * - wrongly called again + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <assert.h> +#include <unistd.h> + +#define warn(fmt, args...) fprintf(stderr, "[%p] " fmt, (void*)pthread_self(), ## args) +#define warnf(fmt, args...) warn("%s:%i: " fmt, __FUNCTION__, __LINE__, ## args) + +int ok_to_kill_thread; + +static void thread_killed(void *arg); + +static void *KillMeThread(void *thread_par) +{ + pthread_t pthread_id; + + warnf("Starting child thread\n"); + + pthread_id = pthread_self(); + pthread_cleanup_push(thread_killed, (void *)pthread_id); + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + /* main code */ + warnf("please kill me now\n"); + while (1) { + ok_to_kill_thread = 1; + sleep(1); + } + + pthread_cleanup_pop(0); + + return 0; +} + +static void thread_killed(void *arg) +{ + static int num_times_called = 0; + + warnf("killing %p [cnt=%i]\n", arg, ++num_times_called); + assert(num_times_called == 1); + + /* pick any cancellation endpoint, sleep() will do just fine */ + while (1) { + warnf("sleeping in cancellation endpoint ...\n"); + sleep(1); + } + + warnf("done cleaning up\n"); +} + +int main(int argc, char *argv[]) +{ + int count = 3; + pthread_t app_pthread_id; + + /* need to tweak this test a bit to play nice with signals and LT */ + return 0; + + ok_to_kill_thread = 0; + + pthread_create(&app_pthread_id, NULL, KillMeThread, NULL); + + warnf("waiting for thread to prepare itself\n"); + while (!ok_to_kill_thread) + sleep(1); + + while (count--) { + warnf("killing thread\n"); + pthread_cancel(app_pthread_id); + sleep(3); + } + + return 0; +} diff --git a/test/setjmp/bug269-setjmp.c b/test/setjmp/bug269-setjmp.c index f50a5b1a5..33431fa19 100644 --- a/test/setjmp/bug269-setjmp.c +++ b/test/setjmp/bug269-setjmp.c @@ -29,7 +29,7 @@ int n_x = 6; static int g_counter = 0; -int +static int f (void) { static int counter = 0; diff --git a/test/setjmp/jmpbug.c b/test/setjmp/jmpbug.c index 4337e527a..da087a724 100644 --- a/test/setjmp/jmpbug.c +++ b/test/setjmp/jmpbug.c @@ -7,6 +7,7 @@ int ret; int verbose; +__attribute__ ((__noreturn__)) static void sub5 (jmp_buf buf) { diff --git a/test/setjmp/sigjmpbug.c b/test/setjmp/sigjmpbug.c index 8c3be1cee..5b1718185 100644 --- a/test/setjmp/sigjmpbug.c +++ b/test/setjmp/sigjmpbug.c @@ -7,6 +7,7 @@ int ret; int verbose; +__attribute__ ((__noreturn__)) static void sub5 (jmp_buf buf) { diff --git a/test/setjmp/tst-setjmp.c b/test/setjmp/tst-setjmp.c index 35d9638ad..f0feb99a8 100644 --- a/test/setjmp/tst-setjmp.c +++ b/test/setjmp/tst-setjmp.c @@ -23,6 +23,7 @@ static jmp_buf env; static int last_value = -1, lose = 0; +__attribute__ ((__noreturn__)) static void jump (int val) { diff --git a/test/setjmp/tst-vfork-longjmp.c b/test/setjmp/tst-vfork-longjmp.c index c64e80559..278442472 100644 --- a/test/setjmp/tst-vfork-longjmp.c +++ b/test/setjmp/tst-vfork-longjmp.c @@ -16,7 +16,7 @@ int verbose = 0; -int execute_child(const char *prog) +static int execute_child(const char *prog) { int status; pid_t child; @@ -33,7 +33,7 @@ int execute_child(const char *prog) sigset_t orig_mask; -int check_sig_mask(void) +static int check_sig_mask(void) { int status; pid_t child; diff --git a/test/signal/sigchld.c b/test/signal/sigchld.c index 60ddf4b3c..22febaca7 100644 --- a/test/signal/sigchld.c +++ b/test/signal/sigchld.c @@ -7,31 +7,29 @@ #include <unistd.h> -void test_handler(int signo) +#ifdef __ARCH_USE_MMU__ + +static void test_handler(int signo) { write(1, "caught SIGCHLD\n", 15); return; } - -#ifdef __ARCH_USE_MMU__ - -int main(void) +int main(void) { pid_t mypid; struct sigaction siga; - static sigset_t sigset; + static sigset_t set; /* Set up sighandling */ - sigfillset(&sigset); + sigfillset(&set); siga.sa_handler = test_handler; - siga.sa_mask = sigset; + siga.sa_mask = set; siga.sa_flags = 0; if (sigaction(SIGCHLD, &siga, (struct sigaction *)NULL) != 0) { fprintf(stderr, "sigaction choked: %s!", strerror(errno)); exit(EXIT_FAILURE); } - /* Setup a child process to exercise the sig handling for us */ mypid = getpid(); @@ -52,7 +50,7 @@ int main(void) sleep(10); if (waitpid(-1, NULL, WNOHANG | WUNTRACED) > 0) break; - write(1, "after sleep\n", 12); + write(1, "after sleep\n", 12); } printf("Bye-bye! All done!\n"); diff --git a/test/signal/signal.c b/test/signal/signal.c index 6e6f04a7a..01d1a785f 100644 --- a/test/signal/signal.c +++ b/test/signal/signal.c @@ -24,7 +24,7 @@ const char *it = "<UNSET>"; /* Routine name for message routines. */ size_t errors = 0; -void check(int thing, int number) +static void check(int thing, int number) { if (!thing) { printf("%s: flunked test %d\n", it, number); @@ -32,10 +32,12 @@ void check(int thing, int number) } } -void equal(const char *a, const char *b, int number) +#if 0 +static void equal(const char *a, const char *b, int number) { check(a != NULL && b != NULL && (strcmp(a, b) == 0), number); } +#endif /* -------------------------------------------------*/ @@ -44,14 +46,14 @@ void equal(const char *a, const char *b, int number) int global_int = 0; -void set_global_int_to_one(int signum) +static void set_global_int_to_one(int signum) { printf ("Received signal %d (%s).\n", signum, strsignal(signum)); global_int = 1; return; } -void signal_test_1(void) +static void signal_test_1(void) { global_int = 0; diff --git a/test/signal/tst-raise.c b/test/signal/tst-raise.c index 9e8e472be..d24c316cf 100644 --- a/test/signal/tst-raise.c +++ b/test/signal/tst-raise.c @@ -26,7 +26,7 @@ volatile int count; -void +static void sh (int sig) { ++count; diff --git a/test/stat/memcmp-stat.c b/test/stat/memcmp-stat.c new file mode 100644 index 000000000..c38e3ff88 --- /dev/null +++ b/test/stat/memcmp-stat.c @@ -0,0 +1,107 @@ +/* Distilled from issue found with tar and symlinks. + * Make sure that the whole stat struct between runs + * is agreeable. + */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <assert.h> +#include <time.h> + +static void show_stat(struct stat *st) +{ + printf( + "------------------\n" + "st_dev = %li\n" + "st_ino = %li\n" + "st_mode = %li\n" + "st_nlink = %li\n" + "st_uid = %li\n" + "st_gid = %li\n" + "st_rdev = %li\n" + "st_size = %li\n" + "st_blksize = %li\n" + "st_blocks = %li\n" + "st_atime = %li\n" + "st_ansec = %li\n" + "st_mtime = %li\n" + "st_mnsec = %li\n" + "st_ctime = %li\n" + "st_cnsec = %li\n", + (long int)st->st_dev, + (long int)st->st_ino, + (long int)st->st_mode, + (long int)st->st_nlink, + (long int)st->st_uid, + (long int)st->st_gid, + (long int)st->st_rdev, + (long int)st->st_size, + (long int)st->st_blksize, + (long int)st->st_blocks, +#ifndef __UCLIBC__ + (long int)st->st_atime, + (long int)st->st_atim.tv_nsec, + (long int)st->st_mtime, + (long int)st->st_mtim.tv_nsec, + (long int)st->st_ctime, + (long int)st->st_ctim.tv_nsec +#else + (long int)st->st_atime, + (long int)st->st_atimensec, + (long int)st->st_mtime, + (long int)st->st_mtimensec, + (long int)st->st_ctime, + (long int)st->st_ctimensec +#endif + ); +} + +int main(void) +{ + int ret; + int fd; + struct stat fst, st; + + memset(&fst, 0xAA, sizeof(fst)); + memset(&st, 0x55, sizeof(st)); + + unlink(".testfile"); + fd = open(".testfile", O_WRONLY | O_CREAT | O_EXCL, 0); + if (fd < 0) { + perror("open(.testfile) failed"); + return 1; + } + ret = fstat(fd, &fst); + if (ret != 0) { + perror("fstat(.testfile) failed"); + return 1; + } + close(fd); + + ret = stat(".testfile", &st); + if (ret != 0) { + perror("stat(.testfile) failed"); + return 1; + } + + ret = memcmp(&fst, &st, sizeof(fst)); + if (ret != 0) { + printf("FAILED: memcmp() = %i\n", ret); + show_stat(&fst); + show_stat(&st); + } + + unlink(".testfile"); + + return ret; +} diff --git a/test/stat/stat.c b/test/stat/stat.c index c9e063f27..4980cdd78 100644 --- a/test/stat/stat.c +++ b/test/stat/stat.c @@ -5,7 +5,7 @@ #include <unistd.h> #include <stdlib.h> -void print_struct_stat(char *msg, struct stat *s) +static void print_struct_stat(char *msg, struct stat *s) { printf("%s\n", msg); /* The casts are because glibc thinks it's cool */ diff --git a/test/stdio/64bit.c b/test/stdio/64bit.c new file mode 100644 index 000000000..9b94dd86c --- /dev/null +++ b/test/stdio/64bit.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +int main(void) +{ + unsigned long long val = -1; + void *ptr = (void *)-1; + printf("%p\n", ptr); + + sscanf("123456789", "%Lx", &val); + printf("val = %Lx\n", val); + return 0; +} diff --git a/test/stdio/Makefile b/test/stdio/Makefile new file mode 100644 index 000000000..d3ae2f368 --- /dev/null +++ b/test/stdio/Makefile @@ -0,0 +1,6 @@ +# uClibc assert tests +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + +include ../Test.mak + +DODIFF_64bit := 1 diff --git a/test/stdio/fclose-loop.c b/test/stdio/fclose-loop.c new file mode 100644 index 000000000..fc0cc424a --- /dev/null +++ b/test/stdio/fclose-loop.c @@ -0,0 +1,21 @@ +/* From: Denis Vlasenko <vda.linux@googlemail.com> + * With certain combination of .config options fclose() does not + * remove FILE* pointer from _stdio_openlist. As a result, subsequent + * fopen() may allocate new FILE structure exactly in place of one + * freed by previous fclose(), which then makes _stdio_openlist + * circularlt looped. The following program will enter infinite loop + * trying to walk _stdio_openlist in exit(): + */ + +#include <stdlib.h> +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + FILE* fp; + fp = fopen("/dev/null", "r"); + fclose(fp); + fp = fopen("/dev/zero", "r"); + fclose(fp); + return 0; +} diff --git a/test/stdlib/qsort.c b/test/stdlib/qsort.c index 9e706c78d..abc505e2d 100644 --- a/test/stdlib/qsort.c +++ b/test/stdlib/qsort.c @@ -3,45 +3,43 @@ #include <stdlib.h> #include <unistd.h> -int select_files(const struct dirent *dirbuf) +static int select_files(const struct dirent *dirbuf) { - if (dirbuf->d_name[0] == '.') - return 0; - else - return 1; + if (dirbuf->d_name[0] == '.') + return 0; + else + return 1; } - int main(void) { - struct dirent **array; - struct dirent *dirbuf; + struct dirent **array; + struct dirent *dirbuf; - int i, numdir; + int i, numdir; - chdir("/"); - numdir = scandir(".", &array, select_files, NULL); - printf("\nGot %d entries from scandir().\n", numdir); - for (i = 0; i < numdir; ++i) { - dirbuf = array[i]; - printf("[%d] %s\n", i, dirbuf->d_name); - free(array[i]); - } - free(array); - numdir = scandir(".", &array, select_files, alphasort); - printf("\nGot %d entries from scandir() using alphasort().\n", numdir); - for (i = 0; i < numdir; ++i) { - dirbuf = array[i]; - printf("[%d] %s\n", i, dirbuf->d_name); - } - printf("\nCalling qsort()\n"); - qsort(array, numdir, sizeof(struct dirent *), alphasort); - for (i = 0; i < numdir; ++i) { - dirbuf = array[i]; - printf("[%d] %s\n", i, dirbuf->d_name); - free(array[i]); - } - free(array); - return(0); + chdir("/"); + numdir = scandir(".", &array, select_files, NULL); + printf("\nGot %d entries from scandir().\n", numdir); + for (i = 0; i < numdir; ++i) { + dirbuf = array[i]; + printf("[%d] %s\n", i, dirbuf->d_name); + free(array[i]); + } + free(array); + numdir = scandir(".", &array, select_files, alphasort); + printf("\nGot %d entries from scandir() using alphasort().\n", numdir); + for (i = 0; i < numdir; ++i) { + dirbuf = array[i]; + printf("[%d] %s\n", i, dirbuf->d_name); + } + printf("\nCalling qsort()\n"); + qsort(array, numdir, sizeof(struct dirent *), alphasort); + for (i = 0; i < numdir; ++i) { + dirbuf = array[i]; + printf("[%d] %s\n", i, dirbuf->d_name); + free(array[i]); + } + free(array); + return (0); } - diff --git a/test/stdlib/test-canon.c b/test/stdlib/test-canon.c new file mode 100644 index 000000000..dd2f9bce3 --- /dev/null +++ b/test/stdlib/test-canon.c @@ -0,0 +1,254 @@ +/* Test program for returning the canonical absolute name of a given file. + Copyright (C) 1996,1997,2000,2002,2004,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Mosberger <davidm@azstarnet.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file must be run from within a directory called "stdlib". */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +/* Prototype for our test function. */ +extern int do_test (int argc, char *argv[]); +#include <test-skeleton.c> + +#ifndef PATH_MAX +# define PATH_MAX 4096 +#endif +static char cwd[PATH_MAX]; +static size_t cwd_len; + +struct { + const char * name; + const char * value; +} symlinks[] = { + {"SYMLINK_LOOP", "SYMLINK_LOOP"}, + {"SYMLINK_1", "."}, + {"SYMLINK_2", "//////./../../etc"}, + {"SYMLINK_3", "SYMLINK_1"}, + {"SYMLINK_4", "SYMLINK_2"}, + {"SYMLINK_5", "doesNotExist"}, +}; + +struct { + const char * in, * out, * resolved; + int error; +} tests[] = { + /* 0 */ + {"/", "/"}, + {"/////////////////////////////////", "/"}, + {"/.././.././.././..///", "/"}, + {"/etc", "/etc"}, + {"/etc/../etc", "/etc"}, + /* 5 */ + {"/doesNotExist/../etc", 0, "/doesNotExist", ENOENT}, + {"./././././././././.", "."}, + {"/etc/.//doesNotExist", 0, "/etc/doesNotExist", ENOENT}, + {"./doesExist", "./doesExist"}, + {"./doesExist/", "./doesExist"}, + /* 10 */ + {"./doesExist/../doesExist", "./doesExist"}, + {"foobar", 0, "./foobar", ENOENT}, + {".", "."}, + {"./foobar", 0, "./foobar", ENOENT}, +#ifdef __UCLIBC__ + /* we differ from glibc here, but POSIX allows it as it says that if we did + * not successfuly complete, the value of resolved_path is undefined */ + {"SYMLINK_LOOP", 0, "", ELOOP}, + /* 15 */ + {"./SYMLINK_LOOP", 0, "", ELOOP}, +#else + {"SYMLINK_LOOP", 0, "./SYMLINK_LOOP", ELOOP}, + /* 15 */ + {"./SYMLINK_LOOP", 0, "./SYMLINK_LOOP", ELOOP}, +#endif + {"SYMLINK_1", "."}, + {"SYMLINK_1/foobar", 0, "./foobar", ENOENT}, + {"SYMLINK_2", "/etc"}, + {"SYMLINK_3", "."}, + /* 20 */ + {"SYMLINK_4", "/etc"}, + {"../stdlib/SYMLINK_1", "."}, + {"../stdlib/SYMLINK_2", "/etc"}, + {"../stdlib/SYMLINK_3", "."}, + {"../stdlib/SYMLINK_4", "/etc"}, + /* 25 */ + {"./SYMLINK_5", 0, "./doesNotExist", ENOENT}, + {"SYMLINK_5", 0, "./doesNotExist", ENOENT}, + {"SYMLINK_5/foobar", 0, "./doesNotExist", ENOENT}, + {"doesExist/../../stdlib/doesExist", "./doesExist"}, + {"doesExist/.././../stdlib/.", "."}, +#ifndef __UCLIBC__ + /* we dont check for ENOTDIR in readlink() which causes failures to + * propogate up to realpath() ... so disable for now ... */ + /* 30 */ + {"./doesExist/someFile/", 0, "./doesExist/someFile", ENOTDIR}, + {"./doesExist/someFile/..", 0, "./doesExist/someFile", ENOTDIR}, +#endif +}; + + +static int +check_path (const char * result, const char * expected) +{ + int good; + + if (!result) + return (expected == NULL); + + if (!expected) + return 0; + + if (expected[0] == '.' && (expected[1] == '/' || expected[1] == '\0')) + good = (strncmp (result, cwd, cwd_len) == 0 + && strcmp (result + cwd_len, expected + 1) == 0); + else + good = (strcmp (expected, result) == 0); + + return good; +} + + +int +do_test (int argc, char ** argv) +{ + char * result; + int i, errors = 0; + char buf[PATH_MAX]; + + getcwd (cwd, sizeof(buf)); + cwd_len = strlen (cwd); + +#ifndef __UCLIBC__ + /* we choose to crash in uClibc when given a NULL */ + errno = 0; + if (realpath (NULL, buf) != NULL || errno != EINVAL) + { + printf ("%s: expected return value NULL and errno set to EINVAL" + " for realpath(NULL,...)\n", argv[0]); + ++errors; + } +#endif + +#if 0 + /* This is now allowed. The test is invalid. */ + errno = 0; + if (realpath ("/", NULL) != NULL || errno != EINVAL) + { + printf ("%s: expected return value NULL and errno set to EINVAL" + " for realpath(...,NULL)\n", argv[0]); + ++errors; + } +#endif + + errno = 0; + if (realpath ("", buf) != NULL || errno != ENOENT) + { + printf ("%s: expected return value NULL and set errno to ENOENT" + " for realpath(\"\",...)\n", argv[0]); + ++errors; + } + + for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i) + symlink (symlinks[i].value, symlinks[i].name); + + int has_dir = mkdir ("doesExist", 0777) == 0; + + int fd = has_dir ? creat ("doesExist/someFile", 0777) : -1; + + for (i = 0; i < (int) (sizeof (tests) / sizeof (tests[0])); ++i) + { + buf[0] = '\0'; + result = realpath (tests[i].in, buf); + + if (!check_path (result, tests[i].out)) + { + printf ("%s: flunked test %d (expected `%s', got `%s')\n", + argv[0], i, tests[i].out ? tests[i].out : "NULL", + result ? result : "NULL"); + ++errors; + continue; + } + + if (!check_path (buf, tests[i].out ? tests[i].out : tests[i].resolved)) + { + printf ("%s: flunked test %d (expected resolved `%s', got `%s')\n", + argv[0], i, tests[i].out ? tests[i].out : tests[i].resolved, + buf); + ++errors; + continue; + } + + if (!tests[i].out && errno != tests[i].error) + { + printf ("%s: flunked test %d (expected errno %d, got %d)\n", + argv[0], i, tests[i].error, errno); + ++errors; + continue; + } + +#ifndef __UCLIBC__ + /* we choose to crash in uClibc when given a NULL */ + char *result2 = realpath (tests[i].in, NULL); + if ((result2 == NULL && result != NULL) + || (result2 != NULL && strcmp (result, result2) != 0)) + { + printf ("\ +%s: realpath(..., NULL) produced different result than realpath(..., buf): '%s' vs '%s'\n", + argv[0], result2, result); + ++errors; + } + free (result2); +#endif + } + + getcwd (buf, sizeof(buf)); + if (strcmp (buf, cwd)) + { + printf ("%s: current working directory changed from %s to %s\n", + argv[0], cwd, buf); + ++errors; + } + + if (fd >= 0) + { + close (fd); + unlink ("doesExist/someFile"); + } + + if (has_dir) + rmdir ("doesExist"); + + for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i) + unlink (symlinks[i].name); + + if (errors != 0) + { + printf ("%d errors.\n", errors); + return EXIT_FAILURE; + } + + puts ("No errors."); + return EXIT_SUCCESS; +} diff --git a/test/stdlib/testatexit.c b/test/stdlib/testatexit.c index 3d4856df3..01874fdde 100644 --- a/test/stdlib/testatexit.c +++ b/test/stdlib/testatexit.c @@ -13,31 +13,38 @@ typedef void (*vfuncp) (void); /* All functions call exit(), in order to test that exit functions can call * exit() without screwing everything up. :) */ -static void exitfunc0(void) { printf("Executing exitfunc0.\n"); exit(0);} -static void exitfunc1(void) { printf("Executing exitfunc1.\n"); exit(0);} -static void exitfunc2(void) { printf("Executing exitfunc2.\n"); exit(0);} -static void exitfunc3(void) { printf("Executing exitfunc3.\n"); exit(0);} -static void exitfunc4(void) { printf("Executing exitfunc4.\n"); exit(0);} -static void exitfunc5(void) { printf("Executing exitfunc5.\n"); exit(0);} -static void exitfunc6(void) { printf("Executing exitfunc6.\n"); exit(0);} -static void exitfunc7(void) { printf("Executing exitfunc7.\n"); exit(0);} -static void exitfunc8(void) { printf("Executing exitfunc8.\n"); exit(0);} -static void exitfunc9(void) { printf("Executing exitfunc9.\n"); exit(0);} -static void exitfunc10(void) { printf("Executing exitfunc10.\n"); exit(0);} -static void exitfunc11(void) { printf("Executing exitfunc11.\n"); exit(0);} -static void exitfunc12(void) { printf("Executing exitfunc12.\n"); exit(0);} -static void exitfunc13(void) { printf("Executing exitfunc13.\n"); exit(0);} -static void exitfunc14(void) { printf("Executing exitfunc14.\n"); exit(0);} -static void exitfunc15(void) { printf("Executing exitfunc15.\n"); exit(0);} -static void exitfunc16(void) { printf("Executing exitfunc16.\n"); exit(0);} -static void exitfunc17(void) { printf("Executing exitfunc17.\n"); exit(0);} -static void exitfunc18(void) { printf("Executing exitfunc18.\n"); exit(0);} -static void exitfunc19(void) { printf("Executing exitfunc19.\n"); exit(0);} -static void exitfunc20(void) { printf("Executing exitfunc20.\n"); exit(0);} -static void exitfunc21(void) { printf("Executing exitfunc21.\n"); exit(0);} -static void exitfunc22(void) { printf("Executing exitfunc22.\n"); exit(0);} -static void exitfunc23(void) { printf("Executing exitfunc23.\n"); exit(0);} -static void exitfunc24(void) { printf("Executing exitfunc24.\n"); exit(0);} +#define make_exitfunc(num) \ +__attribute__ ((__noreturn__)) static \ +void exitfunc##num(void) \ +{ \ + printf("Executing exitfunc"#num".\n"); \ + exit(0); \ +} +make_exitfunc(0) +make_exitfunc(1) +make_exitfunc(2) +make_exitfunc(3) +make_exitfunc(4) +make_exitfunc(5) +make_exitfunc(6) +make_exitfunc(7) +make_exitfunc(8) +make_exitfunc(9) +make_exitfunc(10) +make_exitfunc(11) +make_exitfunc(12) +make_exitfunc(13) +make_exitfunc(14) +make_exitfunc(15) +make_exitfunc(16) +make_exitfunc(17) +make_exitfunc(18) +make_exitfunc(19) +make_exitfunc(20) +make_exitfunc(21) +make_exitfunc(22) +make_exitfunc(23) +make_exitfunc(24) static vfuncp func_table[] = { @@ -72,4 +79,3 @@ main ( void ) return 0; } - diff --git a/test/stdlib/teston_exit.c b/test/stdlib/teston_exit.c index c5789b083..f7e8fd004 100644 --- a/test/stdlib/teston_exit.c +++ b/test/stdlib/teston_exit.c @@ -14,31 +14,38 @@ typedef void (*efuncp) (int, void *); * exit() without screwing everything up. The value passed in through arg gets * used as the next exit status. */ -static void exitfunc0(int status, void *arg) { printf("Executing exitfunc0 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc1(int status, void *arg) { printf("Executing exitfunc1 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc2(int status, void *arg) { printf("Executing exitfunc2 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc3(int status, void *arg) { printf("Executing exitfunc3 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc4(int status, void *arg) { printf("Executing exitfunc4 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc5(int status, void *arg) { printf("Executing exitfunc5 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc6(int status, void *arg) { printf("Executing exitfunc6 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc7(int status, void *arg) { printf("Executing exitfunc7 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc8(int status, void *arg) { printf("Executing exitfunc8 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc9(int status, void *arg) { printf("Executing exitfunc9 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc10(int status, void *arg) { printf("Executing exitfunc10 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc11(int status, void *arg) { printf("Executing exitfunc11 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc12(int status, void *arg) { printf("Executing exitfunc12 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc13(int status, void *arg) { printf("Executing exitfunc13 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc14(int status, void *arg) { printf("Executing exitfunc14 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc15(int status, void *arg) { printf("Executing exitfunc15 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc16(int status, void *arg) { printf("Executing exitfunc16 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc17(int status, void *arg) { printf("Executing exitfunc17 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc18(int status, void *arg) { printf("Executing exitfunc18 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc19(int status, void *arg) { printf("Executing exitfunc19 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc20(int status, void *arg) { printf("Executing exitfunc20 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc21(int status, void *arg) { printf("Executing exitfunc21 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc22(int status, void *arg) { printf("Executing exitfunc22 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc23(int status, void *arg) { printf("Executing exitfunc23 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} -static void exitfunc24(int status, void *arg) { printf("Executing exitfunc24 (status=%d, arg=%lu)\n", status, (unsigned long)arg); exit((unsigned long)arg);} +#define make_exitfunc(num) \ +__attribute__ ((__noreturn__)) static \ +void exitfunc##num(int status, void *arg) \ +{ \ + printf("Executing exitfunc"#num" (status=%d, arg=%lu)\n", status, (unsigned long)arg); \ + exit((unsigned long)arg); \ +} +make_exitfunc(0) +make_exitfunc(1) +make_exitfunc(2) +make_exitfunc(3) +make_exitfunc(4) +make_exitfunc(5) +make_exitfunc(6) +make_exitfunc(7) +make_exitfunc(8) +make_exitfunc(9) +make_exitfunc(10) +make_exitfunc(11) +make_exitfunc(12) +make_exitfunc(13) +make_exitfunc(14) +make_exitfunc(15) +make_exitfunc(16) +make_exitfunc(17) +make_exitfunc(18) +make_exitfunc(19) +make_exitfunc(20) +make_exitfunc(21) +make_exitfunc(22) +make_exitfunc(23) +make_exitfunc(24) static efuncp func_table[] = { diff --git a/test/string/tester.c b/test/string/tester.c index 60caddf99..647b8c174 100644 --- a/test/string/tester.c +++ b/test/string/tester.c @@ -1,5 +1,5 @@ /* Tester for string functions. - Copyright (C) 1995-2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1995-2001, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,6 +34,18 @@ #include <strings.h> #include <fcntl.h> +#ifdef __UCLIBC__ +# define __TEST_BSD_FUNCS__ +#else +# undef __TEST_BSD_FUNCS__ +#endif + +#if defined(__UCLIBC_SUSV3_LEGACY__) || defined(__UCLIBC_SUSV3_LEGACY_MACROS__) +# define __TEST_SUSV3_LEGACY__ +#else +# undef __TEST_SUSV3_LEGACY__ +#endif + #define STREQ(a, b) (strcmp((a), (b)) == 0) const char *it = "<UNSET>"; /* Routine name for message routines. */ @@ -84,8 +96,8 @@ test_strcmp (void) int k; for (k = 0; k < 0x3f; k++) { - buf1[j] = '0' ^ (k & 4); - buf2[j] = '4' ^ (k & 4); + buf1[k] = '0' ^ (k & 4); + buf2[k] = '4' ^ (k & 4); } buf1[i] = buf1[0x3f] = 0; buf2[j] = buf2[0x3f] = 0; @@ -168,6 +180,12 @@ test_strcpy (void) SIMPLE_COPY(strcpy, 14, "44444444444444", 55); SIMPLE_COPY(strcpy, 15, "555555555555555", 56); SIMPLE_COPY(strcpy, 16, "6666666666666666", 57); + + /* Simple test using implicitly coerced `void *' arguments. */ + const void *src = "frobozz"; + void *dst = one; + check (strcpy (dst, src) == dst, 1); + equal (dst, "frobozz", 2); } static void @@ -343,6 +361,53 @@ test_strncat (void) } static void +test_strlcat (void) +{ +#ifdef __TEST_BSD_FUNCS__ + /* First test it as strcat, with big counts, then test the count + mechanism. */ + it = "strlcat"; + (void) strcpy (one, "ijk"); + check (strlcat (one, "lmn", 99) == 6, 1); /* Returned value. */ + equal (one, "ijklmn", 2); /* Basic test. */ + + (void) strcpy (one, "x"); + (void) strlcat (one, "yz", 99); + equal (one, "xyz", 3); /* Writeover. */ + equal (one+4, "mn", 4); /* Wrote too much? */ + + (void) strcpy (one, "gh"); + (void) strcpy (two, "ef"); + (void) strlcat (one, two, 99); + equal (one, "ghef", 5); /* Basic test encore. */ + equal (two, "ef", 6); /* Stomped on source? */ + + (void) strcpy (one, ""); + (void) strlcat (one, "", 99); + equal (one, "", 7); /* Boundary conditions. */ + (void) strcpy (one, "ab"); + (void) strlcat (one, "", 99); + equal (one, "ab", 8); + (void) strcpy (one, ""); + (void) strlcat (one, "cd", 99); + equal (one, "cd", 9); + + (void) strcpy (one, "ab"); + (void) strlcat (one, "cdef", 2); + equal (one, "ab", 10); /* Count-limited. */ + + (void) strlcat (one, "gh", 0); + equal (one, "ab", 11); /* Zero count. */ + + (void) strlcat (one, "gh", 4); + equal (one, "abg", 12); /* Count and length equal. */ + + (void) strlcat (one, "ij", (size_t)-1); /* set sign bit in count */ + equal (one, "abgij", 13); +#endif +} + +static void test_strncmp (void) { /* First test as strcmp with big counts, then test count code. */ @@ -360,7 +425,7 @@ test_strncmp (void) check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */ check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */ check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */ - check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */ + check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */ check (strncmp ("abc", "abc", (size_t)-2) == 0, 15); } @@ -407,6 +472,50 @@ test_strncpy (void) } static void +test_strlcpy (void) +{ +#ifdef __TEST_BSD_FUNCS__ + /* Testing is a bit different because of odd semantics. */ + it = "strlcpy"; + check (strlcpy (one, "abc", sizeof(one)) == 3, 1); /* Returned value. */ + equal (one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy (one, "abcdefgh"); + (void) strlcpy (one, "xyz", 2); + equal (one, "x\0cdefgh", 3); /* Copy cut by count. */ + + (void) strcpy (one, "abcdefgh"); + (void) strlcpy (one, "xyz", 3); /* Copy cut just before NUL. */ + equal (one, "xy\0defgh", 4); + + (void) strcpy (one, "abcdefgh"); + (void) strlcpy (one, "xyz", 4); /* Copy just includes NUL. */ + equal (one, "xyz", 5); + equal (one+4, "efgh", 6); /* Wrote too much? */ + + (void) strcpy (one, "abcdefgh"); + (void) strlcpy (one, "xyz", 5); /* Copy includes padding. */ + equal (one, "xyz", 7); + equal (one+3, "", 8); + equal (one+4, "efgh", 9); + + (void) strcpy (one, "abc"); + (void) strlcpy (one, "xyz", 0); /* Zero-length copy. */ + equal (one, "abc", 10); + + (void) strlcpy (one, "", 2); /* Zero-length source. */ + equal (one, "", 11); + equal (one+1, "bc", 12); + equal (one+2, "c", 13); + + (void) strcpy (one, "hi there"); + (void) strlcpy (two, one, 9); + equal (two, "hi there", 14); /* Just paranoia. */ + equal (one, "hi there", 15); /* Stomped on source? */ +#endif +} + +static void test_strlen (void) { it = "strlen"; @@ -433,7 +542,7 @@ test_strnlen (void) it = "strnlen"; check (strnlen ("", 10) == 0, 1); /* Empty. */ check (strnlen ("a", 10) == 1, 2); /* Single char. */ - check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */ + check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */ check (strnlen ("foo", (size_t)-1) == 3, 4); /* limits of n. */ { @@ -543,6 +652,7 @@ test_rawmemchr (void) static void test_index (void) { +#ifdef __TEST_SUSV3_LEGACY__ it = "index"; check (index ("abcd", 'z') == NULL, 1); /* Not found. */ (void) strcpy (one, "abcd"); @@ -555,6 +665,7 @@ test_index (void) (void) strcpy (one, ""); check (index (one, 'b') == NULL, 7); /* Empty string. */ check (index (one, '\0') == one, 8); /* NUL in empty string. */ +#endif } static void @@ -635,6 +746,7 @@ test_memrchr (void) static void test_rindex (void) { +#ifdef __TEST_SUSV3_LEGACY__ it = "rindex"; check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */ (void) strcpy (one, "abcd"); @@ -647,6 +759,7 @@ test_rindex (void) (void) strcpy (one, ""); check (rindex (one, 'b') == NULL, 7); /* Empty string. */ check (rindex (one, '\0') == one, 8); /* NUL in empty string. */ +#endif } static void @@ -974,15 +1087,31 @@ test_strsep (void) static void test_memcmp (void) { + int i, cnt = 1; + char one[21], two[21]; + it = "memcmp"; - check(memcmp("a", "a", 1) == 0, 1); /* Identity. */ - check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ - check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */ - check(memcmp("abce", "abcd", 4) > 0, 4); - check(memcmp("alph", "beta", 4) < 0, 5); - check(memcmp("a\203", "a\003", 2) > 0, 6); - check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */ - check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */ + check(memcmp("a", "a", 1) == 0, cnt++); /* Identity. */ + check(memcmp("abc", "abc", 3) == 0, cnt++); /* Multicharacter. */ + check(memcmp("abcd", "abcf", 4) < 0, cnt++); /* Honestly unequal. */ + check(memcmp("abcf", "abcd", 4) > 0, cnt++); + check(memcmp("alph", "cold", 4) < 0, cnt++); + check(memcmp("a\203", "a\003", 2) > 0, cnt++); + check(memcmp("a\003", "a\203", 2) < 0, cnt++); + check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt++); + check(memcmp("abc\203", "abc\003", 4) > 0, cnt++); + check(memcmp("abc\003", "abc\203", 4) < 0, cnt++); + check(memcmp("abcf", "abcd", 3) == 0, cnt++); /* Count limited. */ + check(memcmp("abc", "def", 0) == 0, cnt++); /* Zero count. */ + /* Comparisons with shifting 4-byte boundaries. */ + for (i=0; i<4; i++) + { + char *a = one + i, *b = two + i; + strncpy( a, "--------11112222", 16); + strncpy( b, "--------33334444", 16); + check( memcmp(b, a, 16) > 0, cnt++); + check( memcmp(a, b, 16) < 0, cnt++); + } } static void @@ -1243,6 +1372,7 @@ test_memset (void) static void test_bcopy (void) { +#ifdef __TEST_SUSV3_LEGACY__ /* Much like memcpy. Berklix manual is silent about overlap, so don't test it. */ it = "bcopy"; @@ -1262,11 +1392,13 @@ test_bcopy (void) (void) bcopy(one, two, 9); equal(two, "hi there", 4); /* Just paranoia. */ equal(one, "hi there", 5); /* Stomped on source? */ +#endif } static void test_bzero (void) { +#ifdef __TEST_SUSV3_LEGACY__ it = "bzero"; (void) strcpy(one, "abcdef"); bzero(one+2, 2); @@ -1277,6 +1409,7 @@ test_bzero (void) (void) strcpy(one, "abcdef"); bzero(one+2, 0); equal(one, "abcdef", 4); /* Zero-length copy. */ +#endif } static void @@ -1306,6 +1439,7 @@ test_strndup (void) static void test_bcmp (void) { +#ifdef __TEST_SUSV3_LEGACY__ it = "bcmp"; check(bcmp("a", "a", 1) == 0, 1); /* Identity. */ check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ @@ -1314,6 +1448,7 @@ test_bcmp (void) check(bcmp("alph", "beta", 4) != 0, 5); check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */ check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */ +#endif } static void @@ -1325,6 +1460,52 @@ test_strerror (void) check(strerror(ENOENT) != 0, 3); } +static void +test_strcasecmp (void) +{ + it = "strcasecmp"; + /* Note that the locale is "C". */ + check(strcasecmp("a", "a") == 0, 1); + check(strcasecmp("a", "A") == 0, 2); + check(strcasecmp("A", "a") == 0, 3); + check(strcasecmp("a", "b") < 0, 4); + check(strcasecmp("c", "b") > 0, 5); + check(strcasecmp("abc", "AbC") == 0, 6); + check(strcasecmp("0123456789", "0123456789") == 0, 7); + check(strcasecmp("", "0123456789") < 0, 8); + check(strcasecmp("AbC", "") > 0, 9); + check(strcasecmp("AbC", "A") > 0, 10); + check(strcasecmp("AbC", "Ab") > 0, 11); + check(strcasecmp("AbC", "ab") > 0, 12); +} + +static void +test_strncasecmp (void) +{ + it = "strncasecmp"; + /* Note that the locale is "C". */ + check(strncasecmp("a", "a", 5) == 0, 1); + check(strncasecmp("a", "A", 5) == 0, 2); + check(strncasecmp("A", "a", 5) == 0, 3); + check(strncasecmp("a", "b", 5) < 0, 4); + check(strncasecmp("c", "b", 5) > 0, 5); + check(strncasecmp("abc", "AbC", 5) == 0, 6); + check(strncasecmp("0123456789", "0123456789", 10) == 0, 7); + check(strncasecmp("", "0123456789", 10) < 0, 8); + check(strncasecmp("AbC", "", 5) > 0, 9); + check(strncasecmp("AbC", "A", 5) > 0, 10); + check(strncasecmp("AbC", "Ab", 5) > 0, 11); + check(strncasecmp("AbC", "ab", 5) > 0, 12); + check(strncasecmp("0123456789", "AbC", 0) == 0, 13); + check(strncasecmp("AbC", "abc", 1) == 0, 14); + check(strncasecmp("AbC", "abc", 2) == 0, 15); + check(strncasecmp("AbC", "abc", 3) == 0, 16); + check(strncasecmp("AbC", "abcd", 3) == 0, 17); + check(strncasecmp("AbC", "abcd", 4) < 0, 18); + check(strncasecmp("ADC", "abcd", 1) == 0, 19); + check(strncasecmp("ADC", "abcd", 2) > 0, 20); +} + int main (void) { @@ -1348,12 +1529,18 @@ main (void) /* strncat. */ test_strncat (); + /* strlcat. */ + test_strlcat (); + /* strncmp. */ test_strncmp (); /* strncpy. */ test_strncpy (); + /* strlcpy. */ + test_strlcpy (); + /* strlen. */ test_strlen (); @@ -1438,6 +1625,11 @@ main (void) /* strerror - VERY system-dependent. */ test_strerror (); + /* strcasecmp. Without locale dependencies. */ + test_strcasecmp (); + + /* strncasecmp. Without locale dependencies. */ + test_strncasecmp (); if (errors == 0) { @@ -1447,7 +1639,7 @@ main (void) else { status = EXIT_FAILURE; - printf("%lu errors.\n", (unsigned long)errors); + printf("%Zd errors.\n", errors); } return status; diff --git a/test/testsuite.h b/test/testsuite.h index c45876831..afc45b0c0 100644 --- a/test/testsuite.h +++ b/test/testsuite.h @@ -10,15 +10,15 @@ #define TESTSUITE_H #ifdef __NO_TESTCODE__ - extern size_t test_number; +#endif extern void init_testsuite(const char* testname); extern void done_testing(void) __attribute__((noreturn)); extern void success_msg(int result, const char* command); extern void error_msg(int result, int line, const char* file, const char* command); -#else +#ifndef __NO_TESTCODE__ size_t test_number = 0; static int failures = 0; diff --git a/test/time/clocktest.c b/test/time/clocktest.c index f2b3ea73a..a5b2c09e7 100644 --- a/test/time/clocktest.c +++ b/test/time/clocktest.c @@ -7,7 +7,7 @@ volatile int gotit = 0; static void -alarm_handler (int signal) +alarm_handler (int signum) { gotit = 1; } diff --git a/test/time/test_time.c b/test/time/test_time.c index 20216ed9d..2ce819a3f 100644 --- a/test/time/test_time.c +++ b/test/time/test_time.c @@ -37,15 +37,15 @@ main (int argc, char **argv) char buf[BUFSIZ]; if (argc > 0) { - static char buf[BUFSIZ]; - sprintf(buf, "TZ=%s", *argv); - if (putenv(buf)) + static char tzenvbuf[BUFSIZ]; + sprintf(tzenvbuf, "TZ=%s", *argv); + if (putenv(tzenvbuf)) { puts("putenv failed."); lose = 1; } else - puts (buf); + puts (tzenvbuf); } tzset(); tbuf.tm_year = 72; diff --git a/test/time/tst-ftime_l.c b/test/time/tst-ftime_l.c index 3786f8c09..95017f1f8 100644 --- a/test/time/tst-ftime_l.c +++ b/test/time/tst-ftime_l.c @@ -3,7 +3,7 @@ #include <string.h> #include <time.h> #include <features.h> -#if defined __UCLIBC_HAS_WCHAR__ && defined __UCLIBC_HAS_LOCALE__ +#ifdef __UCLIBC_HAS_XLOCALE__ #include <locale.h> #include <wchar.h> diff --git a/test/unistd/clone.c b/test/unistd/clone.c index bc08c94bf..ea7e6ac64 100644 --- a/test/unistd/clone.c +++ b/test/unistd/clone.c @@ -19,12 +19,12 @@ #define GOT3 (1 << 3) #define ALLGOT (GOT1|GOT2|GOT3) -void child_handler(int sig) +static void child_handler(int sig) { printf("I got a SIGCHLD\n"); } -int clone_main(void *arg) +static int clone_main(void *arg) { unsigned long input = (unsigned long)arg; int secs = (input / 10) * 4; diff --git a/test/unistd/errno.c b/test/unistd/errno.c index c77f58aa2..5fdb3b347 100644 --- a/test/unistd/errno.c +++ b/test/unistd/errno.c @@ -6,7 +6,8 @@ #include <sched.h> #include "clone_cruft.h" -int child_fn(void *arg) +__attribute__ ((__noreturn__)) +static int child_fn(void *arg) { fprintf(stderr, "in child_fn\n"); exit(1); diff --git a/test/unistd/fork.c b/test/unistd/fork.c index b163c0ef9..6d132d6d8 100644 --- a/test/unistd/fork.c +++ b/test/unistd/fork.c @@ -18,7 +18,7 @@ #ifdef __ARCH_USE_MMU__ -void child_handler(int sig) +static void child_handler(int sig) { fprintf(stderr, "I got a SIGCHLD\n"); } |
