slirp_user.c 2.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <sched.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "net_user.h"
#include "slirp.h"
15
#include "slip_common.h"
L
Linus Torvalds 已提交
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#include "os.h"

void slirp_user_init(void *data, void *dev)
{
	struct slirp_data *pri = data;

	pri->dev = dev;
}

struct slirp_pre_exec_data {
	int stdin;
	int stdout;
};

static void slirp_pre_exec(void *arg)
{
	struct slirp_pre_exec_data *data = arg;

	if(data->stdin != -1) dup2(data->stdin, 0);
	if(data->stdout != -1) dup2(data->stdout, 1);
}

static int slirp_tramp(char **argv, int fd)
{
	struct slirp_pre_exec_data pe_data;
	int pid;

	pe_data.stdin = fd;
	pe_data.stdout = fd;
	pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);

	return(pid);
}

static int slirp_open(void *data)
{
	struct slirp_data *pri = data;
53
	int fds[2], pid, err;
L
Linus Torvalds 已提交
54

55
	err = os_pipe(fds, 1, 1);
L
Linus Torvalds 已提交
56 57 58
	if(err)
		return(err);

59 60 61 62
	err = slirp_tramp(pri->argw.argv, fds[1]);
	if(err < 0){
		printk("slirp_tramp failed - errno = %d\n", -err);
		goto out;
L
Linus Torvalds 已提交
63
	}
64 65 66 67 68 69 70 71 72 73 74 75
	pid = err;

	pri->slave = fds[1];
	pri->slip.pos = 0;
	pri->slip.esc = 0;
	pri->pid = err;

	return(fds[0]);
out:
	os_close_file(fds[0]);
	os_close_file(fds[1]);
	return err;
L
Linus Torvalds 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
}

static void slirp_close(int fd, void *data)
{
	struct slirp_data *pri = data;
	int status,err;

	os_close_file(fd);
	os_close_file(pri->slave);

	pri->slave = -1;

	if(pri->pid<1) {
		printk("slirp_close: no child process to shut down\n");
		return;
	}

#if 0
	if(kill(pri->pid, SIGHUP)<0) {
		printk("slirp_close: sending hangup to %d failed (%d)\n",
			pri->pid, errno);
	}
#endif

	CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
	if(err < 0) {
		printk("slirp_close: waitpid returned %d\n", errno);
		return;
	}

	if(err == 0) {
		printk("slirp_close: process %d has not exited\n");
		return;
	}

	pri->pid = -1;
}

int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
{
116
	return slip_proto_read(fd, buf, len, &pri->slip);
L
Linus Torvalds 已提交
117 118 119 120
}

int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
{
121
	return slip_proto_write(fd, buf, len, &pri->slip);
L
Linus Torvalds 已提交
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
}

static int slirp_set_mtu(int mtu, void *data)
{
	return(mtu);
}

struct net_user_info slirp_user_info = {
	.init		= slirp_user_init,
	.open		= slirp_open,
	.close	 	= slirp_close,
	.remove	 	= NULL,
	.set_mtu	= slirp_set_mtu,
	.add_address	= NULL,
	.delete_address = NULL,
	.max_packet	= BUF_SIZE
};