summaryrefslogtreecommitdiff
path: root/test/unistd
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-24 20:22:12 +0200
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-24 20:22:12 +0200
commit7988979a722b4cdf287b2093956a76a3f19b9897 (patch)
treed35e251d0472ceca55a2eef61cff261c8ee68fab /test/unistd
add uClibc-ng test directory
Diffstat (limited to 'test/unistd')
-rw-r--r--test/unistd/Makefile8
-rw-r--r--test/unistd/Makefile.in44
-rw-r--r--test/unistd/clone.c101
-rw-r--r--test/unistd/clone_cruft.h24
-rw-r--r--test/unistd/errno.c29
-rw-r--r--test/unistd/exec-null.c13
-rw-r--r--test/unistd/fork.c91
-rw-r--r--test/unistd/getcwd.c39
-rw-r--r--test/unistd/getopt.c69
-rw-r--r--test/unistd/getopt_long.c93
-rw-r--r--test/unistd/tst-fallocate.c166
-rw-r--r--test/unistd/tst-fallocate64.c2
-rwxr-xr-xtest/unistd/tst-getconf.sh240
-rw-r--r--test/unistd/tst-posix_fallocate.c127
-rw-r--r--test/unistd/tst-posix_fallocate64.c2
-rw-r--r--test/unistd/tst-preadwrite.c104
-rw-r--r--test/unistd/tst-preadwrite64.c23
-rw-r--r--test/unistd/tst-pselect.c51
-rw-r--r--test/unistd/tstgetopt.c76
-rw-r--r--test/unistd/vfork.c53
20 files changed, 1355 insertions, 0 deletions
diff --git a/test/unistd/Makefile b/test/unistd/Makefile
new file mode 100644
index 0000000..796d7cc
--- /dev/null
+++ b/test/unistd/Makefile
@@ -0,0 +1,8 @@
+# uClibc unistd tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+top_builddir=../../
+top_srcdir=../../
+include ../Rules.mak
+-include Makefile.in
+include ../Test.mak
diff --git a/test/unistd/Makefile.in b/test/unistd/Makefile.in
new file mode 100644
index 0000000..5b65c13
--- /dev/null
+++ b/test/unistd/Makefile.in
@@ -0,0 +1,44 @@
+# uClibc unistd tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+TESTS_DISABLED :=
+# If LFS is not set, get rid of all *64 tests up front
+ifeq ($(UCLIBC_HAS_LFS),)
+TESTS_DISABLED += tst-preadwrite64
+endif
+
+# If we don't have LINUX_SPECIFIC, then get rid of tst-fallocate
+ifeq ($(UCLIBC_LINUX_SPECIFIC),)
+TESTS_DISABLED += tst-fallocate
+endif
+
+ifeq ($(TARGET_avr32),y)
+TESTS_DISABLED += tst-fallocate tst-posix_fallocate tst-fallocate64
+endif
+
+# The logic is similar for HAS_ADVANCED_REALTIME and
+# tst-posix_fallocate/tst-posix_fallocate64
+ifeq ($(UCLIBC_HAS_ADVANCED_REALTIME),)
+TESTS_DISABLED += tst-posix_fallocate
+endif
+
+OPTS_getopt := -abcXXX -9
+OPTS_getopt_long := --add XXX --delete YYY --verbose
+ifeq ($(UCLIBC_HAS_GNU_GETOPT),y)
+OPTS_tstgetopt := -a -b -cfoobar --required foobar --optional=bazbug --none random --col --color --colour
+else
+# reordering is not supported, behaves as if POSIXLY_CORRECT would be set
+OPTS_tstgetopt := -a -b -cfoobar --required foobar --optional=bazbug --none --colou --color --colour random
+endif
+
+# for embedded systems 4 GB disk space is not available
+TESTS_DISABLED += tst-posix_fallocate64 tst-fallocate64
+
+# getconf.c lives in utils/
+# Testsuite cannot currently be built with O= anyway, so hardcode path here
+getconf.c:
+ $(LN_S) ../../utils/$(@F) .
+EXTRA_CLEAN += getconf.c
+TESTS_DISABLED += getconf
+CFLAGS_getconf = -DGETCONF_DIR='"$(CURDIR)"'
+shell_tst-getconf: getconf getconf_glibc
diff --git a/test/unistd/clone.c b/test/unistd/clone.c
new file mode 100644
index 0000000..ea7e6ac
--- /dev/null
+++ b/test/unistd/clone.c
@@ -0,0 +1,101 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * clone test for uClibc
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sched.h>
+#include <sys/wait.h>
+#include "clone_cruft.h"
+
+#define GOT1 (1 << 1)
+#define GOT2 (1 << 2)
+#define GOT3 (1 << 3)
+#define ALLGOT (GOT1|GOT2|GOT3)
+
+static void child_handler(int sig)
+{
+ printf("I got a SIGCHLD\n");
+}
+
+static int clone_main(void *arg)
+{
+ unsigned long input = (unsigned long)arg;
+ int secs = (input / 10) * 4;
+ printf("Clone got %lu, sleeping for %i secs\n", input, secs);
+ sleep(secs);
+ return input + 20;
+}
+
+int main(void)
+{
+ int clone1, clone2, clone3;
+ char clone1_stack[8192], clone2_stack[8192], clone3_stack[8192];
+ int status, nostatus, result, wpid;
+
+ signal(SIGCHLD, child_handler);
+
+ if ((clone1 = do_clone(clone_main, clone1_stack, 0, (void*)11)) == -1) {
+ perror("Clone 1 failed");
+ exit(-1);
+ }
+ if ((clone2 = do_clone(clone_main, clone2_stack, 0, (void*)22)) == -1) {
+ perror("Clone 2 failed");
+ exit(-2);
+ }
+ if ((clone3 = do_clone(clone_main, clone3_stack, 0, (void*)33)) == -1) {
+ perror("Clone 3 failed");
+ exit(-3);
+ }
+
+ sleep(1);
+ printf("Parent: waiting for the clones to die.\n");
+ nostatus = status = 0;
+ while (1) {
+ if ((wpid = waitpid(clone1, &result, WNOHANG|__WCLONE)) == -1)
+ nostatus |= GOT1;
+ if (wpid == clone1) {
+ status |= GOT1;
+ printf("Clone1 gave back %i\n", WEXITSTATUS(result));
+ }
+
+ if ((wpid = waitpid(clone2, &result, WNOHANG|__WCLONE)) == -1)
+ nostatus |= GOT2;
+ if (wpid == clone2) {
+ status |= GOT2;
+ printf("Clone2 gave back %i\n", WEXITSTATUS(result));
+ }
+
+ if ((wpid = waitpid(clone3, &result, WNOHANG|__WCLONE)) == -1)
+ nostatus |= GOT3;
+ if (wpid == clone3) {
+ status |= GOT3;
+ printf("Clone3 gave back %i\n", WEXITSTATUS(result));
+ }
+
+ if (status == ALLGOT || nostatus == ALLGOT)
+ break;
+ }
+
+ if (status == ALLGOT) {
+ printf("Clones exited.\nGoodbye.\n");
+ return EXIT_SUCCESS;
+ } else {
+ perror("Waiting for clones failed");
+ return EXIT_FAILURE;
+ }
+}
+
+/*
+Local Variables:
+c-file-style: "linux"
+c-basic-offset: 4
+tab-width: 4
+End:
+*/
diff --git a/test/unistd/clone_cruft.h b/test/unistd/clone_cruft.h
new file mode 100644
index 0000000..b6a395d
--- /dev/null
+++ b/test/unistd/clone_cruft.h
@@ -0,0 +1,24 @@
+/* because people like to make things difficult */
+
+#undef do_clone
+
+#define crappy_sizeof(s) (s == NULL ? 0 : sizeof(s))
+
+#if defined __ia64__
+
+extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base,
+ size_t __child_stack_size, int __flags, void *__arg, ...);
+# define do_clone(fn, stack, flags, arg) \
+ __clone2(fn, stack, crappy_sizeof(stack), flags, arg, NULL, NULL, NULL)
+
+#elif defined __hppa__
+
+# define do_clone(fn, stack, flags, arg) \
+ clone(fn, stack, flags, arg)
+
+#else
+
+# define do_clone(fn, stack, flags, arg) \
+ clone(fn, stack+crappy_sizeof(stack), flags, arg)
+
+#endif
diff --git a/test/unistd/errno.c b/test/unistd/errno.c
new file mode 100644
index 0000000..5d4fc72
--- /dev/null
+++ b/test/unistd/errno.c
@@ -0,0 +1,29 @@
+/* based originally on one the clone tests in the LTP */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sched.h>
+#include "clone_cruft.h"
+
+__attribute__ ((__noreturn__))
+static int child_fn(void *arg)
+{
+ fprintf(stderr, "in child_fn\n");
+ exit(1);
+}
+
+int main(void)
+{
+ int r_clone, ret_errno;
+
+ r_clone = do_clone(child_fn, NULL, 0, NULL);
+ ret_errno = errno;
+ if (ret_errno != EINVAL || r_clone != -1) {
+ fprintf(stderr, "clone: res=%d (wanted -1) errno=%d (wanted %d)\n",
+ r_clone, errno, EINVAL);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/test/unistd/exec-null.c b/test/unistd/exec-null.c
new file mode 100644
index 0000000..3df99f3
--- /dev/null
+++ b/test/unistd/exec-null.c
@@ -0,0 +1,13 @@
+/* make sure we handle argv[0] == NULL */
+
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ if (argc == 0)
+ return 0;
+
+ char *exec_argv[1], *exec_envp[1];
+ exec_argv[0] = exec_envp[0] = NULL;
+ return execve("./exec-null", exec_argv, exec_envp);
+}
diff --git a/test/unistd/fork.c b/test/unistd/fork.c
new file mode 100644
index 0000000..6d132d6
--- /dev/null
+++ b/test/unistd/fork.c
@@ -0,0 +1,91 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * fork test for uClibc
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#define GOT1 (1 << 1)
+#define GOT2 (1 << 2)
+#define GOT3 (1 << 3)
+
+#ifdef __ARCH_USE_MMU__
+
+static void child_handler(int sig)
+{
+ fprintf(stderr, "I got a SIGCHLD\n");
+}
+
+int main(void)
+{
+ pid_t pid1, pid2, pid3;
+ int status, result, wpid;
+
+ signal(SIGCHLD, child_handler);
+
+ if ((pid1 = fork()) == 0) {
+ fprintf(stderr, "The child process sleeps 2 seconds...\n");
+ sleep(4);
+ fprintf(stderr, "Child exiting.\n");
+ exit(-1);
+ }
+ if ((pid2 = fork()) == 0) {
+ fprintf(stderr, "The child process sleeps 3 seconds...\n");
+ sleep(3);
+ fprintf(stderr, "Child exiting.\n");
+ exit(-1);
+ }
+ if ((pid3 = fork()) == 0) {
+ fprintf(stderr, "The child process sleeps 4 seconds...\n");
+ sleep(2);
+ fprintf(stderr, "Child exiting.\n");
+ exit(-1);
+ }
+
+ fprintf(stderr, "Parent: waiting for the child to die.\n");
+ status = 0;
+ while (1) {
+ wpid = waitpid(pid1, &result, WNOHANG);
+ if (wpid == pid1)
+ status |= GOT1;
+
+ wpid = waitpid(pid2, &result, WNOHANG);
+ if (wpid == pid2)
+ status |= GOT2;
+
+ wpid = waitpid(pid3, &result, WNOHANG);
+ if (wpid == pid3)
+ status |= GOT3;
+
+ if (status == (GOT1 | GOT2 | GOT3))
+ break;
+ }
+
+ fprintf(stderr, "Child process exited.\nGoodbye.\n");
+ return EXIT_SUCCESS;
+}
+
+#else
+
+int main(void)
+{
+ printf("Skipping test on non-mmu host!\n");
+ return EXIT_SUCCESS;
+}
+
+#endif
+
+/*
+Local Variables:
+c-file-style: "linux"
+c-basic-offset: 4
+tab-width: 4
+End:
+*/
diff --git a/test/unistd/getcwd.c b/test/unistd/getcwd.c
new file mode 100644
index 0000000..bcecec7
--- /dev/null
+++ b/test/unistd/getcwd.c
@@ -0,0 +1,39 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * fork test for uClibc
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(void)
+{
+ char *foo;
+ char junk[12];
+ char crap[100];
+ foo = getcwd(NULL, 0);
+ printf("getcwd(NULL, 0)='%s'\n", foo);
+ if (foo) { free(foo); }
+ foo = getcwd(NULL, 100);
+ printf("\ngetcwd(NULL, 100)='%s'\n", foo);
+ if (foo) { free(foo); }
+ foo = getcwd(junk, sizeof(junk));
+ printf("\nchar junk[12];\n");
+ printf("getcwd(junk, sizeof(junk))='%s'\n", foo);
+ foo = getcwd(crap, sizeof(crap));
+ printf("\nchar crap[100];\n");
+ printf("getcwd(crap, sizeof(crap))='%s'\n", foo);
+ return EXIT_SUCCESS;
+}
+
+/*
+Local Variables:
+c-file-style: "linux"
+c-basic-offset: 4
+tab-width: 4
+End:
+*/
diff --git a/test/unistd/getopt.c b/test/unistd/getopt.c
new file mode 100644
index 0000000..401765c
--- /dev/null
+++ b/test/unistd/getopt.c
@@ -0,0 +1,69 @@
+/* Getopt tests */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+
+int main (int argc, char **argv)
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == EOF)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+ exit (0);
+}
+
diff --git a/test/unistd/getopt_long.c b/test/unistd/getopt_long.c
new file mode 100644
index 0000000..4064e22
--- /dev/null
+++ b/test/unistd/getopt_long.c
@@ -0,0 +1,93 @@
+/* Getopt tests */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+
+int main (int argc, char **argv)
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == EOF)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
diff --git a/test/unistd/tst-fallocate.c b/test/unistd/tst-fallocate.c
new file mode 100644
index 0000000..fc81781
--- /dev/null
+++ b/test/unistd/tst-fallocate.c
@@ -0,0 +1,166 @@
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifndef TST_FALLOCATE64
+# define stat64 stat
+# define fstat64 fstat
+# else
+# ifndef O_LARGEFILE
+# error no O_LARGEFILE but you want to test with LFS enabled
+# endif
+#endif
+
+static void do_prepare(void);
+static int do_test(void);
+#define PREPARE(argc, argv) do_prepare ()
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
+
+static int fd;
+static void
+do_prepare (void)
+{
+ fd = create_temp_file ("tst-fallocate.", NULL);
+ if (fd == -1)
+ {
+ printf ("cannot create temporary file: %m\n");
+ exit (1);
+ }
+}
+
+
+static int
+do_test (void)
+{
+ struct stat64 st;
+ int c;
+ char garbage[4096];
+ blkcnt_t blksb4;
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("1st fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 0)
+ {
+ puts ("file not created with size 0");
+ return 1;
+ }
+
+ /* This is the default mode which is identical to posix_fallocate().
+ Note: we need a few extra blocks for FALLOC_FL_PUNCH_HOLE below.
+ While block sizes vary, we'll assume eight 4K blocks for good measure. */
+ if (fallocate (fd, 0, 8 * 4096, 128) != 0)
+ {
+ puts ("1st fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("2nd fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 8 * 4096 + 128)
+ {
+ printf ("file size after 1st fallocate call is %llu, expected %u\n",
+ (unsigned long long int) st.st_size, 8u * 4096u + 128u);
+ return 1;
+ }
+
+ /* Without FALLOC_FL_KEEP_SIZE, this would increaste the size of the file. */
+ if (fallocate (fd, FALLOC_FL_KEEP_SIZE, 0, 16 * 4096) != 0)
+ {
+ puts ("2nd fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("3rd fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 8 * 4096 + 128)
+ {
+ printf ("file size changed in 2nd fallocate call to %llu, expected %u\n",
+ (unsigned long long int) st.st_size, 8u * 4096u + 128u);
+ return 1;
+ }
+
+ /* Let's fill up the first eight 4k blocks with 'x' to force some allocations. */
+
+ memset(garbage, 'x', 4096);
+ for(c=0; c < 8; c++)
+ if(write(fd, garbage, 4096) == -1)
+ {
+ puts ("write failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("4th fstat failed");
+ return 1;
+ }
+
+ blksb4 = st.st_blocks;
+
+ /* Let's punch a hole in the entire file, turning it effectively into a sparse file. */
+ if (fallocate (fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 8 * 4096 + 128) != 0)
+ {
+ puts ("3rd fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("5th fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 8 * 4096 + 128)
+ {
+ printf ("file size after 3rd fallocate call is %llu, expected %u\n",
+ (unsigned long long int) st.st_size, 8u * 4096u + 128u);
+ return 1;
+ }
+
+ /* The number of allocated blocks should decrease. I hope this works on
+ all filesystems! */
+ if (st.st_blocks >= blksb4)
+ {
+ printf ("number of blocks after 3rd fallocate call is %lu, expected less than %lu\n",
+ (unsigned long int) st.st_blocks, blksb4);
+ return 1;
+ }
+
+#ifdef TST_FALLOCATE64
+ /* We'll just do a mode = 0 test for fallocate64() */
+ if (fallocate64 (fd, 0, 4097ULL, 4294967295ULL + 2ULL) != 0)
+ {
+ puts ("1st fallocate64 call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("6th fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 4097ULL + 4294967295ULL + 2ULL)
+ {
+ printf ("file size after 1st fallocate64 call is %llu, expected %llu\n",
+ (unsigned long long int) st.st_size, 4097ULL + 4294967295ULL + 2ULL);
+ return 1;
+ }
+#endif
+ close (fd);
+
+ return 0;
+}
+
diff --git a/test/unistd/tst-fallocate64.c b/test/unistd/tst-fallocate64.c
new file mode 100644
index 0000000..720428f
--- /dev/null
+++ b/test/unistd/tst-fallocate64.c
@@ -0,0 +1,2 @@
+#define TST_FALLOCATE64
+#include "tst-fallocate.c"
diff --git a/test/unistd/tst-getconf.sh b/test/unistd/tst-getconf.sh
new file mode 100755
index 0000000..3a2aa4e
--- /dev/null
+++ b/test/unistd/tst-getconf.sh
@@ -0,0 +1,240 @@
+#! /bin/sh
+
+basedir="."
+
+# make sure to use the same locale everywhere.
+LC_ALL=C
+export LC_ALL
+LANG=C
+export LANG
+
+for suffix in _glibc ''
+do
+binary=$basedir/getconf$suffix
+logfile=$basedir/tst-getconf$suffix.out
+rm -f $logfile
+
+result=0
+while read name; do
+ case "$name" in
+ "#"*) continue;;
+ esac
+ echo -n "getconf $name: " >> $logfile
+ $binary "$name" 2>> $logfile >> $logfile
+ if test $? -ne 0; then
+ echo "*** $name FAILED" >> $logfile
+ result=1
+ fi
+done <<EOF
+AIO_LISTIO_MAX
+AIO_MAX
+AIO_PRIO_DELTA_MAX
+ARG_MAX
+ATEXIT_MAX
+BC_BASE_MAX
+BC_DIM_MAX
+BC_SCALE_MAX
+BC_STRING_MAX
+CHILD_MAX
+COLL_WEIGHTS_MAX
+DELAYTIMER_MAX
+EXPR_NEST_MAX
+HOST_NAME_MAX
+IOV_MAX
+LINE_MAX
+LOGIN_NAME_MAX
+NGROUPS_MAX
+MQ_OPEN_MAX
+MQ_PRIO_MAX
+OPEN_MAX
+_POSIX_ADVISORY_INFO
+_POSIX_BARRIERS
+_POSIX_ASYNCHRONOUS_IO
+_POSIX_BASE
+_POSIX_C_LANG_SUPPORT
+_POSIX_C_LANG_SUPPORT_R
+_POSIX_CLOCK_SELECTION
+_POSIX_CPUTIME
+_POSIX_DEVICE_IO
+_POSIX_DEVICE_SPECIFIC
+_POSIX_DEVICE_SPECIFIC_R
+_POSIX_FD_MGMT
+_POSIX_FIFO
+_POSIX_FILE_ATTRIBUTES
+_POSIX_FILE_LOCKING
+_POSIX_FILE_SYSTEM
+_POSIX_FSYNC
+_POSIX_JOB_CONTROL
+_POSIX_MAPPED_FILES
+_POSIX_MEMLOCK
+_POSIX_MEMLOCK_RANGE
+_POSIX_MEMORY_PROTECTION
+_POSIX_MESSAGE_PASSING
+_POSIX_MONOTONIC_CLOCK
+_POSIX_MULTI_PROCESS
+_POSIX_NETWORKING
+_POSIX_PIPE
+_POSIX_PRIORITIZED_IO
+_POSIX_PRIORITY_SCHEDULING
+_POSIX_READER_WRITER_LOCKS
+_POSIX_REALTIME_SIGNALS
+_POSIX_REGEXP
+_POSIX_SAVED_IDS
+_POSIX_SEMAPHORES
+_POSIX_SHARED_MEMORY_OBJECTS
+_POSIX_SHELL
+_POSIX_SIGNALS
+_POSIX_SINGLE_PROCESS
+_POSIX_SPAWN
+_POSIX_SPIN_LOCKS
+_POSIX_SPORADIC_SERVER
+_POSIX_SYNCHRONIZED_IO
+_POSIX_SYSTEM_DATABASE
+_POSIX_SYSTEM_DATABASE_R
+_POSIX_THREAD_ATTR_STACKADDR
+_POSIX_THREAD_ATTR_STACKSIZE
+_POSIX_THREAD_CPUTIME
+_POSIX_THREAD_PRIO_INHERIT
+_POSIX_THREAD_PRIO_PROTECT
+_POSIX_THREAD_PRIORITY_SCHEDULING
+_POSIX_THREAD_PROCESS_SHARED
+_POSIX_THREAD_SAFE_FUNCTIONS
+_POSIX_THREAD_SPORADIC_SERVER
+_POSIX_THREADS
+_POSIX_TIMEOUTS
+_POSIX_TIMERS
+_POSIX_TRACE
+_POSIX_TRACE_EVENT_FILTER
+_POSIX_TRACE_INHERIT
+_POSIX_TRACE_LOG
+_POSIX_TYPED_MEMORY_OBJECTS
+_POSIX_USER_GROUPS
+_POSIX_USER_GROUPS_R
+_POSIX_VERSION
+_POSIX_V7_ILP32_OFF32
+_POSIX_V7_ILP32_OFFBIG
+_POSIX_V7_LP64_OFF64
+_POSIX_V7_LPBIG_OFFBIG
+#_POSIX_V7_WIDTH_RESTRICTED_ENVS
+POSIX2_C_BIND
+POSIX2_C_DEV
+POSIX2_C_VERSION
+POSIX2_CHAR_TERM
+POSIX2_FORT_DEV
+POSIX2_FORT_RUN
+POSIX2_LOCALEDEF
+POSIX2_PBS
+POSIX2_PBS_ACCOUNTING
+POSIX2_PBS_LOCATE
+POSIX2_PBS_MESSAGE
+POSIX2_PBS_TRACK
+POSIX2_SW_DEV
+POSIX2_UPE
+POSIX2_VERSION
+_REGEX_VERSION
+PAGE_SIZE
+PAGESIZE
+PTHREAD_DESTRUCTOR_ITERATIONS
+PTHREAD_KEYS_MAX
+PTHREAD_STACK_MIN
+PTHREAD_THREADS_MAX
+RE_DUP_MAX
+RTSIG_MAX
+SEM_NSEMS_MAX
+SEM_VALUE_MAX
+SIGQUEUE_MAX
+STREAM_MAX
+SYMLOOP_MAX
+TIMER_MAX
+TTY_NAME_MAX
+TZNAME_MAX
+#_XBS5_ILP32_OFF32
+#_XBS5_ILP32_OFFBIG
+#_XBS5_LP64_OFF64
+#_XBS5_LPBIG_OFFBIG
+_XOPEN_CRYPT
+_XOPEN_ENH_I18N
+_XOPEN_LEGACY
+_XOPEN_REALTIME
+_XOPEN_REALTIME_THREADS
+_XOPEN_SHM
+_XOPEN_UNIX
+_XOPEN_VERSION
+_XOPEN_XCU_VERSION
+PATH
+#POSIX_V7_ILP32_OFF32_CFLAGS
+#POSIX_V7_ILP32_OFF32_LDFLAGS
+#POSIX_V7_ILP32_OFF32_LIBS
+#POSIX_V7_ILP32_OFF32_LINTFLAGS
+#POSIX_V7_ILP32_OFFBIG_CFLAGS
+#POSIX_V7_ILP32_OFFBIG_LDFLAGS
+#POSIX_V7_ILP32_OFFBIG_LIBS
+#POSIX_V7_ILP32_OFFBIG_LINTFLAGS
+#POSIX_V7_LP64_OFF64_CFLAGS
+#POSIX_V7_LP64_OFF64_LDFLAGS
+#POSIX_V7_LP64_OFF64_LIBS
+#POSIX_V7_LP64_OFF64_LINTFLAGS
+#POSIX_V7_LPBIG_OFFBIG_CFLAGS
+#POSIX_V7_LPBIG_OFFBIG_LDFLAGS
+#POSIX_V7_LPBIG_OFFBIG_LIBS
+#POSIX_V7_LPBIG_OFFBIG_LINTFLAGS
+#XBS5_ILP32_OFF32_CFLAGS
+#XBS5_ILP32_OFF32_LDFLAGS
+#XBS5_ILP32_OFF32_LIBS
+#XBS5_ILP32_OFF32_LINTFLAGS
+#XBS5_ILP32_OFFBIG_CFLAGS
+#XBS5_ILP32_OFFBIG_LDFLAGS
+#XBS5_ILP32_OFFBIG_LIBS
+#XBS5_ILP32_OFFBIG_LINTFLAGS
+#XBS5_LP64_OFF64_CFLAGS
+#XBS5_LP64_OFF64_LDFLAGS
+#XBS5_LP64_OFF64_LIBS
+#XBS5_LP64_OFF64_LINTFLAGS
+#XBS5_LPBIG_OFFBIG_CFLAGS
+#XBS5_LPBIG_OFFBIG_LDFLAGS
+#XBS5_LPBIG_OFFBIG_LIBS
+#XBS5_LPBIG_OFFBIG_LINTFLAGS
+_NPROCESSORS_ONLN
+_NPROCESSORS_CONF
+EOF
+
+while read name; do
+ echo -n "getconf $name /: " >> $logfile
+ $binary "$name" / 2>> $logfile >> $logfile
+ if test $? -ne 0; then
+ echo "*** $name FAILED" >> $logfile
+ result=1
+ fi
+done <<EOF
+FILESIZEBITS
+LINK_MAX
+MAX_CANON
+MAX_INPUT
+NAME_MAX
+PATH_MAX
+PIPE_BUF
+POSIX_ALLOC_SIZE_MIN
+POSIX_REC_INCR_XFER_SIZE
+POSIX_REC_MAX_XFER_SIZE
+POSIX_REC_MIN_XFER_SIZE
+POSIX_REC_XFER_ALIGN
+SYMLINK_MAX
+_POSIX_CHOWN_RESTRICTED
+_POSIX_NO_TRUNC
+_POSIX_VDISABLE
+_POSIX_ASYNC_IO
+_POSIX_PRIO_IO
+_POSIX_SYNC_IO
+EOF
+
+done
+exit $result
+
+# Preserve executable bits for this shell script.
+Local Variables:
+eval:(defun frobme () (set-file-modes buffer-file-name file-mode))
+eval:(make-local-variable 'file-mode)
+eval:(setq file-mode (file-modes (buffer-file-name)))
+eval:(make-local-variable 'after-save-hook)
+eval:(add-hook 'after-save-hook 'frobme)
+End:
diff --git a/test/unistd/tst-posix_fallocate.c b/test/unistd/tst-posix_fallocate.c
new file mode 100644
index 0000000..d41c604
--- /dev/null
+++ b/test/unistd/tst-posix_fallocate.c
@@ -0,0 +1,127 @@
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifndef TST_POSIX_FALLOCATE64
+# define stat64 stat
+# define fstat64 fstat
+# else
+# ifndef O_LARGEFILE
+# error no O_LARGEFILE but you want to test with LFS enabled
+# endif
+#endif
+
+static void do_prepare (void);
+#define PREPARE(argc, argv) do_prepare ()
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
+
+static int fd;
+static void
+do_prepare (void)
+{
+ fd = create_temp_file ("tst-posix_fallocate.", NULL);
+ if (fd == -1)
+ {
+ printf ("cannot create temporary file: %m\n");
+ exit (1);
+ }
+}
+
+
+static int
+do_test (void)
+{
+ struct stat64 st;
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("1st fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 0)
+ {
+ puts ("file not created with size 0");
+ return 1;
+ }
+
+ if (posix_fallocate (fd, 512, 768) != 0)
+ {
+ puts ("1st posix_fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("2nd fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 512 + 768)
+ {
+ printf ("file size after 1st posix_fallocate call is %llu, expected %u\n",
+ (unsigned long long int) st.st_size, 512u + 768u);
+ return 1;
+ }
+
+ if (posix_fallocate (fd, 0, 1024) != 0)
+ {
+ puts ("2nd posix_fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("3rd fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 512 + 768)
+ {
+ puts ("file size changed in 2nd posix_fallocate");
+ return 1;
+ }
+
+ if (posix_fallocate (fd, 2048, 64) != 0)
+ {
+ puts ("3rd posix_fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("4th fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 2048 + 64)
+ {
+ printf ("file size after 3rd posix_fallocate call is %llu, expected %u\n",
+ (unsigned long long int) st.st_size, 2048u + 64u);
+ return 1;
+ }
+#ifdef TST_POSIX_FALLOCATE64
+ if (posix_fallocate64 (fd, 4097ULL, 4294967295ULL + 2ULL) != 0)
+ {
+ puts ("4th posix_fallocate call failed");
+ return 1;
+ }
+
+ if (fstat64 (fd, &st) != 0)
+ {
+ puts ("5th fstat failed");
+ return 1;
+ }
+
+ if (st.st_size != 4097ULL + 4294967295ULL + 2ULL)
+ {
+ printf ("file size after 4th posix_fallocate call is %llu, expected %llu\n",
+ (unsigned long long int) st.st_size, 4097ULL + 4294967295ULL + 2ULL);
+ return 1;
+ }
+#endif
+ close (fd);
+
+ return 0;
+}
diff --git a/test/unistd/tst-posix_fallocate64.c b/test/unistd/tst-posix_fallocate64.c
new file mode 100644
index 0000000..b1ee0ff
--- /dev/null
+++ b/test/unistd/tst-posix_fallocate64.c
@@ -0,0 +1,2 @@
+#define TST_POSIX_FALLOCATE64
+#include "tst-posix_fallocate.c"
diff --git a/test/unistd/tst-preadwrite.c b/test/unistd/tst-preadwrite.c
new file mode 100644
index 0000000..66a1c0a
--- /dev/null
+++ b/test/unistd/tst-preadwrite.c
@@ -0,0 +1,104 @@
+/* Tests for pread and pwrite.
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <string.h>
+#include <unistd.h>
+
+
+/* Allow testing of the 64-bit versions as well. */
+#ifndef PREAD
+# define PREAD pread
+# define PWRITE pwrite
+#endif
+
+#define STRINGIFY(s) STRINGIFY2 (s)
+#define STRINGIFY2(s) #s
+
+/* Prototype for our test function. */
+extern void do_prepare (int argc, char *argv[]);
+extern int do_test (int argc, char *argv[]);
+
+/* We have a preparation function. */
+#define PREPARE do_prepare
+
+/* We might need a bit longer timeout. */
+#define TIMEOUT 20 /* sec */
+
+/* This defines the `main' function and some more. */
+#include "../test-skeleton.c"
+
+/* These are for the temporary file we generate. */
+char *name;
+int fd;
+
+void
+do_prepare (int argc, char *argv[])
+{
+ char name_len;
+
+#define FNAME FNAME2(TRUNCATE)
+#define FNAME2(s) "/" STRINGIFY(s) "XXXXXX"
+
+ name_len = strlen (test_dir);
+ name = malloc (name_len + sizeof (FNAME));
+ if (name == NULL)
+ error (EXIT_FAILURE, errno, "cannot allocate file name");
+ mempcpy (mempcpy (name, test_dir, name_len), FNAME, sizeof (FNAME));
+ add_temp_file (name);
+
+ /* Open our test file. */
+ fd = mkstemp (name);
+ if (fd == -1)
+ error (EXIT_FAILURE, errno, "cannot open test file `%s'", name);
+}
+
+
+int
+do_test (int argc, char *argv[])
+{
+ char buf[1000];
+ char res[1000];
+ int i;
+
+ memset (buf, '\0', sizeof (buf));
+ memset (res, '\xff', sizeof (res));
+
+ if (write (fd, buf, sizeof (buf)) != sizeof (buf))
+ error (EXIT_FAILURE, errno, "during write");
+
+ for (i = 100; i < 200; ++i)
+ buf[i] = i;
+ if (PWRITE (fd, buf + 100, 100, 100) != 100)
+ error (EXIT_FAILURE, errno, "during %s", STRINGIFY (PWRITE));
+
+ for (i = 450; i < 600; ++i)
+ buf[i] = i;
+ if (PWRITE (fd, buf + 450, 150, 450) != 150)
+ error (EXIT_FAILURE, errno, "during %s", STRINGIFY (PWRITE));
+
+ if (PREAD (fd, res, sizeof (buf) - 50, 50) != sizeof (buf) - 50)
+ error (EXIT_FAILURE, errno, "during %s", STRINGIFY (PREAD));
+
+ close (fd);
+ unlink (name);
+
+ return memcmp (buf + 50, res, sizeof (buf) - 50);
+}
diff --git a/test/unistd/tst-preadwrite64.c b/test/unistd/tst-preadwrite64.c
new file mode 100644
index 0000000..a0ec021
--- /dev/null
+++ b/test/unistd/tst-preadwrite64.c
@@ -0,0 +1,23 @@
+/* Tests for pread64 and pwrite64.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define PREAD pread64
+#define PWRITE pwrite64
+
+#include "tst-preadwrite.c"
diff --git a/test/unistd/tst-pselect.c b/test/unistd/tst-pselect.c
new file mode 100644
index 0000000..cab9451
--- /dev/null
+++ b/test/unistd/tst-pselect.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/select.h>
+
+// our SIGALRM handler
+void handler(int signum) {
+ (void)signum;
+ puts("got signal\n");
+}
+
+static int
+do_test (void)
+{
+ int rc;
+ sigset_t wait_mask, mask_sigchld;
+ struct sigaction act;
+
+ // block SIGALRM. We want to handle it only when we're ready
+ sigemptyset(&mask_sigchld);
+ sigaddset(&mask_sigchld, SIGALRM);
+ sigprocmask(SIG_BLOCK, &mask_sigchld, &wait_mask);
+ sigdelset(&wait_mask, SIGALRM);
+
+ // register a signal handler so we can see when the signal arrives
+ memset(&act, 0, sizeof(act));
+ sigemptyset(&act.sa_mask); // just in case an empty set isn't all 0's (total paranoia)
+ act.sa_handler = handler;
+ sigaction(SIGALRM, &act, NULL);
+
+ // send ourselves a SIGARLM. It will pend until we unblock that signal in pselect()
+ printf("sending ourselves a signal\n");
+ kill(getpid(), SIGALRM);
+
+ printf("signal is pending; calling pselect()\n");
+ rc = pselect(0, NULL, NULL, NULL, NULL, &wait_mask);
+ if (rc != -1 || errno != EINTR) {
+ int e = errno;
+ printf("pselect() returned %d, errno %d (%s)\n", rc, e, strerror(e));
+ exit(1);
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
diff --git a/test/unistd/tstgetopt.c b/test/unistd/tstgetopt.c
new file mode 100644
index 0000000..1c1263e
--- /dev/null
+++ b/test/unistd/tstgetopt.c
@@ -0,0 +1,76 @@
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+main (int argc, char **argv)
+{
+ static const struct option options[] =
+ {
+ {"required", required_argument, NULL, 'r'},
+ {"optional", optional_argument, NULL, 'o'},
+ {"none", no_argument, NULL, 'n'},
+ {"color", no_argument, NULL, 'C'},
+ {"colour", no_argument, NULL, 'C'},
+ {NULL, 0, NULL, 0 }
+ };
+
+ int aflag = 0;
+ int bflag = 0;
+ char *cvalue = NULL;
+ int Cflag = 0;
+ int nflag = 0;
+ int idx;
+ int c;
+ int result = 0;
+
+ while ((c = getopt_long (argc, argv, "abc:", options, NULL)) >= 0)
+ switch (c)
+ {
+ case 'a':
+ aflag = 1;
+ break;
+ case 'b':
+ bflag = 1;
+ break;
+ case 'c':
+ cvalue = optarg;
+ break;
+ case 'C':
+ ++Cflag;
+ break;
+ case '?':
+ fputs ("Unknown option.\n", stderr);
+ return 1;
+ default:
+ fprintf (stderr, "This should never happen!\n");
+ return 1;
+
+ case 'r':
+ printf ("--required %s\n", optarg);
+ result |= strcmp (optarg, "foobar") != 0;
+ break;
+ case 'o':
+ printf ("--optional %s\n", optarg);
+ result |= optarg == NULL || strcmp (optarg, "bazbug") != 0;
+ break;
+ case 'n':
+ puts ("--none");
+ nflag = 1;
+ break;
+ }
+
+ printf ("aflag = %d, bflag = %d, cvalue = %s, Cflags = %d, nflag = %d\n",
+ aflag, bflag, cvalue, Cflag, nflag);
+
+ result |= (aflag != 1 || bflag != 1 || cvalue == NULL
+ || strcmp (cvalue, "foobar") != 0 || Cflag != 3 || nflag != 1);
+
+ for (idx = optind; idx < argc; idx++)
+ printf ("Non-option argument %s\n", argv[idx]);
+
+ result |= optind + 1 != argc || strcmp (argv[optind], "random") != 0;
+
+ return result;
+}
diff --git a/test/unistd/vfork.c b/test/unistd/vfork.c
new file mode 100644
index 0000000..2955839
--- /dev/null
+++ b/test/unistd/vfork.c
@@ -0,0 +1,53 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * vfork test for uClibc
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+
+int main(void)
+{
+ pid_t pid;
+ int status, wpid;
+ char *argv[] = {
+ "/bin/ls",
+ "-laF",
+ NULL,
+ };
+
+ clearenv();
+ if ((pid = vfork()) == 0) {
+ printf("Hi. I'm the child process...\n");
+ execvp(argv[0], argv);
+ _exit(0);
+ }
+
+ printf("Hello. I'm the parent process.\n");
+ while (1) {
+ wpid = wait(&status);
+ if (wpid > 0 && wpid != pid) {
+ continue;
+ }
+ if (wpid == pid)
+ break;
+ }
+
+ printf("Child process exited.\nGoodbye.\n");
+ return EXIT_SUCCESS;
+}
+
+/*
+Local Variables:
+c-file-style: "linux"
+c-basic-offset: 4
+tab-width: 4
+End:
+*/