tests: add copy_file_range() to the syscall tests
authorNiels de Vos <ndevos@redhat.com>
Tue, 26 Jun 2018 19:40:43 +0000 (21:40 +0200)
committerNikolaus Rath <Nikolaus@rath.org>
Mon, 19 Nov 2018 12:33:56 +0000 (12:33 +0000)
test/test_syscalls.c

index 4e1dc07befbf2117e3d290d6681cd954f3f8f8ad..a281ae35018f3d08f6d4467062ca38dce2588b97 100644 (file)
@@ -1,3 +1,6 @@
+#define _GNU_SOURCE
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -711,6 +714,101 @@ fail:
        return -1;
 }
 
+#ifdef HAVE_COPY_FILE_RANGE
+static int test_copy_file_range(void)
+{
+       const char *data = testdata;
+       int datalen = testdatalen;
+       int err = 0;
+       int res;
+       int fd_in, fd_out;
+       off_t pos_in = 0, pos_out = 0;
+
+       start_test("copy_file_range");
+       unlink(testfile);
+       fd_in = open(testfile, O_CREAT | O_RDWR, 0644);
+       if (fd_in == -1) {
+               PERROR("creat");
+               return -1;
+       }
+       res = write(fd_in, data, datalen);
+       if (res == -1) {
+               PERROR("write");
+               close(fd_in);
+               return -1;
+       }
+       if (res != datalen) {
+               ERROR("write is short: %u instead of %u", res, datalen);
+               close(fd_in);
+               return -1;
+       }
+
+       unlink(testfile2);
+       fd_out = creat(testfile2, 0644);
+       if (fd_out == -1) {
+               PERROR("creat");
+               close(fd_in);
+               return -1;
+       }
+       res = copy_file_range(fd_in, &pos_in, fd_out, &pos_out, datalen, 0);
+       if (res == -1) {
+               PERROR("copy_file_range");
+               close(fd_in);
+               close(fd_out);
+               return -1;
+       }
+       if (res != datalen) {
+               ERROR("copy is short: %u instead of %u", res, datalen);
+               close(fd_in);
+               close(fd_out);
+               return -1;
+       }
+
+       res = close(fd_in);
+       if (res == -1) {
+               PERROR("close");
+               return -1;
+       }
+       res = close(fd_out);
+       if (res == -1) {
+               PERROR("close");
+               return -1;
+       }
+
+       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;
+       if (err)
+               return -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;
+}
+#else
+static int test_copy_file_range(void)
+{
+       return 0;
+}
+#endif
+
 static int test_utime(void)
 {
        struct utimbuf utm;
@@ -1792,6 +1890,7 @@ int main(int argc, char *argv[])
        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);
+       err += test_copy_file_range();
 
        unlink(testfile);
        unlink(testfile2);