| #define _LARGEFILE64_SOURCE /* needed to use lseek64 */ | 
 |  | 
 | #include <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; | 
 | } |