It smells like additional tests for fchmod(), fchmodat(), lchmod() could uncover bugs on some platforms. So I'm adding more tests.
2021-01-09 Bruno Haible <br...@clisp.org> fchmod-tests, fchmodat tests, lchmod tests: Add more tests. * tests/test-fchmod.c: Include <fcntl.h>. (BASE): New macro. (main): Add more tests. * tests/test-fchmodat.c (main): Add more tests. * tests/test-lchmod.c (main): Likewise. diff --git a/tests/test-fchmod.c b/tests/test-fchmod.c index 43b70ac..f8db9e5 100644 --- a/tests/test-fchmod.c +++ b/tests/test-fchmod.c @@ -22,10 +22,13 @@ SIGNATURE_CHECK (fchmod, int, (int, mode_t)); #include <errno.h> +#include <fcntl.h> #include <unistd.h> #include "macros.h" +#define BASE "test-fchmod." + int main (void) { @@ -42,5 +45,24 @@ main (void) ASSERT (errno == EBADF); } + /* Test that fchmod works on regular files. */ + { + struct stat statbuf; + int fd; + + unlink (BASE "file"); + ASSERT (close (creat (BASE "file", 0600)) == 0); + fd = open (BASE "file", O_RDWR); + ASSERT (fd >= 0); + ASSERT (fchmod (fd, 0400) == 0); + ASSERT (stat (BASE "file", &statbuf) >= 0); + ASSERT ((statbuf.st_mode & 0700) == 0400); + ASSERT (close (fd) == 0); + + /* Clean up. */ + ASSERT (chmod (BASE "file", 0600) == 0); + ASSERT (unlink (BASE "file") == 0); + } + return 0; } diff --git a/tests/test-fchmodat.c b/tests/test-fchmodat.c index 5e4d2b0..6d430fa 100644 --- a/tests/test-fchmodat.c +++ b/tests/test-fchmodat.c @@ -46,6 +46,39 @@ main (void) ASSERT (errno == EBADF); } + /* Test that fchmodat works on regular files. */ + { + struct stat statbuf; + + unlink (BASE "file"); + ASSERT (close (creat (BASE "file", 0600)) == 0); + ASSERT (fchmodat (AT_FDCWD, BASE "file", 0400, 0) == 0); + ASSERT (stat (BASE "file", &statbuf) >= 0); + ASSERT ((statbuf.st_mode & 0700) == 0400); + + errno = 0; + ASSERT (fchmodat (AT_FDCWD, BASE "file/", 0600, 0) == -1); + ASSERT (errno == ENOTDIR); + + /* Clean up. */ + ASSERT (chmod (BASE "file", 0600) == 0); + ASSERT (unlink (BASE "file") == 0); + } + + /* Test that fchmodat works on directories. */ + { + struct stat statbuf; + rmdir (BASE "dir"); + ASSERT (mkdir (BASE "dir", 0700) == 0); + ASSERT (fchmodat (AT_FDCWD, BASE "dir", 0500, 0) == 0); + ASSERT (stat (BASE "dir", &statbuf) >= 0); + ASSERT ((statbuf.st_mode & 0700) == 0500); + ASSERT (fchmodat (AT_FDCWD, BASE "dir/", 0700, 0) == 0); + + /* Clean up. */ + ASSERT (rmdir (BASE "dir") == 0); + } + /* Test that fchmodat works on non-symlinks, when given the AT_SYMLINK_NOFOLLOW flag. */ { diff --git a/tests/test-lchmod.c b/tests/test-lchmod.c index 7b8e8a1..d4c811e 100644 --- a/tests/test-lchmod.c +++ b/tests/test-lchmod.c @@ -33,7 +33,7 @@ SIGNATURE_CHECK (lchmod, int, (const char *, mode_t)); int main (void) { - /* Test that lchmod works on non-symlinks. */ + /* Test that lchmod works on regular files. */ { struct stat statbuf; unlink (BASE "file"); @@ -41,11 +41,31 @@ main (void) ASSERT (lchmod (BASE "file", 0400) == 0); ASSERT (stat (BASE "file", &statbuf) >= 0); ASSERT ((statbuf.st_mode & 0700) == 0400); + + errno = 0; + ASSERT (lchmod (BASE "file/", 0600) == -1); + ASSERT (errno == ENOTDIR); + /* Clean up. */ ASSERT (chmod (BASE "file", 0600) == 0); ASSERT (unlink (BASE "file") == 0); } + /* Test that lchmod works on directories. */ + { + struct stat statbuf; + + rmdir (BASE "dir"); + ASSERT (mkdir (BASE "dir", 0700) == 0); + ASSERT (lchmod (BASE "dir", 0500) == 0); + ASSERT (stat (BASE "dir", &statbuf) >= 0); + ASSERT ((statbuf.st_mode & 0700) == 0500); + ASSERT (lchmod (BASE "dir/", 0700) == 0); + + /* Clean up. */ + ASSERT (rmdir (BASE "dir") == 0); + } + /* Test that lchmod on symlinks does not modify the symlink target. */ { unlink (BASE "file");