linux/arch/um/drivers/slirp_user.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
   3 * Licensed under the GPL.
   4 */
   5
   6#include <unistd.h>
   7#include <errno.h>
   8#include <string.h>
   9#include <sys/wait.h>
  10#include <net_user.h>
  11#include <os.h>
  12#include "slirp.h"
  13
  14static int slirp_user_init(void *data, void *dev)
  15{
  16        struct slirp_data *pri = data;
  17
  18        pri->dev = dev;
  19        return 0;
  20}
  21
  22struct slirp_pre_exec_data {
  23        int stdin;
  24        int stdout;
  25};
  26
  27static void slirp_pre_exec(void *arg)
  28{
  29        struct slirp_pre_exec_data *data = arg;
  30
  31        if (data->stdin != -1)
  32                dup2(data->stdin, 0);
  33        if (data->stdout != -1)
  34                dup2(data->stdout, 1);
  35}
  36
  37static int slirp_tramp(char **argv, int fd)
  38{
  39        struct slirp_pre_exec_data pe_data;
  40        int pid;
  41
  42        pe_data.stdin = fd;
  43        pe_data.stdout = fd;
  44        pid = run_helper(slirp_pre_exec, &pe_data, argv);
  45
  46        return pid;
  47}
  48
  49static int slirp_open(void *data)
  50{
  51        struct slirp_data *pri = data;
  52        int fds[2], pid, err;
  53
  54        err = os_pipe(fds, 1, 1);
  55        if (err)
  56                return err;
  57
  58        err = slirp_tramp(pri->argw.argv, fds[1]);
  59        if (err < 0) {
  60                printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err);
  61                goto out;
  62        }
  63        pid = err;
  64
  65        pri->slave = fds[1];
  66        pri->slip.pos = 0;
  67        pri->slip.esc = 0;
  68        pri->pid = err;
  69
  70        return fds[0];
  71out:
  72        close(fds[0]);
  73        close(fds[1]);
  74        return err;
  75}
  76
  77static void slirp_close(int fd, void *data)
  78{
  79        struct slirp_data *pri = data;
  80        int err;
  81
  82        close(fd);
  83        close(pri->slave);
  84
  85        pri->slave = -1;
  86
  87        if (pri->pid<1) {
  88                printk(UM_KERN_ERR "slirp_close: no child process to shut "
  89                       "down\n");
  90                return;
  91        }
  92
  93#if 0
  94        if (kill(pri->pid, SIGHUP)<0) {
  95                printk(UM_KERN_ERR "slirp_close: sending hangup to %d failed "
  96                       "(%d)\n", pri->pid, errno);
  97        }
  98#endif
  99        err = helper_wait(pri->pid);
 100        if (err < 0)
 101                return;
 102
 103        pri->pid = -1;
 104}
 105
 106int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
 107{
 108        return slip_proto_read(fd, buf, len, &pri->slip);
 109}
 110
 111int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
 112{
 113        return slip_proto_write(fd, buf, len, &pri->slip);
 114}
 115
 116const struct net_user_info slirp_user_info = {
 117        .init           = slirp_user_init,
 118        .open           = slirp_open,
 119        .close          = slirp_close,
 120        .remove         = NULL,
 121        .add_address    = NULL,
 122        .delete_address = NULL,
 123        .mtu            = BUF_SIZE,
 124        .max_packet     = BUF_SIZE,
 125};
 126