Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.12-rc4 201 lines 3.9 kB view raw
1#include <stdio.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <stddef.h> 5#include <sched.h> 6#include <string.h> 7#include <errno.h> 8#include <sys/wait.h> 9#include <sys/signal.h> 10#include "user_util.h" 11#include "kern_util.h" 12#include "user.h" 13#include "net_user.h" 14#include "slirp.h" 15#include "slip_proto.h" 16#include "helper.h" 17#include "os.h" 18 19void slirp_user_init(void *data, void *dev) 20{ 21 struct slirp_data *pri = data; 22 23 pri->dev = dev; 24} 25 26struct slirp_pre_exec_data { 27 int stdin; 28 int stdout; 29}; 30 31static void slirp_pre_exec(void *arg) 32{ 33 struct slirp_pre_exec_data *data = arg; 34 35 if(data->stdin != -1) dup2(data->stdin, 0); 36 if(data->stdout != -1) 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, NULL); 47 48 return(pid); 49} 50 51/* XXX This is just a trivial wrapper around os_pipe */ 52static int slirp_datachan(int *mfd, int *sfd) 53{ 54 int fds[2], err; 55 56 err = os_pipe(fds, 1, 1); 57 if(err < 0){ 58 printk("slirp_datachan: Failed to open pipe, err = %d\n", -err); 59 return(err); 60 } 61 62 *mfd = fds[0]; 63 *sfd = fds[1]; 64 return(0); 65} 66 67static int slirp_open(void *data) 68{ 69 struct slirp_data *pri = data; 70 int sfd, mfd, pid, err; 71 72 err = slirp_datachan(&mfd, &sfd); 73 if(err) 74 return(err); 75 76 pid = slirp_tramp(pri->argw.argv, sfd); 77 78 if(pid < 0){ 79 printk("slirp_tramp failed - errno = %d\n", -pid); 80 os_close_file(sfd); 81 os_close_file(mfd); 82 return(pid); 83 } 84 85 pri->slave = sfd; 86 pri->pos = 0; 87 pri->esc = 0; 88 89 pri->pid = pid; 90 91 return(mfd); 92} 93 94static void slirp_close(int fd, void *data) 95{ 96 struct slirp_data *pri = data; 97 int status,err; 98 99 os_close_file(fd); 100 os_close_file(pri->slave); 101 102 pri->slave = -1; 103 104 if(pri->pid<1) { 105 printk("slirp_close: no child process to shut down\n"); 106 return; 107 } 108 109#if 0 110 if(kill(pri->pid, SIGHUP)<0) { 111 printk("slirp_close: sending hangup to %d failed (%d)\n", 112 pri->pid, errno); 113 } 114#endif 115 116 CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG)); 117 if(err < 0) { 118 printk("slirp_close: waitpid returned %d\n", errno); 119 return; 120 } 121 122 if(err == 0) { 123 printk("slirp_close: process %d has not exited\n"); 124 return; 125 } 126 127 pri->pid = -1; 128} 129 130int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) 131{ 132 int i, n, size, start; 133 134 if(pri->more>0) { 135 i = 0; 136 while(i < pri->more) { 137 size = slip_unesc(pri->ibuf[i++], 138 pri->ibuf,&pri->pos,&pri->esc); 139 if(size){ 140 memcpy(buf, pri->ibuf, size); 141 memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); 142 pri->more=pri->more-i; 143 return(size); 144 } 145 } 146 pri->more=0; 147 } 148 149 n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); 150 if(n <= 0) return(n); 151 152 start = pri->pos; 153 for(i = 0; i < n; i++){ 154 size = slip_unesc(pri->ibuf[start + i], 155 pri->ibuf,&pri->pos,&pri->esc); 156 if(size){ 157 memcpy(buf, pri->ibuf, size); 158 memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); 159 pri->more=n-(i+1); 160 return(size); 161 } 162 } 163 return(0); 164} 165 166int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) 167{ 168 int actual, n; 169 170 actual = slip_esc(buf, pri->obuf, len); 171 n = net_write(fd, pri->obuf, actual); 172 if(n < 0) return(n); 173 else return(len); 174} 175 176static int slirp_set_mtu(int mtu, void *data) 177{ 178 return(mtu); 179} 180 181struct net_user_info slirp_user_info = { 182 .init = slirp_user_init, 183 .open = slirp_open, 184 .close = slirp_close, 185 .remove = NULL, 186 .set_mtu = slirp_set_mtu, 187 .add_address = NULL, 188 .delete_address = NULL, 189 .max_packet = BUF_SIZE 190}; 191 192/* 193 * Overrides for Emacs so that we follow Linus's tabbing style. 194 * Emacs will notice this stuff at the end of the file and automatically 195 * adjust the settings for this buffer only. This must remain at the end 196 * of the file. 197 * --------------------------------------------------------------------------- 198 * Local variables: 199 * c-file-style: "linux" 200 * End: 201 */