diff options
author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-24 20:22:12 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-24 20:22:12 +0200 |
commit | 7988979a722b4cdf287b2093956a76a3f19b9897 (patch) | |
tree | d35e251d0472ceca55a2eef61cff261c8ee68fab /test/unistd |
add uClibc-ng test directory
Diffstat (limited to 'test/unistd')
-rw-r--r-- | test/unistd/Makefile | 8 | ||||
-rw-r--r-- | test/unistd/Makefile.in | 44 | ||||
-rw-r--r-- | test/unistd/clone.c | 101 | ||||
-rw-r--r-- | test/unistd/clone_cruft.h | 24 | ||||
-rw-r--r-- | test/unistd/errno.c | 29 | ||||
-rw-r--r-- | test/unistd/exec-null.c | 13 | ||||
-rw-r--r-- | test/unistd/fork.c | 91 | ||||
-rw-r--r-- | test/unistd/getcwd.c | 39 | ||||
-rw-r--r-- | test/unistd/getopt.c | 69 | ||||
-rw-r--r-- | test/unistd/getopt_long.c | 93 | ||||
-rw-r--r-- | test/unistd/tst-fallocate.c | 166 | ||||
-rw-r--r-- | test/unistd/tst-fallocate64.c | 2 | ||||
-rwxr-xr-x | test/unistd/tst-getconf.sh | 240 | ||||
-rw-r--r-- | test/unistd/tst-posix_fallocate.c | 127 | ||||
-rw-r--r-- | test/unistd/tst-posix_fallocate64.c | 2 | ||||
-rw-r--r-- | test/unistd/tst-preadwrite.c | 104 | ||||
-rw-r--r-- | test/unistd/tst-preadwrite64.c | 23 | ||||
-rw-r--r-- | test/unistd/tst-pselect.c | 51 | ||||
-rw-r--r-- | test/unistd/tstgetopt.c | 76 | ||||
-rw-r--r-- | test/unistd/vfork.c | 53 |
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: +*/ |