On Tue, Feb 11, 2014 at 05:01:41PM +0100, Miklos Szeredi wrote:
> On Mon, Feb 10, 2014 at 09:51:45PM +1100, Dave Chinner wrote:

> > Miklos, can you please write an xfstest for this new API? That way
> > we can verify that the behaviour is as documented, and we can ensure
> > that when we implement it on other filesystems it works exactly the
> > same on all filesystems?

This is a standalone testprog, but I guess it's trivial to integrate into
xfstests.

Please let me know what you think.

Thanks,
Miklos
----

#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 testname[256];
static char testdata[] = "abcdefghijklmnopqrstuvwxyz";
static char testdata2[] = "1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
static const char *testdir_files[] = { "f1", "f2", NULL};
static const char *testdir_files2[] = { "f3", "f4", "f5", NULL};
static const char *testdir_empty[] = { NULL};
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 swap(a, b) \
        do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)

#define MAX_ENTRIES 1024

static void test_perror(const char *func, const char *msg)
{
        printf("%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;
        printf("%s %s() - ", testname, func);
        va_start(ap, msg);
        vfprintf(stdout, msg, ap);
        va_end(ap);
        fprintf(stdout, "\n");
}

static void success(void)
{
        printf("%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 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 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 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 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 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 = open(path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 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 void cleanup_one(const char *path)
{
        int res;

        res = unlink(path);
        if (res == -1 && errno != ENOENT) {
                res = rmdir(path);
                if (res == -1) {
                        DIR *dp = opendir(path);
                        if (dp != NULL) {
                                int fd = dirfd(dp);
                                while (1) {
                                        struct dirent *de = readdir(dp);
                                        if (de == NULL)
                                                break;
                                        res = unlinkat(fd, de->d_name, 0);
                                        if (res == -1) {
                                                unlinkat(fd, de->d_name,
                                                         AT_REMOVEDIR);
                                        }
                                }
                                closedir(dp);
                                rmdir(path);
                        }
                }
        }
}

static void cleanup(void)
{
        cleanup_one(testfile);
        cleanup_one(testfile2);
        cleanup_one(testdir);
        cleanup_one(testdir2);
}

#define SYS_renameat2 316
#define RENAME_NOREPLACE        (1 << 0)        /* Don't overwrite target */
#define RENAME_EXCHANGE         (1 << 1)        /* Exchange source and dest */

static int sys_renameat2(int dfd1, const char *path1,
                         int dfd2, const char *path2,
                         unsigned int flags)
{
        return syscall(SYS_renameat2, dfd1, path1, dfd2, path2, flags);
}

static const char *type_name(int type, int empty)
{
        switch (type) {
        case S_IFREG:
                return "REG ";
        case S_IFLNK:
                return "LNK ";
        case S_IFDIR:
                if (empty)
                        return "DIR-";
                else
                        return "DIR+";
        case 0:
                return "-   ";
        default:
                return "????";
        }
}

static int check_any(const char *path, int type, void *data, int data_len)
{
        int res;
        char buf[1024];

        if (type) {
                res = check_type(path, type);
                if (res == -1)
                        return -1;

        }

        switch (type) {
        case S_IFDIR:
                res = check_mode(path, 0755);
                if (res == -1)
                        return -1;
                res = check_dir_contents(path, data);
                if (res == -1)
                        return -1;
                res = cleanup_dir(path, data, 0);
                if (res == -1)
                        return -1;
                res = rmdir(path);
                if (res == -1)
                        return -1;
                break;

        case S_IFREG:
                res = check_mode(path, 0644);
                if (res == -1)
                        return -1;
                res = check_nlink(path, 1);
                if (res == -1)
                        return -1;
                res = check_size(path, data_len);
                if (res == -1)
                        return -1;
                res = check_data(path, data, 0, data_len);
                if (res == -1)
                        return -1;
                res = unlink(path);
                if (res == -1) {
                        PERROR("unlink");
                        return -1;
                }
                break;

        case S_IFLNK:
                res = check_mode(path, 0777);
                if (res == -1)
                        return -1;
                res = readlink(path, buf, sizeof(buf));
                if (res == -1) {
                        PERROR("readlink");
                        return -1;
                }
                if (res != data_len) {
                        ERROR("short readlink: %u instead of %u", res,
                              data_len);
                        return -1;
                }
                if (memcmp(buf, data, data_len) != 0) {
                        ERROR("link mismatch");
                        return -1;
                }
                res = unlink(path);
                if (res == -1) {
                        PERROR("unlink");
                        return -1;
                }
                break;
        }

        res = check_nonexist(path);
        if (res == -1)
                return -1;

        return 0;
}

static int create_any(const char *path, int type, void *data, int data_len)
{
        int res;

        switch (type) {
        case S_IFREG:
                res = create_file(path, data, data_len);
                break;
        case S_IFLNK:
                res = symlink(data, path);
                if (res == -1)
                        PERROR("symlink");
                break;
        case S_IFDIR:
                res = create_dir(path, data);
                break;
        case 0:
                res = check_nonexist(path);
                break;
        }
        return res;
}

static const char *rename_flag_name(unsigned int flags)
{
        switch (flags) {
        case 0:
                return "(none)";
        case RENAME_NOREPLACE:
                return "(NOREPLACE)";
        case RENAME_EXCHANGE:
                return "(EXCHANGE)";
        case RENAME_NOREPLACE | RENAME_EXCHANGE:
                return "(NOREPLACE | EXCHANGE)";
        default:
                return "????";
        }
}

static int test_rename(unsigned int flags, int src_type, int src_empty,
                       int dst_type, int dst_empty, int err)
{
        int res;
        const char *src = NULL;
        const char *dst = NULL;
        void *src_data = NULL;
        void *dst_data = NULL;
        int src_datalen = 0;
        int dst_datalen = 0;

        start_test("rename %-11s %s -> %s error: '%s'",
                   rename_flag_name(flags),
                   type_name(src_type, src_empty), 
                   type_name(dst_type, dst_empty),
                   strerror(err));

        res = 0;
        if (src_type == S_IFDIR) {
                src_data = src_empty ? testdir_empty : testdir_files;
                src = testdir;
        } else {
                src = testfile;
                src_data = testdata;
                src_datalen = testdatalen;
        }
        if (dst_type == S_IFDIR) {
                dst = testdir2;
                dst_data = dst_empty ? testdir_empty : testdir_files2;
        } else {
                dst = testfile2;
                dst_data = testdata2;
                dst_datalen = testdata2len;
        }

        res = create_any(src, src_type, src_data, src_datalen);
        if (res == -1)
                goto cleanup;
        res = create_any(dst, dst_type, dst_data, dst_datalen);
        if (res == -1)
                goto cleanup;

        res = sys_renameat2(AT_FDCWD, src, AT_FDCWD, dst, flags);
        if (res == 0) {
                if (err) {
                        ERROR("renameat2 should have failed");
                        res = -1;
                        goto cleanup;
                }
                if (!(flags & RENAME_EXCHANGE)) {
                        dst_type = src_type;
                        dst_data = src_data;
                        dst_datalen = src_datalen;
                        src_type = 0;
                        src_data = NULL;
                        src_datalen = 0;
                } else {
                        swap(src_type, dst_type);
                        swap(src_data, dst_data);
                        swap(dst_datalen, src_datalen);
                }
        } else {
                if (errno == ENOSYS || errno == EINVAL) {
                        success(); /* not supported, most likely */
                        res = 0;
                        goto cleanup;
                }
                if (err != errno) {
                        PERROR("wrong errno");
                        res = -1;
                        goto cleanup;
                }
        }

        res = check_any(src, src_type, src_data, src_datalen);
        if (res == -1)
                goto cleanup;
        res = check_any(dst, dst_type, dst_data, dst_datalen);
        if (res == -1)
                goto cleanup;

        success();
        return 0;

cleanup:
        cleanup();
        return res;
}

static int test_renames(void)
{
        int err = 0;

        err += test_rename(0, 0, 0, S_IFREG, 0, ENOENT);
        err += test_rename(0, 0, 0, S_IFLNK, 0, ENOENT);
        err += test_rename(0, 0, 0, S_IFDIR, 0, ENOENT);
        err += test_rename(0, 0, 0, S_IFDIR, 1, ENOENT);
        err += test_rename(0, 0, 0, 0, 0, ENOENT);

        err += test_rename(0, S_IFREG, 0, S_IFREG, 0, 0);
        err += test_rename(0, S_IFREG, 0, S_IFLNK, 0, 0);
        err += test_rename(0, S_IFREG, 0, S_IFDIR, 0, EISDIR);
        err += test_rename(0, S_IFREG, 0, S_IFDIR, 1, EISDIR);
        err += test_rename(0, S_IFREG, 0, 0, 0, 0);

        err += test_rename(0, S_IFLNK, 0, S_IFREG, 0, 0);
        err += test_rename(0, S_IFLNK, 0, S_IFLNK, 0, 0);
        err += test_rename(0, S_IFLNK, 0, S_IFDIR, 0, EISDIR);
        err += test_rename(0, S_IFLNK, 0, S_IFDIR, 1, EISDIR);
        err += test_rename(0, S_IFLNK, 0, 0, 0, 0);

        err += test_rename(0, S_IFDIR, 0, S_IFREG, 0, ENOTDIR);
        err += test_rename(0, S_IFDIR, 0, S_IFLNK, 0, ENOTDIR);
        err += test_rename(0, S_IFDIR, 0, S_IFDIR, 0, ENOTEMPTY);
        err += test_rename(0, S_IFDIR, 0, S_IFDIR, 1, 0);
        err += test_rename(0, S_IFDIR, 0, 0, 0, 0);

        err += test_rename(0, S_IFDIR, 1, S_IFREG, 0, ENOTDIR);
        err += test_rename(0, S_IFDIR, 1, S_IFLNK, 0, ENOTDIR);
        err += test_rename(0, S_IFDIR, 1, S_IFDIR, 0, ENOTEMPTY);
        err += test_rename(0, S_IFDIR, 1, S_IFDIR, 1, 0);
        err += test_rename(0, S_IFDIR, 1, 0, 0, 0);

        err += test_rename(RENAME_NOREPLACE, 0, 0, S_IFREG, 0, ENOENT);
        err += test_rename(RENAME_NOREPLACE, 0, 0, S_IFLNK, 0, ENOENT);
        err += test_rename(RENAME_NOREPLACE, 0, 0, S_IFDIR, 0, ENOENT);
        err += test_rename(RENAME_NOREPLACE, 0, 0, S_IFDIR, 1, ENOENT);
        err += test_rename(RENAME_NOREPLACE, 0, 0, 0, 0, ENOENT);

        err += test_rename(RENAME_NOREPLACE, S_IFREG, 0, S_IFREG, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFREG, 0, S_IFLNK, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFREG, 0, S_IFDIR, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFREG, 0, S_IFDIR, 1, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFREG, 0, 0, 0, 0);

        err += test_rename(RENAME_NOREPLACE, S_IFLNK, 0, S_IFREG, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFLNK, 0, S_IFLNK, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFLNK, 0, S_IFDIR, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFLNK, 0, S_IFDIR, 1, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFLNK, 0, 0, 0, 0);

        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 0, S_IFREG, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 0, S_IFLNK, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 0, S_IFDIR, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 0, S_IFDIR, 1, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 0, 0, 0, 0);

        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 1, S_IFREG, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 1, S_IFLNK, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 1, S_IFDIR, 0, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 1, S_IFDIR, 1, EEXIST);
        err += test_rename(RENAME_NOREPLACE, S_IFDIR, 1, 0, 0, 0);


        err += test_rename(RENAME_EXCHANGE, 0, 0, S_IFREG, 0, ENOENT);
        err += test_rename(RENAME_EXCHANGE, 0, 0, S_IFLNK, 0, ENOENT);
        err += test_rename(RENAME_EXCHANGE, 0, 0, S_IFDIR, 0, ENOENT);
        err += test_rename(RENAME_EXCHANGE, 0, 0, S_IFDIR, 1, ENOENT);
        err += test_rename(RENAME_EXCHANGE, 0, 0, 0, 0, ENOENT);

        err += test_rename(RENAME_EXCHANGE, S_IFREG, 0, S_IFREG, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFREG, 0, S_IFLNK, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFREG, 0, S_IFDIR, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFREG, 0, S_IFDIR, 1, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFREG, 0, 0, 0, ENOENT);

        err += test_rename(RENAME_EXCHANGE, S_IFLNK, 0, S_IFREG, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFLNK, 0, S_IFLNK, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFLNK, 0, S_IFDIR, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFLNK, 0, S_IFDIR, 1, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFLNK, 0, 0, 0, ENOENT);

        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 0, S_IFREG, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 0, S_IFLNK, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 0, S_IFDIR, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 0, S_IFDIR, 1, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 0, 0, 0, ENOENT);

        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 1, S_IFREG, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 1, S_IFLNK, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 1, S_IFDIR, 0, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 1, S_IFDIR, 1, 0);
        err += test_rename(RENAME_EXCHANGE, S_IFDIR, 1, 0, 0, ENOENT);

        err += test_rename(RENAME_NOREPLACE | RENAME_EXCHANGE,
                           S_IFREG, 0, S_IFREG, 0, EINVAL);

        return err;
}

int main(int argc, char *argv[])
{
        const char *basepath;
        int err = 0;
        int res;

        umask(0);
        if (argc != 2) {
                fprintf(stderr, "usage: %s testdir\n", argv[0]);
                return 1;
        }
        basepath = argv[1];
        assert(strlen(basepath) < 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);

        if (check_nonexist(testfile) == -1 ||
            check_nonexist(testfile2) == -1 ||
            check_nonexist(testdir) == -1 ||
            check_nonexist(testdir2) == -1)
                return 1;

        err += test_renames();

        res = mkdir(testdir, 0755);
        if (res == -1) {
                perror(testdir);
                return 1;
        }
        res = mkdir(testdir2, 0755);
        if (res == -1) {
                perror(testdir2);
                return 1;
        }
        printf("------- Doing cross-directory renames...\n");

        sprintf(testfile, "%s/testdir/subfile", basepath);
        sprintf(testdir, "%s/testdir/subdir", basepath);
        sprintf(testfile2, "%s/testdir2/subfile2", basepath);
        sprintf(testdir2, "%s/testdir2/subdir2", basepath);

        err += test_renames();

        sprintf(testdir, "%s/testdir", basepath);
        sprintf(testdir2, "%s/testdir2", basepath);
        cleanup();

        if (err) {
                fprintf(stderr, "%i tests failed\n", -err);
                return 1;
        }

        return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to