| #define _LARGEFILE64_SOURCE /* needed to use lseek64 */ |
| |
| #include <parlib/stdio.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <parlib/arch/arch.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <dirent.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <ros/syscall.h> |
| #include <parlib/parlib.h> |
| |
| /* Test the childfdmap system call. |
| * Create a pipe, start the spawn, dup the pipes over fd 0 and 1, write |
| * to it, see that you get the same back. |
| */ |
| char filename[512]; |
| int main(int argc, char *argv[]) |
| { |
| struct childfdmap childfdmap[3]; |
| int ret; |
| int flag = 0; |
| int kid; |
| int talk[2]; |
| char hi[3] = {0}; |
| char *child_argv[3]; |
| |
| /* detect the child by the number of args. */ |
| if (argc > 1) { |
| read(0, hi, 3); |
| assert(!strcmp(hi, "HI")); |
| /* pass something else back */ |
| hi[0] = 'Y'; |
| hi[1] = 'O'; |
| hi[2] = '\0'; |
| write(1, hi, 3); |
| exit(0); |
| } |
| |
| if (pipe(talk) < 0) { |
| perror("pipe"); |
| exit(1); |
| } |
| printd("pipe [%d, %d]\n", talk[0], talk[1]); |
| |
| /* parent will read and write on talk[0], and the child does the same |
| * for talk[1]. internally, writing to talk 0 gets read on talk 1. the |
| * child gets talk1 mapped for both stdin (fd 0) and stdout (fd 1). */ |
| childfdmap[0].parentfd = talk[1]; |
| childfdmap[0].childfd = 0; |
| childfdmap[1].parentfd = talk[1]; |
| childfdmap[1].childfd = 1; |
| |
| sprintf(filename, "/bin/%s", argv[0]); |
| child_argv[0] = filename; |
| child_argv[1] = "1"; /* dummy arg, signal so we know they're the child*/ |
| child_argv[2] = 0; |
| |
| kid = sys_proc_create(filename, strlen(filename), child_argv, NULL, 0); |
| if (kid < 0) { |
| perror("create failed"); |
| exit(1); |
| } |
| |
| ret = syscall(SYS_dup_fds_to, kid, childfdmap, 2); |
| if (ret != 2) { |
| perror("childfdmap faled"); |
| exit(2); |
| } |
| |
| /* close the pipe endpoint that we duped in the child. it doesn't |
| * matter for this test, but after the child exits, the pipe will still |
| * be open unless we close our side of it. */ |
| close(talk[1]); |
| |
| sys_proc_run(kid); |
| |
| if (write(talk[0], "HI", 3) < 3) { |
| perror("write HI"); |
| exit(3); |
| } |
| |
| if (read(talk[0], hi, 3) < 3) { |
| perror("read YO"); |
| exit(4); |
| } |
| assert(!strcmp(hi, "YO")); |
| |
| printf("Passed\n"); |
| |
| return 0; |
| } |