akaros/tests/childfdmap.c
<<
>>
Prefs
   1#define _LARGEFILE64_SOURCE /* needed to use lseek64 */
   2
   3#include <parlib/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 */
  20char filename[512];
  21int 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
  50         * for talk[1].  internally, writing to talk 0 gets read on talk 1.  the
  51         * child 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
  75         * matter for this test, but after the child exits, the pipe will still
  76         * be open 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}
  96