1 /* uipc_syscalls.c 4.21 82/07/24 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/proc.h" 8 #include "../h/file.h" 9 #include "../h/inode.h" 10 #include "../h/buf.h" 11 #include "../h/mbuf.h" 12 #include "../h/protosw.h" 13 #include "../h/socket.h" 14 #include "../h/socketvar.h" 15 #include "../net/in.h" 16 #include "../net/in_systm.h" 17 #include "../h/descrip.h" 18 19 ssocreate() 20 { 21 22 } 23 24 ssobind() 25 { 26 27 } 28 29 ssolisten() 30 { 31 32 } 33 34 ssoaccept() 35 { 36 37 } 38 39 ssoconnect() 40 { 41 42 } 43 44 ssocreatepair() 45 { 46 47 } 48 49 ssosendto() 50 { 51 52 } 53 54 ssosend() 55 { 56 57 } 58 59 ssorecvfrom() 60 { 61 62 } 63 64 ssorecv() 65 { 66 67 } 68 69 ssosendm() 70 { 71 72 } 73 74 ssorecvm() 75 { 76 77 } 78 79 ssoshutdown() 80 { 81 82 } 83 84 /* 85 * Socket system call interface. 86 * 87 * These routines interface the socket routines to UNIX, 88 * isolating the system interface from the socket-protocol interface. 89 * 90 * TODO: 91 * SO_INTNOTIFY 92 */ 93 94 static struct sockproto localproto = { PF_UNIX, 0 }; 95 /* 96 * Pipe system call interface. 97 */ 98 spipe() 99 { 100 register struct file *rf, *wf; 101 struct socket *rso, *wso; 102 int r; 103 104 u.u_error = socreate(&rso, SOCK_STREAM, 105 &localproto, (struct sockaddr *)0, 0); 106 if (u.u_error) 107 return; 108 u.u_error = socreate(&wso, SOCK_STREAM, 109 &localproto, (struct sockaddr *)0, 0); 110 if (u.u_error) 111 goto free; 112 rf = falloc(); 113 if (rf == NULL) 114 goto free2; 115 r = u.u_r.r_val1; 116 rf->f_flag = FREAD; 117 rf->f_type = DTYPE_SOCKET; 118 rf->f_socket = rso; 119 wf = falloc(); 120 if (wf == NULL) 121 goto free3; 122 wf->f_flag = FWRITE; 123 wf->f_type = DTYPE_SOCKET; 124 wf->f_socket = wso; 125 u.u_r.r_val2 = u.u_r.r_val1; 126 u.u_r.r_val1 = r; 127 if (piconnect(wso, rso) == 0) 128 goto free4; 129 return; 130 free4: 131 wf->f_count = 0; 132 u.u_ofile[u.u_r.r_val2] = 0; 133 free3: 134 rf->f_count = 0; 135 u.u_ofile[r] = 0; 136 free2: 137 wso->so_state |= SS_NOFDREF; 138 sofree(wso); 139 free: 140 rso->so_state |= SS_NOFDREF; 141 sofree(rso); 142 } 143 144 /* 145 * Socket system call interface. Copy sa arguments 146 * set up file descriptor and call internal socket 147 * creation routine. 148 */ 149 ssocket() 150 { 151 register struct a { 152 int type; 153 struct sockproto *asp; 154 struct sockaddr *asa; 155 int options; 156 } *uap = (struct a *)u.u_ap; 157 struct sockproto sp; 158 struct sockaddr sa; 159 struct socket *so; 160 register struct file *fp; 161 162 if ((fp = falloc()) == NULL) 163 return; 164 fp->f_flag = FREAD|FWRITE; 165 fp->f_type = DTYPE_SOCKET; 166 if (uap->asp && copyin((caddr_t)uap->asp, (caddr_t)&sp, sizeof (sp)) || 167 uap->asa && copyin((caddr_t)uap->asa, (caddr_t)&sa, sizeof (sa))) { 168 u.u_error = EFAULT; 169 return; 170 } 171 u.u_error = socreate(&so, uap->type, 172 uap->asp ? &sp : 0, uap->asa ? &sa : 0, uap->options); 173 if (u.u_error) 174 goto bad; 175 fp->f_socket = so; 176 return; 177 bad: 178 u.u_ofile[u.u_r.r_val1] = 0; 179 fp->f_count = 0; 180 } 181 182 /* 183 * Accept system call interface. 184 */ 185 saccept() 186 { 187 register struct a { 188 int fdes; 189 struct sockaddr *asa; 190 } *uap = (struct a *)u.u_ap; 191 struct sockaddr sa; 192 register struct file *fp; 193 struct socket *so; 194 int s; 195 196 if (uap->asa && useracc((caddr_t)uap->asa, sizeof (sa), B_WRITE)==0) { 197 u.u_error = EFAULT; 198 return; 199 } 200 fp = getf(uap->fdes); 201 if (fp == 0) 202 return; 203 if (fp->f_type != DTYPE_SOCKET) { 204 u.u_error = ENOTSOCK; 205 return; 206 } 207 s = splnet(); 208 so = fp->f_socket; 209 if ((so->so_options & SO_ACCEPTCONN) == 0) { 210 u.u_error = EINVAL; 211 splx(s); 212 return; 213 } 214 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) { 215 u.u_error = EWOULDBLOCK; 216 splx(s); 217 return; 218 } 219 while (so->so_qlen == 0 && so->so_error == 0) { 220 if (so->so_state & SS_CANTRCVMORE) { 221 so->so_error = ECONNABORTED; 222 break; 223 } 224 sleep((caddr_t)&so->so_timeo, PZERO+1); 225 } 226 if (so->so_error) { 227 u.u_error = so->so_error; 228 splx(s); 229 return; 230 } 231 if ((so->so_options & SO_NEWFDONCONN) == 0) { 232 struct socket *nso = so->so_q; 233 (void) soqremque(nso, 1); 234 soclose(so, 1); 235 fp->f_socket = nso; 236 nso->so_q = 0; 237 so = nso; 238 goto ret; 239 } 240 if (ufalloc() < 0) { 241 splx(s); 242 return; 243 } 244 fp = falloc(); 245 if (fp == 0) { 246 u.u_ofile[u.u_r.r_val1] = 0; 247 splx(s); 248 return; 249 } 250 fp->f_type = DTYPE_SOCKET; 251 fp->f_flag = FREAD|FWRITE; 252 fp->f_socket = so->so_q; 253 so->so_q = so->so_q->so_q; 254 so->so_qlen--; 255 ret: 256 soaccept(so, &sa); 257 if (uap->asa) 258 (void) copyout((caddr_t)&sa, (caddr_t)uap->asa, sizeof (sa)); 259 splx(s); 260 } 261 262 /* 263 * Connect socket to foreign peer; system call 264 * interface. Copy sa arguments and call internal routine. 265 */ 266 sconnect() 267 { 268 register struct a { 269 int fdes; 270 struct sockaddr *a; 271 } *uap = (struct a *)u.u_ap; 272 struct sockaddr sa; 273 register struct file *fp; 274 register struct socket *so; 275 int s; 276 277 if (copyin((caddr_t)uap->a, (caddr_t)&sa, sizeof (sa))) { 278 u.u_error = EFAULT; 279 return; 280 } 281 fp = getf(uap->fdes); 282 if (fp == 0) 283 return; 284 if (fp->f_type != DTYPE_SOCKET) { 285 u.u_error = ENOTSOCK; 286 return; 287 } 288 so = fp->f_socket; 289 u.u_error = soconnect(so, &sa); 290 if (u.u_error) 291 return; 292 s = splnet(); 293 if ((so->so_state & SS_NBIO) && 294 (so->so_state & SS_ISCONNECTING)) { 295 u.u_error = EINPROGRESS; 296 splx(s); 297 return; 298 } 299 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) 300 sleep((caddr_t)&so->so_timeo, PZERO+1); 301 u.u_error = so->so_error; 302 so->so_error = 0; 303 splx(s); 304 } 305 306 /* 307 * Send data on socket. 308 */ 309 ssend() 310 { 311 register struct a { 312 int fdes; 313 struct sockaddr *asa; 314 caddr_t cbuf; 315 unsigned count; 316 } *uap = (struct a *)u.u_ap; 317 register struct file *fp; 318 struct sockaddr sa; 319 320 fp = getf(uap->fdes); 321 if (fp == 0) 322 return; 323 if (fp->f_type != DTYPE_SOCKET) { 324 u.u_error = ENOTSOCK; 325 return; 326 } 327 u.u_base = uap->cbuf; 328 u.u_count = uap->count; 329 u.u_segflg = 0; 330 if (useracc(uap->cbuf, uap->count, B_READ) == 0 || 331 uap->asa && copyin((caddr_t)uap->asa, (caddr_t)&sa, sizeof (sa))) { 332 u.u_error = EFAULT; 333 return; 334 } 335 u.u_error = sosend(fp->f_socket, uap->asa ? &sa : 0); 336 u.u_r.r_val1 = uap->count - u.u_count; 337 } 338 339 /* 340 * Receive data on socket. 341 */ 342 sreceive() 343 { 344 register struct a { 345 int fdes; 346 struct sockaddr *asa; 347 caddr_t cbuf; 348 u_int count; 349 } *uap = (struct a *)u.u_ap; 350 register struct file *fp; 351 struct sockaddr sa; 352 353 fp = getf(uap->fdes); 354 if (fp == 0) 355 return; 356 if (fp->f_type != DTYPE_SOCKET) { 357 u.u_error = ENOTSOCK; 358 return; 359 } 360 u.u_base = uap->cbuf; 361 u.u_count = uap->count; 362 u.u_segflg = 0; 363 if (useracc(uap->cbuf, uap->count, B_WRITE) == 0 || 364 uap->asa && copyin((caddr_t)uap->asa, (caddr_t)&sa, sizeof (sa))) { 365 u.u_error = EFAULT; 366 return; 367 } 368 u.u_error = soreceive(fp->f_socket, uap->asa ? &sa : 0); 369 if (u.u_error) 370 return; 371 if (uap->asa) 372 (void) copyout((caddr_t)&sa, (caddr_t)uap->asa, sizeof (sa)); 373 u.u_r.r_val1 = uap->count - u.u_count; 374 } 375 376 /* 377 * Get socket address. 378 */ 379 ssocketaddr() 380 { 381 register struct a { 382 int fdes; 383 struct sockaddr *asa; 384 } *uap = (struct a *)u.u_ap; 385 register struct file *fp; 386 register struct socket *so; 387 struct sockaddr addr; 388 389 fp = getf(uap->fdes); 390 if (fp == 0) 391 return; 392 if (fp->f_type != DTYPE_SOCKET) { 393 u.u_error = ENOTSOCK; 394 return; 395 } 396 so = fp->f_socket; 397 u.u_error = 398 (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, (caddr_t)&addr); 399 if (u.u_error) 400 return; 401 if (copyout((caddr_t)&addr, (caddr_t)uap->asa, sizeof (addr))) 402 u.u_error = EFAULT; 403 } 404