Fix dup() of 9ns FDs
[akaros.git] / user / utest / file-posix.c
1 #define _LARGEFILE64_SOURCE /* needed to use lseek64 */
2
3 #include <stdio.h> 
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <parlib/arch/arch.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <dirent.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <parlib/parlib.h>
14
15 #include <utest/utest.h>
16
17 TEST_SUITE("FILE POSIX");
18
19 /* <--- Begin definition of test cases ---> */
20
21 bool test_openat(void)
22 {
23         int dfd = open("/dir1", O_RDONLY);
24         UT_ASSERT(dfd >= 0);
25
26         int ffd = openat(dfd, "f1.txt", O_RDWR);
27         UT_ASSERT(ffd >= 0, close(dfd));
28
29         close(ffd);
30         close(dfd);
31         return TRUE;
32 }
33
34 /* This tests opening a lot of files, enough to grow our file/chan table, then
35  * forking/spawning with DUP_FGRP.  It caused a panic at one point. */
36 bool test_open_lots_and_spawn(void)
37 {
38         char *p_argv[] = {0, 0, 0};
39         char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
40         #define NR_LOOPS 128
41         int fd[NR_LOOPS];
42         int pid;
43         const char *filename = "/bin/hello";
44
45         /* the kernel-internal number is 32 at the moment. */
46         for (int i = 0; i < NR_LOOPS; i++) {
47                 fd[i] = open("hello.txt", O_RDONLY);
48                 UT_ASSERT(fd[i] >= 0);
49         }
50         pid = sys_proc_create(filename, strlen(filename), p_argv, p_envp,
51                               PROC_DUP_FGRP);
52         UT_ASSERT(pid > 0);
53         sys_proc_destroy(pid, 0);
54         for (int i = 0; i < NR_LOOPS; i++)
55                 close(fd[i]);
56         return TRUE;
57 }
58
59 bool test_pipe_dup2(void)
60 {
61         int pipefd[2];
62         int ret;
63
64         ret = pipe(pipefd);
65         UT_ASSERT(!ret);
66         ret = dup2(pipefd[0], 100);
67         UT_ASSERT(ret == 100);
68         ret = close(100);
69         UT_ASSERT(!ret);
70         ret = close(pipefd[0]);
71         UT_ASSERT(!ret);
72         ret = close(pipefd[1]);
73         UT_ASSERT(!ret);
74         return TRUE;
75 }
76
77 /* <--- End definition of test cases ---> */
78
79 struct utest utests[] = {
80         UTEST_REG(openat),
81         UTEST_REG(open_lots_and_spawn),
82         UTEST_REG(pipe_dup2),
83 };
84 int num_utests = sizeof(utests) / sizeof(struct utest);
85
86 int main(int argc, char *argv[])
87 {
88         // Run test suite passing it all the args as whitelist of what tests to run.
89         char **whitelist = &argv[1];
90         int whitelist_len = argc - 1;
91         RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
92 }