1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <ip.h> 5 #include <plumb.h> 6 #include <thread.h> 7 #include <fcall.h> 8 #include <9p.h> 9 #include <mp.h> 10 #include <libsec.h> 11 #include "dat.h" 12 #include "fns.h" 13 14 static int tlsdial(char*, char*, char*, int*, int); 15 16 static long 17 t(Ioproc *io, void (*op)(Ioproc*), int n, ...) 18 { 19 int i, ret; 20 va_list arg; 21 22 assert(!io->inuse); 23 io->inuse = 1; 24 io->op = op; 25 va_start(arg, n); 26 for(i=0; i<n; i++) 27 io->arg[i] = va_arg(arg, long); 28 sendp(io->c, io); 29 recvp(io->c); 30 ret = io->ret; 31 if(ret < 0) 32 errstr(io->err, sizeof io->err); 33 io->inuse = 0; 34 return ret; 35 } 36 37 static void 38 t2(Ioproc *io, int ret) 39 { 40 io->ret = ret; 41 if(ret < 0) 42 rerrstr(io->err, sizeof io->err); 43 sendp(io->c, io); 44 } 45 46 static void ioread2(Ioproc*); 47 static long 48 ioread(Ioproc *io, int fd, void *a, long n) 49 { 50 return t(io, ioread2, 3, fd, a, n); 51 } 52 static void 53 ioread2(Ioproc *io) 54 { 55 t2(io, read(io->arg[0], (void*)io->arg[1], io->arg[2])); 56 } 57 58 static void iowrite2(Ioproc*); 59 static long 60 iowrite(Ioproc *io, int fd, void *a, long n) 61 { 62 return t(io, iowrite2, 3, fd, a, n); 63 } 64 static void 65 iowrite2(Ioproc *io) 66 { 67 t2(io, write(io->arg[0], (void*)io->arg[1], io->arg[2])); 68 } 69 70 static void ioclose2(Ioproc*); 71 static int 72 ioclose(Ioproc *io, int fd) 73 { 74 return t(io, ioclose2, 1, fd); 75 } 76 static void 77 ioclose2(Ioproc *io) 78 { 79 t2(io, close(io->arg[0])); 80 } 81 82 static void iodial2(Ioproc*); 83 static int 84 iodial(Ioproc *io, char *a, char *b, char *c, int *d, int e) 85 { 86 return t(io, iodial2, 5, a, b, c, d, e); 87 } 88 static void 89 iodial2(Ioproc *io) 90 { 91 t2(io, tlsdial((char*)io->arg[0], (char*)io->arg[1], (char*)io->arg[2], (int*)io->arg[3], io->arg[4])); 92 } 93 94 static void ioopen2(Ioproc*); 95 static int 96 ioopen(Ioproc *io, char *path, int mode) 97 { 98 return t(io, ioopen2, 2, path, mode); 99 } 100 static void 101 ioopen2(Ioproc *io) 102 { 103 t2(io, open((char*)io->arg[0], io->arg[1])); 104 } 105 106 static int 107 ioprint(Ioproc *io, int fd, char *fmt, ...) 108 { 109 char buf[1024]; 110 va_list arg; 111 112 va_start(arg, fmt); 113 vseprint(buf, buf+sizeof buf, fmt, arg); 114 va_end(arg); 115 return iowrite(io, fd, buf, strlen(buf)); 116 } 117 118 static void 119 iointerrupt(Ioproc *io) 120 { 121 if(!io->inuse) 122 return; 123 postnote(PNPROC, io->pid, "interrupt"); 124 } 125 126 static void 127 xioproc(void *a) 128 { 129 Ioproc *io; 130 131 io = a; 132 io->pid = getpid(); 133 sendp(io->c, nil); 134 while(recvp(io->c) == io) 135 io->op(io); 136 chanfree(io->c); 137 free(io); 138 } 139 140 static int 141 tlsdial(char *a, char *b, char *c, int *d, int usetls) 142 { 143 int fd, tfd; 144 TLSconn conn; 145 146 fd = dial(a, b, c, d); 147 if(fd < 0) 148 return -1; 149 if(usetls == 0) 150 return fd; 151 152 memset(&conn, 0, sizeof conn); 153 tfd = tlsClient(fd, &conn); 154 if(tfd < 0){ 155 print("tls %r\n"); 156 close(fd); 157 return -1; 158 } 159 /* BUG: check cert here? */ 160 if(conn.cert) 161 free(conn.cert); 162 close(fd); 163 return tfd; 164 } 165 166 Ioproc iofns = 167 { 168 ioread, 169 iowrite, 170 iodial, 171 ioclose, 172 ioopen, 173 ioprint, 174 iointerrupt, 175 }; 176 177 Ioproc *iofree; 178 179 Ioproc* 180 ioproc(void) 181 { 182 Ioproc *io; 183 184 if((io = iofree) != nil){ 185 iofree = io->next; 186 return io; 187 } 188 io = emalloc(sizeof(*io)); 189 *io = iofns; 190 io->c = chancreate(sizeof(void*), 0); 191 if(proccreate(xioproc, io, STACK) < 0) 192 sysfatal("proccreate: %r"); 193 recvp(io->c); 194 return io; 195 } 196 197 void 198 closeioproc(Ioproc *io) 199 { 200 io->next = iofree; 201 iofree = io; 202 } 203 204