arena: Connecting importers with sources
[akaros.git] / tests / childfdmap.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 <ros/syscall.h>
14 #include <parlib/parlib.h>
15
16 /* Test the childfdmap system call.
17  * Create a pipe, start the spawn, dup the pipes over fd 0 and 1, write
18  * to it, see that you get the same back.
19  */
20 char filename[512];
21 int main(int argc, char *argv[]) 
22
23         struct childfdmap childfdmap[3];
24         int ret;
25         int flag = 0;
26         int kid;
27         int talk[2];
28         char hi[3] = {0};
29         char *child_argv[3];
30
31         /* detect the child by the number of args. */
32         if (argc > 1) {
33                 read(0, hi, 3);
34                 assert(!strcmp(hi, "HI"));
35                 /* pass something else back */
36                 hi[0] = 'Y';
37                 hi[1] = 'O';
38                 hi[2] = '\0';
39                 write(1, hi, 3);
40                 exit(0);
41         }
42
43         if (pipe(talk) < 0) {
44                 perror("pipe");
45                 exit(1);
46         }
47         printd("pipe [%d, %d]\n", talk[0], talk[1]);
48
49         /* parent will read and write on talk[0], and the child does the same for
50          * talk[1].  internally, writing to talk 0 gets read on talk 1.  the child
51          * gets talk1 mapped for both stdin (fd 0) and stdout (fd 1). */
52         childfdmap[0].parentfd = talk[1];
53         childfdmap[0].childfd = 0;
54         childfdmap[1].parentfd = talk[1];
55         childfdmap[1].childfd = 1;
56
57         sprintf(filename, "/bin/%s", argv[0]);
58         child_argv[0] = filename;
59         child_argv[1] = "1"; /* dummy arg, signal so we know they're the child */
60         child_argv[2] = 0;
61
62         kid = sys_proc_create(filename, strlen(filename), child_argv, NULL, 0);
63         if (kid < 0) {
64                 perror("create failed");
65                 exit(1);
66         }
67
68         ret = syscall(SYS_dup_fds_to, kid, childfdmap, 2);
69         if (ret != 2) {
70                 perror("childfdmap faled");
71                 exit(2);
72         }
73
74         /* close the pipe endpoint that we duped in the child.  it doesn't matter
75          * for this test, but after the child exits, the pipe will still be open
76          * unless we close our side of it. */
77         close(talk[1]);
78
79         sys_proc_run(kid);
80
81         if (write(talk[0], "HI", 3) < 3) {
82                 perror("write HI");
83                 exit(3);
84         }
85
86         if (read(talk[0], hi, 3) < 3) {
87                 perror("read YO");
88                 exit(4);
89         }
90         assert(!strcmp(hi, "YO"));
91
92         printf("Passed\n");
93
94         return 0;
95 }