diff options
Diffstat (limited to 'src/cmd/tests/libc')
-rw-r--r-- | src/cmd/tests/libc/esemaphore.c | 95 | ||||
-rw-r--r-- | src/cmd/tests/libc/setjmp.c | 31 | ||||
-rw-r--r-- | src/cmd/tests/libc/string.c | 124 |
3 files changed, 250 insertions, 0 deletions
diff --git a/src/cmd/tests/libc/esemaphore.c b/src/cmd/tests/libc/esemaphore.c new file mode 100644 index 0000000..f089f4f --- /dev/null +++ b/src/cmd/tests/libc/esemaphore.c @@ -0,0 +1,95 @@ +#include "../tests.h" +#include <camellia/flags.h> +#include <camellia/syscalls.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <esemaphore.h> + +static void odd(hid_t out, struct evil_sem *sem1, struct evil_sem *sem2) { + _sys_write(out, "1", 1, -1, 0); + esem_signal(sem1); + + esem_wait(sem2); + _sys_write(out, "3", 1, -1, 0); + esem_signal(sem1); + + esem_wait(sem2); + _sys_write(out, "5", 1, -1, 0); + esem_signal(sem1); +} + +static void even(hid_t out, struct evil_sem *sem1, struct evil_sem *sem2) { + esem_wait(sem1); + _sys_write(out, "2", 1, -1, 0); + esem_signal(sem2); + + esem_wait(sem1); + _sys_write(out, "4", 1, -1, 0); + esem_signal(sem2); + + esem_wait(sem1); + _sys_write(out, "6", 1, -1, 0); + esem_signal(sem2); +} + +static void test_semaphore(void) { + struct evil_sem *sem1, *sem2; + hid_t pipe[2]; + test(_sys_pipe(pipe, 0) >= 0); + + if (!fork()) { + sem1 = esem_new(0); + sem2 = esem_new(0); + test(sem1 && sem2); + if (!fork()) { + odd(pipe[1], sem1, sem2); + exit(69); + } else { + even(pipe[1], sem1, sem2); + test(_sys_await() == 69); + } + esem_free(sem1); + esem_free(sem2); + + _sys_write(pipe[1], "|", 1, -1, 0); + + sem1 = esem_new(0); + sem2 = esem_new(0); + test(sem1 && sem2); + if (!fork()) { + even(pipe[1], sem1, sem2); + exit(69); + } else { + odd(pipe[1], sem1, sem2); + test(_sys_await() == 69); + _sys_await(); + } + esem_free(sem1); + esem_free(sem2); + + _sys_filicide(); + exit(0); + } else { + close(pipe[1]); + + char buf[16]; + size_t pos = 0; + for (;;) { + int ret = _sys_read(pipe[0], buf + pos, sizeof(buf) - pos, 0); + if (ret < 0) break; + pos += ret; + } + buf[pos] = '\0'; // idc about the "potential" overflow + if (strcmp(buf, "123456|123456")) { + printf("%s\n", buf); + test_fail(); + } + + _sys_await(); + } +} + +void r_libc_esemaphore(void) { + run_test(test_semaphore); +} diff --git a/src/cmd/tests/libc/setjmp.c b/src/cmd/tests/libc/setjmp.c new file mode 100644 index 0000000..0dded9d --- /dev/null +++ b/src/cmd/tests/libc/setjmp.c @@ -0,0 +1,31 @@ +#include "../tests.h" +#include <stdbool.h> +#include <setjmp.h> + +static void test_setjmp(void) { + jmp_buf env; + volatile bool inner; + int val; + inner = false; + if (!(val = setjmp(env))) { + inner = true; + longjmp(env, 1234); + test(0); + } else { + test(val == 1234); + test(inner); + } + inner = false; + if (!(val = setjmp(env))) { + inner = true; + longjmp(env, 0); + test(0); + } else { + test(val == 1); + test(inner); + } +} + +void r_libc_setjmp(void) { + run_test(test_setjmp); +} diff --git a/src/cmd/tests/libc/string.c b/src/cmd/tests/libc/string.c new file mode 100644 index 0000000..6afe350 --- /dev/null +++ b/src/cmd/tests/libc/string.c @@ -0,0 +1,124 @@ +#include "../tests.h" +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +static void test_memcmp(void) { + test(0 == memcmp("some", "thing", 0)); + test(0 != memcmp("some", "thing", 1)); + test(0 != memcmp("some", "thing", 4)); + + test(0 == memcmp("test", "tennis", 0)); + test(0 == memcmp("test", "tennis", 1)); + test(0 == memcmp("test", "tennis", 2)); + test(0 != memcmp("test", "tennis", 3)); + test(0 != memcmp("test", "tennis", 4)); + test(0 != memcmp("test", "tennis", 5)); + + test(0 > memcmp("foo", "moo", 4)); + test(0 < memcmp("moo", "foo", 4)); + test(0 > memcmp("555", "654", 3)); + test(0 < memcmp("654", "555", 3)); +} + +static bool memall(const unsigned char *s, unsigned char c, size_t n) { + for (size_t i = 0; i < n; i++) + if (s[i] != c) return false; + return true; +} + +static void test_memset(void) { + const size_t buflen = 4096; + void *buf = malloc(buflen); + test(buf); + for (int i = 0; i < 257; i++) { + memset(buf, i, buflen); + test(memall(buf, i & 0xff, buflen)); + } + free(buf); +} + +static void test_memmove(void) { + const int partsize = 64; + char buf[partsize * 3]; + for (int i = 0; i < partsize * 2; i++) { + memset(buf, 0, sizeof buf); + for (int j = 0; j < partsize; j++) buf[i + j] = j; + memmove(buf + partsize, buf + i, partsize); + for (int j = 0; j < partsize; j++) test(buf[partsize + j] == j); + } +} + +static void test_strcmp(void) { + test(0 == strcmp("string", "string")); + test(0 > strcmp("str", "string")); + test(0 < strcmp("string", "str")); + + test(0 != strcmp("stress", "string")); + + test(0 != strncmp("abc", "ab", 3)); + test(0 == strncmp("abc", "ab", 2)); +} + +static void test_strtol(void) { + char *end; + test(1234 == strtol("1234", NULL, 10)); + test(1234 == strtol("+1234", NULL, 10)); + test(-1234 == strtol("-1234", NULL, 10)); + + test(1234 == strtol("1234", &end, 10)); + test(!strcmp("", end)); + test(1234 == strtol(" 1234hello", &end, 10)); + test(!strcmp("hello", end)); + + test(1234 == strtol(" 1234hello", &end, 0)); + test(!strcmp("hello", end)); + test(0xCAF3 == strtol(" 0xCaF3hello", &end, 0)); + test(!strcmp("hello", end)); + test(01234 == strtol(" 01234hello", &end, 0)); + test(!strcmp("hello", end)); +} + +static void test_strspn(void) { + test(0 == strspn("", "1234")); + test(0 == strspn("asdf", "1234")); + test(0 == strspn("a2df", "1234")); + test(2 == strspn("42df", "1234")); + test(4 == strspn("4211", "1234")); + + test(0 == strcspn("", "1234")); + test(4 == strcspn("asdf", "1234")); + test(1 == strcspn("a2df", "1234")); +} + +static void test_strtok(void) { + const char *sep = " \t"; + { + char line[] = "LINE TO BE SEPARATED"; + test(!strcmp(strtok(line, sep), "LINE")); + test(!strcmp(strtok(NULL, sep), "TO")); + test(!strcmp(strtok(NULL, sep), "BE")); + test(!strcmp(strtok(NULL, sep), "SEPARATED")); + for (int i = 0; i < 4; i++) + test(strtok(NULL, sep) == NULL); + } + { + char line[] = " LINE TO\tBE \t SEPARATED "; + test(!strcmp(strtok(line, sep), "LINE")); + test(!strcmp(strtok(NULL, sep), "TO")); + test(!strcmp(strtok(NULL, sep), "BE")); + test(!strcmp(strtok(NULL, sep), "SEPARATED")); + for (int i = 0; i < 4; i++) + test(strtok(NULL, sep) == NULL); + } +} + +void r_libc_string(void) { + run_test(test_memcmp); + run_test(test_memset); + run_test(test_memmove); + run_test(test_strcmp); + run_test(test_strtol); + run_test(test_strspn); + run_test(test_strtok); +} |