diff options
Diffstat (limited to 'test/test.c')
-rw-r--r-- | test/test.c | 1522 |
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; -} |