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