diff --git a/include/ft/all-tests.h b/include/ft/all-tests.h index 3eff9cf..fa62c2b 100644 --- a/include/ft/all-tests.h +++ b/include/ft/all-tests.h @@ -56,6 +56,8 @@ extern ft_test ft_time_functions; /* unistd */ extern ft_test ft_unistd_simple_write; extern ft_test ft_unistd_write_odd; +extern ft_test ft_unistd_simple_read; +extern ft_test ft_unistd_seek_patterns; /* fcntl */ extern ft_test ft_fcntl_open; diff --git a/include/ft/util.h b/include/ft/util.h index e88cfe0..5ee9653 100644 --- a/include/ft/util.h +++ b/include/ft/util.h @@ -29,6 +29,7 @@ extern bopti_image_t img_fbar_main; if(errno != 0) ft_log(t, "errno %d: %s\n", errno, strerror(errno)) /* Combination */ #define DO_E(var, expr, t, fmt) { \ + errno = 0; \ var = expr; \ ft_log(t, #expr " = " fmt "\n", var); \ SHOW_ERRNO(t); \ diff --git a/src/fcntl/open.c b/src/fcntl/open.c index dd955e9..1f9a338 100644 --- a/src/fcntl/open.c +++ b/src/fcntl/open.c @@ -1,7 +1,8 @@ #include #include -#include +#include +#include #include #include #include @@ -9,31 +10,23 @@ static void _ft_fcntl_open_switch(ft_test *t) { - char const *filename = "ft_open.txt"; int fd, rc; errno = 0; - fd = open(filename, O_RDONLY); - ft_log(t, "open(\"%s\", O_RDONLY) = %d\n", filename, fd); - if(fd == -1) - ft_log(t, "errno %d: %s\n", errno, strerror(errno)); + DO_E(fd, open("ft_open.txt", O_RDONLY), t, "%d"); ft_assert(t, fd == -1 && errno == ENOENT); if(fd != -1) close(fd); - fd = open(filename, O_RDWR | O_CREAT); - ft_log(t, "open(\"%s\", O_RDWR | O_CREAT) = %d\n", filename, fd); - if(fd == -1) - ft_log(t, "errno %d: %s\n", errno, strerror(errno)); + DO_E(fd, open("ft_open.txt", O_RDWR | O_CREAT), t, "%d"); ft_assert(t, fd >= 0); - if(fd != -1) - close(fd); + if(fd != -1) { + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); - rc = unlink(filename); - ft_log(t, "unlink(\"%s\") = %d\n", filename, rc); - if(rc == -1) - ft_log(t, "errno %d: %s\n", errno, strerror(errno)); - ft_assert(t, rc == 0); + DO_E(rc, unlink("ft_open.txt"), t, "%d"); + ft_assert(t, rc == 0); + } } static void _ft_fcntl_open(ft_test *t) diff --git a/src/main.c b/src/main.c index 3be8451..00fd6d9 100644 --- a/src/main.c +++ b/src/main.c @@ -86,6 +86,8 @@ ft_list headers_posix[] = { { "", (ft_test*[]){ &ft_unistd_simple_write, &ft_unistd_write_odd, + &ft_unistd_simple_read, + &ft_unistd_seek_patterns, NULL, }}, { NULL } diff --git a/src/unistd/files.c b/src/unistd/files.c index 2341c6f..357c3f9 100644 --- a/src/unistd/files.c +++ b/src/unistd/files.c @@ -3,9 +3,11 @@ #include #include +#include +#include + #include #include - #include #include @@ -26,7 +28,8 @@ static void _ft_unistd_simple_write_switch(ft_test *t) ft_assert(t, rc == 8); } - close(fd); + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); } static void _ft_unistd_simple_write(ft_test *t) @@ -54,7 +57,8 @@ static void _ft_unistd_write_odd_switch_1(ft_test *t) ft_assert(t, rc == 21); } - close(fd); + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); } static void _ft_unistd_write_odd_switch_2(ft_test *t) @@ -72,7 +76,8 @@ static void _ft_unistd_write_odd_switch_2(ft_test *t) ft_assert(t, rc == 22); } - close(fd); + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); } static void _ft_unistd_write_odd(ft_test *t) @@ -85,3 +90,157 @@ ft_test ft_unistd_write_odd = { .name = "Odd-length writes", .function = _ft_unistd_write_odd, }; + +static void _ft_unistd_simple_read_switch(ft_test *t) +{ + /* First we need to generate some stuff to read... */ + int fd, rc; + errno = 0; + + DO_E(fd, open("ft_read.txt", O_WRONLY | O_CREAT | O_TRUNC), t, "%d"); + ft_assert(t, fd >= 0); + + if(fd >= 0) { + DO_E(rc, write(fd, "_ft_unistd_simple_read", 22), t, "%d"); + ft_assert(t, rc == 22); + + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); + } + else return; + + /* Then actually read it */ + DO_E(fd, open("ft_read.txt", O_RDONLY), t, "%d"); + ft_assert(t, fd >= 0); + if(fd < 0) return; + + int fugue_fd = (int)fs_get_descriptor(fd)->data; + + ft_log(t, "[INFO] lseek(fd, 0, SEEK_CUR) = %ld\n", + lseek(fd, 0, SEEK_CUR)); + DO_E(rc, BFile_Size(fugue_fd), t, "%d"); + + char buffer[29] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + DO_E(rc, read(fd, buffer, 11), t, "%d"); + ft_assert(t, rc == 11); + ft_assert(t, !strcmp(buffer, "_ft_unistd_xxxxxxxxxxxxxxxxx")); + + ft_log(t, "[INFO] lseek(fd, 0, SEEK_CUR) = %ld\n", + lseek(fd, 0, SEEK_CUR)); + DO_E(rc, BFile_Size(fugue_fd), t, "%d"); + + DO_E(rc, read(fd, buffer + 11, 11), t, "%d"); + ft_assert(t, rc == 11); + ft_assert(t, !strcmp(buffer, "_ft_unistd_simple_readxxxxxx")); + + ft_log(t, "[INFO] lseek(fd, 0, SEEK_CUR) = %ld\n", + lseek(fd, 0, SEEK_CUR)); + DO_E(rc, BFile_Size(fugue_fd), t, "%d"); + + ft_log(t, "[INFO] lseek(fd, 4, SEEK_SET) = %ld\n", + lseek(fd, 4, SEEK_SET)); + ft_log(t, "[INFO] lseek(fd, 4, SEEK_END) = %ld\n", + lseek(fd, 4, SEEK_END)); + ft_log(t, "[INFO] lseek(fd, 0, SEEK_CUR) = %ld\n", + lseek(fd, 4, SEEK_CUR)); + + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); +} + +static void _ft_unistd_simple_read(ft_test *t) +{ + gint_world_switch(GINT_CALL(_ft_unistd_simple_read_switch, (void *)t)); +} + +ft_test ft_unistd_simple_read = { + .name = "Simple read", + .function = _ft_unistd_simple_read, +}; + +static void _ft_unistd_seek_patterns_switch(ft_test *t) +{ + /* Generate a basic file */ + int fd, rc; + errno = 0; + + DO_E(fd, open("ft_seek.txt", O_WRONLY | O_CREAT | O_TRUNC), t, "%d"); + ft_assert(t, fd >= 0); + + if(fd >= 0) { + DO_E(rc, write(fd, "_ft_unistd_seek_patterns", 24), t, "%d"); + ft_assert(t, rc == 24); + + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); + } + else return; + + DO_E(fd, open("ft_seek.txt", O_RDWR), t, "%d"); + ft_assert(t, fd >= 0); + if(fd < 0) return; + + int fugue_fd = (int)fs_get_descriptor(fd)->data; + + /* Read from the start */ + char str[32] = { 0 }; + DO_E(rc, read(fd, str, 8), t, "%d"); + ft_assert(t, rc == 8 && !strncmp(str, "_ft_unis", 8)); + DO_E(rc, read(fd, str, 4), t, "%d"); + ft_assert(t, rc == 4 && !strncmp(str, "td_sunis", 8)); + + /* Rewind */ + DO_E(rc, lseek(fd, 0, SEEK_SET), t, "%d"); + ft_assert(t, rc == 0); + DO_E(rc, read(fd, str, 24), t, "%d"); + ft_assert(t, rc == 24 && !strcmp(str, "_ft_unistd_seek_patterns")); + + /* Read from the middle */ + DO_E(rc, pread(fd, str, 8, (off_t)12), t, "%d"); + ft_assert(t, rc == 8 && !strncmp(str, "eek_patt", 8)); + + /* Write to the end */ + DO_E(rc, lseek(fd, -8, SEEK_END), t, "%d"); + ft_assert(t, rc == 16); + DO_E(rc, write(fd, "methods!", 8), t, "%d"); + ft_assert(t, rc == 8); + + /* Read again from the end */ + DO_E(rc, pread(fd, str, 8, (off_t)16), t, "%d"); + ft_assert(t, rc == 8 && !strncmp(str, "methods!", 8)); + + /* Play around with absolute seeking */ + DO_E(rc, lseek(fd, -4, SEEK_END), t, "%d"); + ft_assert(t, rc == 20); + DO_E(rc, lseek(fd, 0, SEEK_END), t, "%d"); + ft_assert(t, rc == BFile_Size(fugue_fd)); + DO_E(rc, lseek(fd, 8, SEEK_SET), t, "%d"); + ft_assert(t, rc == 8); + + /* Relative seeking */ + DO_E(rc, lseek(fd, -6, SEEK_CUR), t, "%d"); + ft_assert(t, rc == 2); + + /* Write in the middle */ + DO_E(rc, pwrite(fd, "@", 1, (off_t)3), t, "%d"); + ft_assert(t, rc == 1); + DO_E(rc, lseek(fd, 0, SEEK_SET), t, "%d"); + ft_assert(t, rc == 0); + memset(str, 0, sizeof str); + DO_E(rc, read(fd, str, 24), t, "%d"); + ft_assert(t, rc == 24 && !strcmp(str, "_ft@unistd_seek_methods!")); + + DO_E(rc, close(fd), t, "%d"); + ft_assert(t, rc == 0); +} + +static void _ft_unistd_seek_patterns(ft_test *t) +{ + gint_world_switch(GINT_CALL(_ft_unistd_seek_patterns_switch, + (void *)t)); +} + +ft_test ft_unistd_seek_patterns = { + .name = "Seek patterns", + .function = _ft_unistd_seek_patterns, +}; diff --git a/src/widgets/fbrowser.c b/src/widgets/fbrowser.c index 89e2e08..d48bc04 100644 --- a/src/widgets/fbrowser.c +++ b/src/widgets/fbrowser.c @@ -111,6 +111,7 @@ void fbrowser_set_headers(fbrowser *b, ft_list *headers, bool select) GINT_CALL(render_entries, 0 /* Overridden */, (void *)headers, 1)); flist_set_rows(b->headers, rows + 1); flist_select(b->headers, select ? 1 : 0); + flist_scroll_to(b->headers, 0); jscene *scene = jscene_owning(b); if(scene) jscene_set_focused_widget(scene, b->headers); @@ -130,6 +131,7 @@ void fbrowser_set_tests(fbrowser *b, ft_test **tests) GINT_CALL(render_entries, 0 /* Overridden */, (void *)tests, 0)); flist_set_rows(b->tests, rows); flist_select(b->tests, -1); + flist_scroll_to(b->tests, 0); b->data_tests = tests; fbar_set_tests(b->bar_right, tests);