aboutsummaryrefslogtreecommitdiffstats
path: root/test/test.c
diff options
context:
space:
mode:
authorNikolaus Rath <Nikolaus@rath.org>2017-01-05 09:37:00 -0800
committerNikolaus Rath <Nikolaus@rath.org>2017-01-12 15:19:04 -0800
commit9f96db71252fc66b72c433e2ca0d49e031c6a5fd (patch)
tree494132dae14dba3de18a9013f2299cfc37cceda5 /test/test.c
parent3006686b536942f6f96675e3d12b793087e78e6a (diff)
downloadlibfuse-9f96db71252fc66b72c433e2ca0d49e031c6a5fd.tar.gz
Added experimental support for building with Meson+Ninja
Diffstat (limited to 'test/test.c')
-rw-r--r--test/test.c1522
1 files changed, 0 insertions, 1522 deletions
diff --git a/test/test.c b/test/test.c
deleted file mode 100644
index 281f218..0000000
--- a/test/test.c
+++ /dev/null
@@ -1,1522 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <utime.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-
-static char testfile[1024];
-static char testfile2[1024];
-static char testdir[1024];
-static char testdir2[1024];
-static char subfile[1024];
-
-static char testfile_r[1024];
-static char testfile2_r[1024];
-static char testdir_r[1024];
-static char testdir2_r[1024];
-static char subfile_r[1024];
-
-static char testname[256];
-static char testdata[] = "abcdefghijklmnopqrstuvwxyz";
-static char testdata2[] = "1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
-static const char *testdir_files[] = { "f1", "f2", NULL};
-static char zerodata[4096];
-static int testdatalen = sizeof(testdata) - 1;
-static int testdata2len = sizeof(testdata2) - 1;
-static unsigned int testnum = 1;
-static unsigned int select_test = 0;
-static unsigned int skip_test = 0;
-
-#define MAX_ENTRIES 1024
-
-static void test_perror(const char *func, const char *msg)
-{
- fprintf(stderr, "%s %s() - %s: %s\n", testname, func, msg,
- strerror(errno));
-}
-
-static void test_error(const char *func, const char *msg, ...)
- __attribute__ ((format (printf, 2, 3)));
-
-static void __start_test(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-static void test_error(const char *func, const char *msg, ...)
-{
- va_list ap;
- fprintf(stderr, "%s %s() - ", testname, func);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- va_end(ap);
- fprintf(stderr, "\n");
-}
-
-static void success(void)
-{
- fprintf(stderr, "%s OK\n", testname);
-}
-
-static void __start_test(const char *fmt, ...)
-{
- unsigned int n;
- va_list ap;
- n = sprintf(testname, "%3i [", testnum++);
- va_start(ap, fmt);
- n += vsprintf(testname + n, fmt, ap);
- va_end(ap);
- sprintf(testname + n, "]");
-}
-
-#define start_test(msg, args...) { \
- if ((select_test && testnum != select_test) || \
- (testnum == skip_test)) { \
- testnum++; \
- return 0; \
- } \
- __start_test(msg, ##args); \
-}
-
-#define PERROR(msg) test_perror(__FUNCTION__, msg)
-#define ERROR(msg, args...) test_error(__FUNCTION__, msg, ##args)
-
-static int check_size(const char *path, int len)
-{
- struct stat stbuf;
- int res = stat(path, &stbuf);
- if (res == -1) {
- PERROR("stat");
- return -1;
- }
- if (stbuf.st_size != len) {
- ERROR("length %u instead of %u", (int) stbuf.st_size,
- (int) len);
- return -1;
- }
- return 0;
-}
-
-static int fcheck_size(int fd, int len)
-{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if (stbuf.st_size != len) {
- ERROR("length %u instead of %u", (int) stbuf.st_size,
- (int) len);
- return -1;
- }
- return 0;
-}
-
-static int check_type(const char *path, mode_t type)
-{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if ((stbuf.st_mode & S_IFMT) != type) {
- ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
- return -1;
- }
- return 0;
-}
-
-static int fcheck_type(int fd, mode_t type)
-{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if ((stbuf.st_mode & S_IFMT) != type) {
- ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
- return -1;
- }
- return 0;
-}
-
-static int check_mode(const char *path, mode_t mode)
-{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if ((stbuf.st_mode & 07777) != mode) {
- ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
- return -1;
- }
- return 0;
-}
-
-static int fcheck_mode(int fd, mode_t mode)
-{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if ((stbuf.st_mode & 07777) != mode) {
- ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
- return -1;
- }
- return 0;
-}
-
-static int check_times(const char *path, time_t atime, time_t mtime)
-{
- int err = 0;
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if (stbuf.st_atime != atime) {
- ERROR("atime %li instead of %li", stbuf.st_atime, atime);
- err--;
- }
- if (stbuf.st_mtime != mtime) {
- ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
- err--;
- }
- if (err)
- return -1;
-
- return 0;
-}
-
-#if 0
-static int fcheck_times(int fd, time_t atime, time_t mtime)
-{
- int err = 0;
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if (stbuf.st_atime != atime) {
- ERROR("atime %li instead of %li", stbuf.st_atime, atime);
- err--;
- }
- if (stbuf.st_mtime != mtime) {
- ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
- err--;
- }
- if (err)
- return -1;
-
- return 0;
-}
-#endif
-
-static int check_nlink(const char *path, nlink_t nlink)
-{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == -1) {
- PERROR("lstat");
- return -1;
- }
- if (stbuf.st_nlink != nlink) {
- ERROR("nlink %li instead of %li", (long) stbuf.st_nlink,
- (long) nlink);
- return -1;
- }
- return 0;
-}
-
-static int fcheck_nlink(int fd, nlink_t nlink)
-{
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1) {
- PERROR("fstat");
- return -1;
- }
- if (stbuf.st_nlink != nlink) {
- ERROR("nlink %li instead of %li", (long) stbuf.st_nlink,
- (long) nlink);
- return -1;
- }
- return 0;
-}
-
-static int check_nonexist(const char *path)
-{
- struct stat stbuf;
- int res = lstat(path, &stbuf);
- if (res == 0) {
- ERROR("file should not exist");
- return -1;
- }
- if (errno != ENOENT) {
- ERROR("file should not exist: %s", strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int check_buffer(const char *buf, const char *data, unsigned len)
-{
- if (memcmp(buf, data, len) != 0) {
- ERROR("data mismatch");
- return -1;
- }
- return 0;
-}
-
-static int check_data(const char *path, const char *data, int offset,
- unsigned len)
-{
- char buf[4096];
- int res;
- int fd = open(path, O_RDONLY);
- if (fd == -1) {
- PERROR("open");
- return -1;
- }
- if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
- PERROR("lseek");
- close(fd);
- return -1;
- }
- while (len) {
- int rdlen = len < sizeof(buf) ? len : sizeof(buf);
- res = read(fd, buf, rdlen);
- if (res == -1) {
- PERROR("read");
- close(fd);
- return -1;
- }
- if (res != rdlen) {
- ERROR("short read: %u instead of %u", res, rdlen);
- close(fd);
- return -1;
- }
- if (check_buffer(buf, data, rdlen) != 0) {
- close(fd);
- return -1;
- }
- data += rdlen;
- len -= rdlen;
- }
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- return 0;
-}
-
-static int fcheck_data(int fd, const char *data, int offset,
- unsigned len)
-{
- char buf[4096];
- int res;
- if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
- PERROR("lseek");
- return -1;
- }
- while (len) {
- int rdlen = len < sizeof(buf) ? len : sizeof(buf);
- res = read(fd, buf, rdlen);
- if (res == -1) {
- PERROR("read");
- return -1;
- }
- if (res != rdlen) {
- ERROR("short read: %u instead of %u", res, rdlen);
- return -1;
- }
- if (check_buffer(buf, data, rdlen) != 0) {
- return -1;
- }
- data += rdlen;
- len -= rdlen;
- }
- return 0;
-}
-
-static int check_dir_contents(const char *path, const char **contents)
-{
- int i;
- int res;
- int err = 0;
- int found[MAX_ENTRIES];
- const char *cont[MAX_ENTRIES];
- DIR *dp;
-
- for (i = 0; contents[i]; i++) {
- assert(i < MAX_ENTRIES - 3);
- found[i] = 0;
- cont[i] = contents[i];
- }
- found[i] = 0;
- cont[i++] = ".";
- found[i] = 0;
- cont[i++] = "..";
- cont[i] = NULL;
-
- dp = opendir(path);
- if (dp == NULL) {
- PERROR("opendir");
- return -1;
- }
- memset(found, 0, sizeof(found));
- while(1) {
- struct dirent *de;
- errno = 0;
- de = readdir(dp);
- if (de == NULL) {
- if (errno) {
- PERROR("readdir");
- closedir(dp);
- return -1;
- }
- break;
- }
- for (i = 0; cont[i] != NULL; i++) {
- assert(i < MAX_ENTRIES);
- if (strcmp(cont[i], de->d_name) == 0) {
- if (found[i]) {
- ERROR("duplicate entry <%s>",
- de->d_name);
- err--;
- } else
- found[i] = 1;
- break;
- }
- }
- if (!cont[i]) {
- ERROR("unexpected entry <%s>", de->d_name);
- err --;
- }
- }
- for (i = 0; cont[i] != NULL; i++) {
- if (!found[i]) {
- ERROR("missing entry <%s>", cont[i]);
- err--;
- }
- }
- res = closedir(dp);
- if (res == -1) {
- PERROR("closedir");
- return -1;
- }
- if (err)
- return -1;
-
- return 0;
-}
-
-static int create_file(const char *path, const char *data, int len)
-{
- int res;
- int fd;
-
- unlink(path);
- fd = creat(path, 0644);
- if (fd == -1) {
- PERROR("creat");
- return -1;
- }
- if (len) {
- res = write(fd, data, len);
- if (res == -1) {
- PERROR("write");
- close(fd);
- return -1;
- }
- if (res != len) {
- ERROR("write is short: %u instead of %u", res, len);
- close(fd);
- return -1;
- }
- }
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- res = check_type(path, S_IFREG);
- if (res == -1)
- return -1;
- res = check_mode(path, 0644);
- if (res == -1)
- return -1;
- res = check_nlink(path, 1);
- if (res == -1)
- return -1;
- res = check_size(path, len);
- if (res == -1)
- return -1;
-
- if (len) {
- res = check_data(path, data, 0, len);
- if (res == -1)
- return -1;
- }
-
- return 0;
-}
-
-static int cleanup_dir(const char *path, const char **dir_files, int quiet)
-{
- int i;
- int err = 0;
-
- for (i = 0; dir_files[i]; i++) {
- int res;
- char fpath[1024];
- sprintf(fpath, "%s/%s", path, dir_files[i]);
- res = unlink(fpath);
- if (res == -1 && !quiet) {
- PERROR("unlink");
- err --;
- }
- }
- if (err)
- return -1;
-
- return 0;
-}
-
-static int create_dir(const char *path, const char **dir_files)
-{
- int res;
- int i;
-
- rmdir(path);
- res = mkdir(path, 0755);
- if (res == -1) {
- PERROR("mkdir");
- return -1;
- }
- res = check_type(path, S_IFDIR);
- if (res == -1)
- return -1;
- res = check_mode(path, 0755);
- if (res == -1)
- return -1;
-
- for (i = 0; dir_files[i]; i++) {
- char fpath[1024];
- sprintf(fpath, "%s/%s", path, dir_files[i]);
- res = create_file(fpath, "", 0);
- if (res == -1) {
- cleanup_dir(path, dir_files, 1);
- return -1;
- }
- }
- res = check_dir_contents(path, dir_files);
- if (res == -1) {
- cleanup_dir(path, dir_files, 1);
- return -1;
- }
-
- return 0;
-}
-
-static int test_truncate(int len)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int res;
-
- start_test("truncate(%u)", (int) len);
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- res = truncate(testfile, len);
- if (res == -1) {
- PERROR("truncate");
- return -1;
- }
- res = check_size(testfile, len);
- if (res == -1)
- return -1;
-
- if (len > 0) {
- if (len <= datalen) {
- res = check_data(testfile, data, 0, len);
- if (res == -1)
- return -1;
- } else {
- res = check_data(testfile, data, 0, datalen);
- if (res == -1)
- return -1;
- res = check_data(testfile, zerodata, datalen,
- len - datalen);
- if (res == -1)
- return -1;
- }
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_ftruncate(int len, int mode)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int res;
- int fd;
-
- start_test("ftruncate(%u) mode: 0%03o", len, mode);
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- fd = open(testfile, O_WRONLY);
- if (fd == -1) {
- PERROR("open");
- return -1;
- }
-
- res = fchmod(fd, mode);
- if (res == -1) {
- PERROR("fchmod");
- close(fd);
- return -1;
- }
- res = check_mode(testfile, mode);
- if (res == -1) {
- close(fd);
- return -1;
- }
- res = ftruncate(fd, len);
- if (res == -1) {
- PERROR("ftruncate");
- close(fd);
- return -1;
- }
- close(fd);
- res = check_size(testfile, len);
- if (res == -1)
- return -1;
-
- if (len > 0) {
- if (len <= datalen) {
- res = check_data(testfile, data, 0, len);
- if (res == -1)
- return -1;
- } else {
- res = check_data(testfile, data, 0, datalen);
- if (res == -1)
- return -1;
- res = check_data(testfile, zerodata, datalen,
- len - datalen);
- if (res == -1)
- return -1;
- }
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_utime(void)
-{
- struct utimbuf utm;
- time_t atime = 987631200;
- time_t mtime = 123116400;
- int res;
-
- start_test("utime");
- res = create_file(testfile, NULL, 0);
- if (res == -1)
- return -1;
-
- utm.actime = atime;
- utm.modtime = mtime;
- res = utime(testfile, &utm);
- if (res == -1) {
- PERROR("utime");
- return -1;
- }
- res = check_times(testfile, atime, mtime);
- if (res == -1) {
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_create(void)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
- int fd;
-
- start_test("create");
- unlink(testfile);
- fd = creat(testfile, 0644);
- if (fd == -1) {
- PERROR("creat");
- return -1;
- }
- res = write(fd, data, datalen);
- if (res == -1) {
- PERROR("write");
- close(fd);
- return -1;
- }
- if (res != datalen) {
- ERROR("write is short: %u instead of %u", res, datalen);
- close(fd);
- return -1;
- }
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- res = check_type(testfile, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 1);
- err += check_size(testfile, datalen);
- err += check_data(testfile, data, 0, datalen);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_create_unlink(void)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
- int fd;
-
- start_test("create+unlink");
- unlink(testfile);
- fd = open(testfile, O_CREAT | O_RDWR | O_TRUNC, 0644);
- if (fd == -1) {
- PERROR("creat");
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- close(fd);
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- res = write(fd, data, datalen);
- if (res == -1) {
- PERROR("write");
- close(fd);
- return -1;
- }
- if (res != datalen) {
- ERROR("write is short: %u instead of %u", res, datalen);
- close(fd);
- return -1;
- }
- err += fcheck_type(fd, S_IFREG);
- err += fcheck_mode(fd, 0644);
- err += fcheck_nlink(fd, 0);
- err += fcheck_size(fd, datalen);
- err += fcheck_data(fd, data, 0, datalen);
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- err--;
- }
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_mknod(void)
-{
- int err = 0;
- int res;
-
- start_test("mknod");
- unlink(testfile);
- res = mknod(testfile, 0644, 0);
- if (res == -1) {
- PERROR("mknod");
- return -1;
- }
- res = check_type(testfile, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 1);
- err += check_size(testfile, 0);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-#define test_open(exist, flags, mode) do_test_open(exist, flags, #flags, mode)
-
-static int do_test_open(int exist, int flags, const char *flags_str, int mode)
-{
- char buf[4096];
- const char *data = testdata;
- int datalen = testdatalen;
- unsigned currlen = 0;
- int err = 0;
- int res;
- int fd;
- off_t off;
-
- start_test("open(%s, %s, 0%03o)", exist ? "+" : "-", flags_str, mode);
- unlink(testfile);
- if (exist) {
- res = create_file(testfile_r, testdata2, testdata2len);
- if (res == -1)
- return -1;
-
- currlen = testdata2len;
- }
-
- fd = open(testfile, flags, mode);
- if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
- if (fd != -1) {
- ERROR("open should have failed");
- close(fd);
- return -1;
- } else if (errno == EEXIST)
- goto succ;
- }
- if (!(flags & O_CREAT) && !exist) {
- if (fd != -1) {
- ERROR("open should have failed");
- close(fd);
- return -1;
- } else if (errno == ENOENT)
- goto succ;
- }
- if (fd == -1) {
- PERROR("open");
- return -1;
- }
-
- if (flags & O_TRUNC)
- currlen = 0;
-
- err += check_type(testfile, S_IFREG);
- if (exist)
- err += check_mode(testfile, 0644);
- else
- err += check_mode(testfile, mode);
- err += check_nlink(testfile, 1);
- err += check_size(testfile, currlen);
- if (exist && !(flags & O_TRUNC) && (mode & 0400))
- err += check_data(testfile, testdata2, 0, testdata2len);
-
- res = write(fd, data, datalen);
- if ((flags & O_ACCMODE) != O_RDONLY) {
- if (res == -1) {
- PERROR("write");
- err --;
- } else if (res != datalen) {
- ERROR("write is short: %u instead of %u", res, datalen);
- err --;
- } else {
- if (datalen > (int) currlen)
- currlen = datalen;
-
- err += check_size(testfile, currlen);
-
- if (mode & 0400) {
- err += check_data(testfile, data, 0, datalen);
- if (exist && !(flags & O_TRUNC) &&
- testdata2len > datalen)
- err += check_data(testfile,
- testdata2 + datalen,
- datalen,
- testdata2len - datalen);
- }
- }
- } else {
- if (res != -1) {
- ERROR("write should have failed");
- err --;
- } else if (errno != EBADF) {
- PERROR("write");
- err --;
- }
- }
- off = lseek(fd, SEEK_SET, 0);
- if (off == (off_t) -1) {
- PERROR("lseek");
- err--;
- } else if (off != 0) {
- ERROR("offset should have returned 0");
- err --;
- }
- res = read(fd, buf, sizeof(buf));
- if ((flags & O_ACCMODE) != O_WRONLY) {
- if (res == -1) {
- PERROR("read");
- err--;
- } else {
- int readsize =
- currlen < sizeof(buf) ? currlen : sizeof(buf);
- if (res != readsize) {
- ERROR("read is short: %i instead of %u",
- res, readsize);
- err--;
- } else {
- if ((flags & O_ACCMODE) != O_RDONLY) {
- err += check_buffer(buf, data, datalen);
- if (exist && !(flags & O_TRUNC) &&
- testdata2len > datalen)
- err += check_buffer(buf + datalen,
- testdata2 + datalen,
- testdata2len - datalen);
- } else if (exist)
- err += check_buffer(buf, testdata2,
- testdata2len);
- }
- }
- } else {
- if (res != -1) {
- ERROR("read should have failed");
- err --;
- } else if (errno != EBADF) {
- PERROR("read");
- err --;
- }
- }
-
- res = close(fd);
- if (res == -1) {
- PERROR("close");
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- res = check_nonexist(testfile_r);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
-succ:
- success();
- return 0;
-}
-
-#define test_open_acc(flags, mode, err) \
- do_test_open_acc(flags, #flags, mode, err)
-
-static int do_test_open_acc(int flags, const char *flags_str, int mode, int err)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int res;
- int fd;
-
- start_test("open_acc(%s) mode: 0%03o message: '%s'", flags_str, mode,
- strerror(err));
- unlink(testfile);
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- res = chmod(testfile, mode);
- if (res == -1) {
- PERROR("chmod");
- return -1;
- }
-
- res = check_mode(testfile, mode);
- if (res == -1)
- return -1;
-
- fd = open(testfile, flags);
- if (fd == -1) {
- if (err != errno) {
- PERROR("open");
- return -1;
- }
- } else {
- if (err) {
- ERROR("open should have failed");
- close(fd);
- return -1;
- }
- close(fd);
- }
- success();
- return 0;
-}
-
-static int test_symlink(void)
-{
- char buf[1024];
- const char *data = testdata;
- int datalen = testdatalen;
- int linklen = strlen(testfile);
- int err = 0;
- int res;
-
- start_test("symlink");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = symlink(testfile, testfile2);
- if (res == -1) {
- PERROR("symlink");
- return -1;
- }
- res = check_type(testfile2, S_IFLNK);
- if (res == -1)
- return -1;
- err += check_mode(testfile2, 0777);
- err += check_nlink(testfile2, 1);
- res = readlink(testfile2, buf, sizeof(buf));
- if (res == -1) {
- PERROR("readlink");
- err--;
- }
- if (res != linklen) {
- ERROR("short readlink: %u instead of %u", res, linklen);
- err--;
- }
- if (memcmp(buf, testfile, linklen) != 0) {
- ERROR("link mismatch");
- err--;
- }
- err += check_size(testfile2, datalen);
- err += check_data(testfile2, data, 0, datalen);
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_link(void)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
-
- start_test("link");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = link(testfile, testfile2);
- if (res == -1) {
- PERROR("link");
- return -1;
- }
- res = check_type(testfile2, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile2, 0644);
- err += check_nlink(testfile2, 2);
- err += check_size(testfile2, datalen);
- err += check_data(testfile2, data, 0, datalen);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
-
- err += check_nlink(testfile2, 1);
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_link2(void)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
-
- start_test("link-unlink-link");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = link(testfile, testfile2);
- if (res == -1) {
- PERROR("link");
- return -1;
- }
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- res = link(testfile2, testfile);
- if (res == -1) {
- PERROR("link");
- }
- res = check_type(testfile, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 2);
- err += check_size(testfile, datalen);
- err += check_data(testfile, data, 0, datalen);
-
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- err += check_nlink(testfile, 1);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_rename_file(void)
-{
- const char *data = testdata;
- int datalen = testdatalen;
- int err = 0;
- int res;
-
- start_test("rename file");
- res = create_file(testfile, data, datalen);
- if (res == -1)
- return -1;
-
- unlink(testfile2);
- res = rename(testfile, testfile2);
- if (res == -1) {
- PERROR("rename");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- res = check_type(testfile2, S_IFREG);
- if (res == -1)
- return -1;
- err += check_mode(testfile2, 0644);
- err += check_nlink(testfile2, 1);
- err += check_size(testfile2, datalen);
- err += check_data(testfile2, data, 0, datalen);
- res = unlink(testfile2);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_rename_dir(void)
-{
- int err = 0;
- int res;
-
- start_test("rename dir");
- res = create_dir(testdir, testdir_files);
- if (res == -1)
- return -1;
-
- rmdir(testdir2);
- res = rename(testdir, testdir2);
- if (res == -1) {
- PERROR("rename");
- cleanup_dir(testdir, testdir_files, 1);
- return -1;
- }
- res = check_nonexist(testdir);
- if (res == -1) {
- cleanup_dir(testdir, testdir_files, 1);
- return -1;
- }
- res = check_type(testdir2, S_IFDIR);
- if (res == -1) {
- cleanup_dir(testdir2, testdir_files, 1);
- return -1;
- }
- err += check_mode(testdir2, 0755);
- err += check_dir_contents(testdir2, testdir_files);
- err += cleanup_dir(testdir2, testdir_files, 0);
- res = rmdir(testdir2);
- if (res == -1) {
- PERROR("rmdir");
- return -1;
- }
- res = check_nonexist(testdir2);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_mkfifo(void)
-{
- int res;
- int err = 0;
-
- start_test("mkfifo");
- unlink(testfile);
- res = mkfifo(testfile, 0644);
- if (res == -1) {
- PERROR("mkfifo");
- return -1;
- }
- res = check_type(testfile, S_IFIFO);
- if (res == -1)
- return -1;
- err += check_mode(testfile, 0644);
- err += check_nlink(testfile, 1);
- res = unlink(testfile);
- if (res == -1) {
- PERROR("unlink");
- return -1;
- }
- res = check_nonexist(testfile);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-static int test_mkdir(void)
-{
- int res;
- int err = 0;
- const char *dir_contents[] = {NULL};
-
- start_test("mkdir");
- rmdir(testdir);
- res = mkdir(testdir, 0755);
- if (res == -1) {
- PERROR("mkdir");
- return -1;
- }
- res = check_type(testdir, S_IFDIR);
- if (res == -1)
- return -1;
- err += check_mode(testdir, 0755);
- err += check_nlink(testdir, 2);
- err += check_dir_contents(testdir, dir_contents);
- res = rmdir(testdir);
- if (res == -1) {
- PERROR("rmdir");
- return -1;
- }
- res = check_nonexist(testdir);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-#define test_create_ro_dir(flags) \
- do_test_create_ro_dir(flags, #flags)
-
-static int do_test_create_ro_dir(int flags, const char *flags_str)
-{
- int res;
- int err = 0;
- int fd;
-
- start_test("open(%s) in read-only directory", flags_str);
- rmdir(testdir);
- res = mkdir(testdir, 0555);
- if (res == -1) {
- PERROR("mkdir");
- return -1;
- }
- fd = open(subfile, flags, 0644);
- if (fd != -1) {
- close(fd);
- unlink(subfile);
- ERROR("open should have failed");
- err--;
- } else {
- res = check_nonexist(subfile);
- if (res == -1)
- err--;
- }
- unlink(subfile);
- res = rmdir(testdir);
- if (res == -1) {
- PERROR("rmdir");
- return -1;
- }
- res = check_nonexist(testdir);
- if (res == -1)
- return -1;
- if (err)
- return -1;
-
- success();
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- const char *basepath;
- const char *realpath;
- int err = 0;
- int a;
- int is_root;
-
- umask(0);
- if (argc < 2 || argc > 4) {
- fprintf(stderr, "usage: %s testdir [:realdir] [[-]test#]\n", argv[0]);
- return 1;
- }
- basepath = argv[1];
- realpath = basepath;
- for (a = 2; a < argc; a++) {
- char *endptr;
- char *arg = argv[a];
- if (arg[0] == ':') {
- realpath = arg + 1;
- } else {
- if (arg[0] == '-') {
- arg++;
- skip_test = strtoul(arg, &endptr, 10);
- } else {
- select_test = strtoul(arg, &endptr, 10);
- }
- if (arg[0] == '\0' || *endptr != '\0') {
- fprintf(stderr, "invalid number: '%s'\n", arg);
- return 1;
- }
- }
- }
- assert(strlen(basepath) < 512);
- assert(strlen(realpath) < 512);
- if (basepath[0] != '/') {
- fprintf(stderr, "testdir must be an absolute path\n");
- return 1;
- }
-
- sprintf(testfile, "%s/testfile", basepath);
- sprintf(testfile2, "%s/testfile2", basepath);
- sprintf(testdir, "%s/testdir", basepath);
- sprintf(testdir2, "%s/testdir2", basepath);
- sprintf(subfile, "%s/subfile", testdir2);
-
- sprintf(testfile_r, "%s/testfile", realpath);
- sprintf(testfile2_r, "%s/testfile2", realpath);
- sprintf(testdir_r, "%s/testdir", realpath);
- sprintf(testdir2_r, "%s/testdir2", realpath);
- sprintf(subfile_r, "%s/subfile", testdir2_r);
-
- is_root = (geteuid() == 0);
-
- err += test_create();
- err += test_create_unlink();
- err += test_mknod();
- err += test_symlink();
- err += test_link();
- err += test_link2();
- err += test_mkfifo();
- err += test_mkdir();
- err += test_rename_file();
- err += test_rename_dir();
- err += test_utime();
- err += test_truncate(0);
- err += test_truncate(testdatalen / 2);
- err += test_truncate(testdatalen);
- err += test_truncate(testdatalen + 100);
- err += test_ftruncate(0, 0600);
- err += test_ftruncate(testdatalen / 2, 0600);
- err += test_ftruncate(testdatalen, 0600);
- err += test_ftruncate(testdatalen + 100, 0600);
- err += test_ftruncate(0, 0400);
- err += test_ftruncate(0, 0200);
- err += test_ftruncate(0, 0000);
- err += test_open(0, O_RDONLY, 0);
- err += test_open(1, O_RDONLY, 0);
- err += test_open(1, O_RDWR, 0);
- err += test_open(1, O_WRONLY, 0);
- err += test_open(0, O_RDWR | O_CREAT, 0600);
- err += test_open(1, O_RDWR | O_CREAT, 0600);
- err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
- err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
- err += test_open(0, O_RDONLY | O_CREAT, 0600);
- err += test_open(0, O_RDONLY | O_CREAT, 0400);
- err += test_open(0, O_RDONLY | O_CREAT, 0200);
- err += test_open(0, O_RDONLY | O_CREAT, 0000);
- err += test_open(0, O_WRONLY | O_CREAT, 0600);
- err += test_open(0, O_WRONLY | O_CREAT, 0400);
- err += test_open(0, O_WRONLY | O_CREAT, 0200);
- err += test_open(0, O_WRONLY | O_CREAT, 0000);
- err += test_open(0, O_RDWR | O_CREAT, 0400);
- err += test_open(0, O_RDWR | O_CREAT, 0200);
- err += test_open(0, O_RDWR | O_CREAT, 0000);
- err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
- err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
- err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
- err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
- err += test_open_acc(O_RDONLY, 0600, 0);
- err += test_open_acc(O_WRONLY, 0600, 0);
- err += test_open_acc(O_RDWR, 0600, 0);
- err += test_open_acc(O_RDONLY, 0400, 0);
- err += test_open_acc(O_WRONLY, 0200, 0);
- if(!is_root) {
- err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
- err += test_open_acc(O_WRONLY, 0400, EACCES);
- err += test_open_acc(O_RDWR, 0400, EACCES);
- err += test_open_acc(O_RDONLY, 0200, EACCES);
- err += test_open_acc(O_RDWR, 0200, EACCES);
- err += test_open_acc(O_RDONLY, 0000, EACCES);
- err += test_open_acc(O_WRONLY, 0000, EACCES);
- err += test_open_acc(O_RDWR, 0000, EACCES);
- }
- err += test_create_ro_dir(O_CREAT);
- err += test_create_ro_dir(O_CREAT | O_EXCL);
- err += test_create_ro_dir(O_CREAT | O_WRONLY);
- err += test_create_ro_dir(O_CREAT | O_TRUNC);
-
- unlink(testfile);
- unlink(testfile2);
- rmdir(testdir);
- rmdir(testdir2);
-
- if (err) {
- fprintf(stderr, "%i tests failed\n", -err);
- return 1;
- }
-
- return 0;
-}