Mercurial > hg > octave-lyh > gnulib-hg
changeset 11980:0811c19e147f
test-link: consolidate into single C program, test more cases
* tests/test-link.sh: Delete.
* tests/test-link.c: Test more error conditions. Exposes bugs on
at least Cygwin and Solaris.
* modules/link-tests (Files): Remove unused file.
(Depends-on): Add errno, sys_stat.
(Makefile.am): Simplify.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Wed, 09 Sep 2009 11:06:44 -0600 |
parents | 4dab439a2737 |
children | 7e5f9267c62e |
files | ChangeLog modules/link-tests tests/test-link.c tests/test-link.sh |
diffstat | 4 files changed, 111 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-09-09 Eric Blake <ebb9@byu.net> + + test-link: consolidate into single C program, test more cases + * tests/test-link.sh: Delete. + * tests/test-link.c: Test more error conditions. Exposes bugs on + at least Cygwin and Solaris. + * modules/link-tests (Files): Remove unused file. + (Depends-on): Add errno, sys_stat. + (Makefile.am): Simplify. + 2009-09-08 Bruno Haible <bruno@clisp.org> Work around towlower, towupper bug on mingw.
--- a/modules/link-tests +++ b/modules/link-tests @@ -1,12 +1,12 @@ Files: -tests/test-link.sh tests/test-link.c Depends-on: +errno +sys_stat configure.ac: Makefile.am: -TESTS += test-link.sh -TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' +TESTS += test-link check_PROGRAMS += test-link
--- a/tests/test-link.c +++ b/tests/test-link.c @@ -19,8 +19,12 @@ #include <unistd.h> #include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> #define ASSERT(expr) \ do \ @@ -34,30 +38,119 @@ } \ while (0) +#define BASE "test-link.t" + int main (int argc, char **argv) { + int fd; int ret; - ASSERT (argc == 3); + /* Remove any garbage left from previous partial runs. */ + ASSERT (system ("rm -rf " BASE "*") == 0); + + /* Create first file. */ + fd = open (BASE "a", O_CREAT | O_EXCL | O_WRONLY, 0600); + ASSERT (0 <= fd); + ASSERT (write (fd, "hello", 5) == 5); + ASSERT (close (fd) == 0); - ret = link (argv[1], argv[2]); - if (ret < 0) + /* Not all file systems support link. Mingw doesn't have reliable + st_nlink on hard links, but our implementation does fail with + EPERM on poor file systems, and we can detect the inferior stat() + via st_ino. Cygwin 1.5.x copies rather than links files on those + file systems, but there, st_nlink and st_ino are reliable. */ + ret = link (BASE "a", BASE "b"); + if (!ret) + { + struct stat st; + ASSERT (stat (BASE "b", &st) == 0); + if (st.st_ino && st.st_nlink != 2) + { + ASSERT (unlink (BASE "b") == 0); + errno = EPERM; + ret = -1; + } + } + if (ret == -1) { /* If the device does not support hard links, errno is EPERM on Linux, EOPNOTSUPP on FreeBSD. */ switch (errno) { case EPERM: -#ifdef EOPNOTSUPP case EOPNOTSUPP: -#endif + fputs ("skipping test: " + "hard links are not supported on this file system\n", stderr); + ASSERT (unlink (BASE "a") == 0); return 77; default: perror ("link"); return 1; } } + ASSERT (ret == 0); + + /* Now, for some behavior tests. Modify the contents of 'b', and + ensure that 'a' can see it, both while 'b' exists and after. */ + fd = open (BASE "b", O_APPEND | O_WRONLY); + ASSERT (0 <= fd); + ASSERT (write (fd, "world", 5) == 5); + ASSERT (close (fd) == 0); + { + char buf[11] = { 0 }; + fd = open (BASE "a", O_RDONLY); + ASSERT (0 <= fd); + ASSERT (read (fd, buf, 10) == 10); + ASSERT (strcmp (buf, "helloworld") == 0); + ASSERT (close (fd) == 0); + ASSERT (unlink (BASE "b") == 0); + fd = open (BASE "a", O_RDONLY); + ASSERT (0 <= fd); + ASSERT (read (fd, buf, 10) == 10); + ASSERT (strcmp (buf, "helloworld") == 0); + ASSERT (close (fd) == 0); + } + + /* Test for various error conditions. Assumes hard links to + directories are not permitted. */ + ASSERT (mkdir (BASE "d", 0700) == 0); + errno = 0; + ASSERT (link (BASE "a", ".") == -1); + ASSERT (errno == EEXIST || errno == EINVAL); + errno = 0; + ASSERT (link (BASE "a", BASE "a") == -1); + ASSERT (errno == EEXIST); + ASSERT (link (BASE "a", BASE "b") == 0); + errno = 0; + ASSERT (link (BASE "a", BASE "b") == -1); + ASSERT (errno == EEXIST); + errno = 0; + ASSERT (link (BASE "a", BASE "d") == -1); + ASSERT (errno == EEXIST); + errno = 0; + ASSERT (link (BASE "c", BASE "e") == -1); + ASSERT (errno == ENOENT); + errno = 0; + ASSERT (link (BASE "a", BASE "c/.") == -1); + ASSERT (errno == ENOENT); + errno = 0; + ASSERT (link (BASE "a/", BASE "c") == -1); + ASSERT (errno == ENOTDIR); + errno = 0; + ASSERT (link (BASE "a", BASE "c/") == -1); + ASSERT (errno == ENOTDIR); + errno = 0; + ASSERT (link (BASE "d", BASE "c") == -1); + ASSERT (errno == EPERM || errno == EACCES); + + /* Clean up. */ + ASSERT (unlink (BASE "a") == 0); + ASSERT (unlink (BASE "b") == 0); + errno = 0; + ASSERT (unlink (BASE "c") == -1); + ASSERT (errno == ENOENT); + ASSERT (rmdir (BASE "d") == 0); return 0; }
deleted file mode 100755 --- a/tests/test-link.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -tmpfiles="test-link-a.txt test-link-b.txt test-link-c.txt" -trap 'rm -fr $tmpfiles' 1 2 3 15 - -# Create a file. -echo "hello" > test-link-a.txt || exit 1 - -# Use link() to create a new name for it. -./test-link${EXEEXT} test-link-a.txt test-link-b.txt -case $? in - 0) ;; - 77) - echo "Skipping test: hard links are not supported on this file system" - rm -fr $tmpfiles - exit 77 - ;; - *) exit 1 ;; -esac -cmp test-link-a.txt test-link-b.txt || exit 1 - -# Modify the contents of the first file. -echo "world" >> test-link-a.txt || exit 1 -cmp test-link-a.txt test-link-b.txt || exit 1 - -# Modify the contents of the second file. -echo "some text" >> test-link-b.txt || exit 1 -cmp test-link-a.txt test-link-b.txt || exit 1 - -# Delete the first file, then verity the second file still has the same -# contents. -cp test-link-a.txt test-link-c.txt || exit 1 -rm test-link-a.txt || exit 1 -cmp test-link-b.txt test-link-c.txt || exit 1 - -rm -fr $tmpfiles -exit 0