diff -Naur -X exclude-files ac_cur/arch/um/drivers/ethertap_user.c ac/arch/um/drivers/ethertap_user.c --- ac_cur/arch/um/drivers/ethertap_user.c Tue Oct 30 18:27:12 2001 +++ ac/arch/um/drivers/ethertap_user.c Sat Nov 3 00:02:29 2001 @@ -37,6 +37,7 @@ int control_remote; int control_me; int err; + char *output; }; struct addr_change { @@ -44,47 +45,43 @@ unsigned char addr[4]; }; -static void etap_open_addr(unsigned char *addr, void *arg) +static void etap_change(int op, unsigned char *addr, int fd) { - int fd = *((int *) arg); struct addr_change change; + char *output; - change.what = ADD_ADDR; + change.what = op; memcpy(change.addr, addr, sizeof(change.addr)); if(write(fd, &change, sizeof(change)) != sizeof(change)) - printk("etap_add_addr - request failed, errno = %d\n", + printk("etap_change - request failed, errno = %d\n", errno); + if(!read_output(fd, &output)) printk("%s", output); } -static void etap_close_addr(unsigned char *addr, void *arg) +static void etap_open_addr(unsigned char *addr, void *arg) { - int fd = *((int *) arg); - struct addr_change change; + etap_change(ADD_ADDR, addr, *((int *) arg)); +} - change.what = DEL_ADDR; - memcpy(change.addr, addr, sizeof(change.addr)); - if(write(fd, &change, sizeof(change)) != sizeof(change)) - printk("etap_close_addr - request failed, errno = %d\n", - errno); +static void etap_close_addr(unsigned char *addr, void *arg) +{ + etap_change(DEL_ADDR, addr, *((int *) arg)); } static void etap_tramp(void *arg) { struct etap_open_data *data = arg; - int pid, status, n; + int pid, status; char version_buf[sizeof("nnnnn\0")]; char data_fd_buf[sizeof("nnnnnn\0")]; - char control_fd_buf[sizeof("nnnnnn\0")]; - char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")], c; + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; char *setup_args[] = { "uml_net", version_buf, "ethertap", data->name, - data_fd_buf, control_fd_buf, gate_buf, NULL }; + data_fd_buf, gate_buf, NULL }; char *nosetup_args[] = { "uml_net", version_buf, "ethertap", - data->name, data_fd_buf, control_fd_buf, - NULL }; - char **args; + data->name, data_fd_buf, NULL }; + char **args, c; sprintf(data_fd_buf, "%d", data->data_remote); - sprintf(control_fd_buf, "%d", data->control_remote); sprintf(version_buf, "%d", UML_NET_VERSION); if(data->gate != NULL){ strcpy(gate_buf, data->gate); @@ -93,30 +90,34 @@ else args = nosetup_args; data->err = 0; if((pid = fork()) == 0){ - char zero = 0; /* XXX Not necessary */ - + dup2(data->control_remote, 1); close(data->data_me); close(data->control_me); execvp(args[0], args); printk("Exec of '%s' failed - errno = %d\n", args[0], errno); - write(data->control_remote, &zero, sizeof(zero)); - exit(errno); + exit(1); } else if(pid < 0) data->err = errno; close(data->data_remote); close(data->control_remote); - n = read(data->control_me, &c, sizeof(c)); - if(n != sizeof(c)){ - printk("etap_open - failed to read response from helper : " - "return = %d, errno = %d\n", n, errno); + if(read(data->control_me, &c, sizeof(c)) != sizeof(c)){ + printk("etap_tramp : read of status failed, errno = %d\n", + errno); + data->err = EINVAL; + return; + } + if(c != 1){ + printk("etap_tramp : uml_net failed\n"); + data->err = EINVAL; if(waitpid(pid, &status, 0) < 0) data->err = errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){ printk("uml_net didn't exit with status 1\n"); - data->err = EINVAL; } - else data->err = EINVAL; + return; } - else if(c != 1) data->err = EINVAL; + data->output = NULL; + if(read_output(data->control_me, &data->output)) + data->err = EINVAL; } static int etap_open(void *data) @@ -146,6 +147,10 @@ tap_data.gate = pri->gate_addr; tracing_cb(etap_tramp, &tap_data); + if(tap_data.output){ + printk("%s", tap_data.output); + kfree(tap_data.output); + } if(tap_data.err != 0){ printk("etap_tramp failed - errno = %d\n", tap_data.err); return(-tap_data.err); @@ -164,7 +169,9 @@ close(fd); shutdown(pri->data_fd, SHUT_RDWR); close(pri->data_fd); + pri->data_fd = -1; close(pri->control_fd); + pri->control_fd = -1; } int etap_user_read(int fd, void *buf, int len, struct ethertap_data *pri) diff -Naur -X exclude-files ac_cur/arch/um/drivers/net_user.c ac/arch/um/drivers/net_user.c --- ac_cur/arch/um/drivers/net_user.c Tue Oct 30 18:27:12 2001 +++ ac/arch/um/drivers/net_user.c Sat Nov 3 00:02:29 2001 @@ -4,9 +4,11 @@ */ #include +#include #include #include #include "user.h" +#include "user_util.h" #include "net_user.h" int tap_open_common(void *dev, int hw_setup, char *gate_addr) @@ -49,6 +51,28 @@ ether[0] = 0xfe; ether[1] = 0xfd; set_ether_mac(dev, ether); + } + return(0); +} + +int read_output(int fd, char **output_out) +{ + int n; + + if(read(fd, &n, sizeof(n)) != sizeof(n)){ + printk("read_output - read of length failed, errno = %d\n", + errno); + return(-1); + } + if((*output_out = um_kmalloc(n)) == NULL){ + printk("read_output - kmalloc failed\n"); + return(-1); + } + if(read(fd, *output_out, n) != n){ + printk("read_output - read of data failed, errno = %d\n", + errno); + kfree(*output_out); + return(-1); } return(0); } diff -Naur -X exclude-files ac_cur/arch/um/drivers/net_user.h ac/arch/um/drivers/net_user.h --- ac_cur/arch/um/drivers/net_user.h Tue Oct 30 18:27:12 2001 +++ ac/arch/um/drivers/net_user.h Sat Nov 3 00:02:29 2001 @@ -6,7 +6,7 @@ #define ETH_HEADER_OTHER (14) #define ETH_MAX_PACKET (1500) -#define UML_NET_VERSION (2) +#define UML_NET_VERSION (3) struct net_user_info { void (*init)(void *, void *); @@ -28,6 +28,8 @@ extern void free_output_buffer(void *buffer); extern int tap_open_common(void *dev, int hw_setup, char *gate_addr); + +extern int read_output(int fd, char **output_out); #endif diff -Naur -X exclude-files ac_cur/arch/um/drivers/slip_user.c ac/arch/um/drivers/slip_user.c --- ac_cur/arch/um/drivers/slip_user.c Tue Oct 30 18:27:12 2001 +++ ac/arch/um/drivers/slip_user.c Sat Nov 3 00:02:29 2001 @@ -55,21 +55,32 @@ struct slip_tramp_data { char **args; int err; + char *output; }; void slip_tramp(void *arg) { struct slip_tramp_data *data = arg; char **argv = data->args; - int status, pid; + int status, pid, fds[2]; data->err = 0; + data->output = NULL; + if(pipe(fds) != 0){ + perror("slip_tramp : pipe failed"); + data->err = EINVAL; + return; + } if((pid = fork()) == 0){ + dup2(fds[1], 1); + close(fds[0]); execvp(argv[0], argv); exit(errno); } else if(pid < 0) data->err = errno; else { + close(fds[1]); + read_output(fds[0], &data->output); if(waitpid(pid, &status, 0) < 0) data->err = errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ printk("'%s' didn't exit with status 0\n", argv[0]); @@ -108,6 +119,10 @@ strcpy(gate_buf, pri->gate_addr); slip_data.args = argv; tracing_cb(slip_tramp, &slip_data); + if(slip_data.output != NULL){ + printk("%s", slip_data.output); + kfree(slip_data.output); + } if(slip_data.err != 0){ printk("slip_tramp failed - errno = %d\n", slip_data.err); @@ -137,7 +152,7 @@ struct slip_tramp_data slip_data; char fd_buf[sizeof("nnnnnn\0")], addr_buf[sizeof("nnn.nnn.nnn.nnn\0")]; char version_buf[sizeof("nnnnn\0")]; - char *argv[] = { "uml_net", "slip", version_buf, "down", fd_buf, + char *argv[] = { "uml_net", version_buf, "slip", "down", fd_buf, addr_buf, NULL }; sprintf(version_buf, "%d", UML_NET_VERSION); @@ -145,6 +160,10 @@ dev_ip_addr(pri->dev, addr_buf, NULL); slip_data.args = argv; tracing_cb(slip_tramp, &slip_data); + if(slip_data.output != NULL){ + printk("%s", slip_data.output); + kfree(slip_data.output); + } if(slip_data.err != 0) printk("slip_tramp failed - errno = %d\n", slip_data.err); close(fd); diff -Naur -X exclude-files ac_cur/arch/um/drivers/tuntap_user.c ac/arch/um/drivers/tuntap_user.c --- ac_cur/arch/um/drivers/tuntap_user.c Tue Oct 30 18:27:12 2001 +++ ac/arch/um/drivers/tuntap_user.c Sat Nov 3 00:02:29 2001 @@ -43,8 +43,7 @@ { struct tuntap_open_data *data = arg; char version_buf[sizeof("nnnnn\0")]; - char fd_buf[sizeof("nnnnnn\0")]; - char *args[] = { "uml_net", version_buf, "tuntap", "up", "", fd_buf, + char *args[] = { "uml_net", version_buf, "tuntap", "up", "", data->gate, NULL }; char buf[CMSG_SPACE(sizeof(data->data_fd))]; struct msghdr msg; @@ -53,9 +52,9 @@ int pid, n; sprintf(version_buf, "%d", UML_NET_VERSION); - sprintf(fd_buf, "%d", data->remote); data->err = 0; if((pid = fork()) == 0){ + dup2(data->remote, 1); close(data->me); execvp(args[0], args); printk("Exec of '%s' failed - errno = %d\n", args[0], errno); @@ -107,22 +106,32 @@ char *dev; char *what; char *address; + char *output; }; static void tuntap_change_tramp(void *arg) { - int pid; + int pid, fds[2]; struct tuntap_change_data *data = arg; char version[sizeof("nnnnn\0")]; char *argv[] = { "uml_net", version, "tuntap", data->what, data->dev, data->address, NULL }; sprintf(version, "%d", UML_NET_VERSION); + if(pipe(fds) < 0){ + printk("tuntap_change_tramp - pipe failed, errno = %d\n", + errno); + return; + } if((pid = fork()) == 0){ + dup2(fds[1], 1); + close(fds[0]); execvp(argv[0], argv); printk("Exec of '%s' failed - errno = %d\n", argv[0], errno); exit(1); - } + } + close(fds[1]); + if(read_output(fds[0], &data->output)) data->output = NULL; waitpid(pid, NULL, 0); } @@ -135,7 +144,11 @@ data.what = what; sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); data.address = addr_buf; - tracing_cb(tuntap_change_tramp, &data); + tracing_cb(tuntap_change_tramp, &data); + if(data.output != NULL){ + printk("%s", data.output); + kfree(data.output); + } } static void tuntap_open_addr(unsigned char *addr, void *arg)