1 /* sys_generic.c 6.8 85/03/12 */ 2 3 #include "param.h" 4 #include "systm.h" 5 #include "dir.h" 6 #include "user.h" 7 #include "ioctl.h" 8 #include "file.h" 9 #include "proc.h" 10 #include "uio.h" 11 #include "kernel.h" 12 #include "stat.h" 13 14 /* 15 * Read system call. 16 */ 17 read() 18 { 19 register struct a { 20 int fdes; 21 char *cbuf; 22 unsigned count; 23 } *uap = (struct a *)u.u_ap; 24 struct uio auio; 25 struct iovec aiov; 26 27 aiov.iov_base = (caddr_t)uap->cbuf; 28 aiov.iov_len = uap->count; 29 auio.uio_iov = &aiov; 30 auio.uio_iovcnt = 1; 31 rwuio(&auio, UIO_READ); 32 } 33 34 readv() 35 { 36 register struct a { 37 int fdes; 38 struct iovec *iovp; 39 int iovcnt; 40 } *uap = (struct a *)u.u_ap; 41 struct uio auio; 42 struct iovec aiov[16]; /* XXX */ 43 44 if (uap->iovcnt <= 0 || uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) { 45 u.u_error = EINVAL; 46 return; 47 } 48 auio.uio_iov = aiov; 49 auio.uio_iovcnt = uap->iovcnt; 50 u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov, 51 (unsigned)(uap->iovcnt * sizeof (struct iovec))); 52 if (u.u_error) 53 return; 54 rwuio(&auio, UIO_READ); 55 } 56 57 /* 58 * Write system call 59 */ 60 write() 61 { 62 register struct a { 63 int fdes; 64 char *cbuf; 65 int count; 66 } *uap = (struct a *)u.u_ap; 67 struct uio auio; 68 struct iovec aiov; 69 70 auio.uio_iov = &aiov; 71 auio.uio_iovcnt = 1; 72 aiov.iov_base = uap->cbuf; 73 aiov.iov_len = uap->count; 74 rwuio(&auio, UIO_WRITE); 75 } 76 77 writev() 78 { 79 register struct a { 80 int fdes; 81 struct iovec *iovp; 82 int iovcnt; 83 } *uap = (struct a *)u.u_ap; 84 struct uio auio; 85 struct iovec aiov[16]; /* XXX */ 86 87 if (uap->iovcnt <= 0 || uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) { 88 u.u_error = EINVAL; 89 return; 90 } 91 auio.uio_iov = aiov; 92 auio.uio_iovcnt = uap->iovcnt; 93 u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov, 94 (unsigned)(uap->iovcnt * sizeof (struct iovec))); 95 if (u.u_error) 96 return; 97 rwuio(&auio, UIO_WRITE); 98 } 99 100 rwuio(uio, rw) 101 register struct uio *uio; 102 enum uio_rw rw; 103 { 104 struct a { 105 int fdes; 106 }; 107 register struct file *fp; 108 register struct iovec *iov; 109 int i, count; 110 111 GETF(fp, ((struct a *)u.u_ap)->fdes); 112 if ((fp->f_flag&(rw==UIO_READ ? FREAD : FWRITE)) == 0) { 113 u.u_error = EBADF; 114 return; 115 } 116 uio->uio_resid = 0; 117 uio->uio_segflg = UIO_USERSPACE; 118 iov = uio->uio_iov; 119 for (i = 0; i < uio->uio_iovcnt; i++) { 120 if (iov->iov_len < 0) { 121 u.u_error = EINVAL; 122 return; 123 } 124 uio->uio_resid += iov->iov_len; 125 if (uio->uio_resid < 0) { 126 u.u_error = EINVAL; 127 return; 128 } 129 iov++; 130 } 131 count = uio->uio_resid; 132 uio->uio_offset = fp->f_offset; 133 if (setjmp(&u.u_qsave)) { 134 if (uio->uio_resid == count) { 135 if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0 || 136 (u.u_procp->p_flag & SOUSIG) != 0) 137 u.u_error = EINTR; 138 else 139 u.u_eosys = RESTARTSYS; 140 } 141 } else 142 u.u_error = (*fp->f_ops->fo_rw)(fp, rw, uio); 143 u.u_r.r_val1 = count - uio->uio_resid; 144 fp->f_offset += u.u_r.r_val1; 145 } 146 147 /* 148 * Ioctl system call 149 */ 150 ioctl() 151 { 152 register struct file *fp; 153 struct a { 154 int fdes; 155 int cmd; 156 caddr_t cmarg; 157 } *uap; 158 register int com; 159 register u_int size; 160 char data[IOCPARM_MASK+1]; 161 162 uap = (struct a *)u.u_ap; 163 GETF(fp, uap->fdes); 164 if ((fp->f_flag & (FREAD|FWRITE)) == 0) { 165 u.u_error = EBADF; 166 return; 167 } 168 com = uap->cmd; 169 170 #if defined(vax) && defined(COMPAT) 171 /* 172 * Map old style ioctl's into new for the 173 * sake of backwards compatibility (sigh). 174 */ 175 if ((com&~0xffff) == 0) { 176 com = mapioctl(com); 177 if (com == 0) { 178 u.u_error = EINVAL; 179 return; 180 } 181 } 182 #endif 183 if (com == FIOCLEX) { 184 u.u_pofile[uap->fdes] |= UF_EXCLOSE; 185 return; 186 } 187 if (com == FIONCLEX) { 188 u.u_pofile[uap->fdes] &= ~UF_EXCLOSE; 189 return; 190 } 191 192 /* 193 * Interpret high order word to find 194 * amount of data to be copied to/from the 195 * user's address space. 196 */ 197 size = (com &~ (IOC_INOUT|IOC_VOID)) >> 16; 198 if (size > sizeof (data)) { 199 u.u_error = EFAULT; 200 return; 201 } 202 if (com&IOC_IN) { 203 if (size) { 204 u.u_error = 205 copyin(uap->cmarg, (caddr_t)data, (u_int)size); 206 if (u.u_error) 207 return; 208 } else 209 *(caddr_t *)data = uap->cmarg; 210 } else if ((com&IOC_OUT) && size) 211 /* 212 * Zero the buffer on the stack so the user 213 * always gets back something deterministic. 214 */ 215 bzero((caddr_t)data, size); 216 else if (com&IOC_VOID) 217 *(caddr_t *)data = uap->cmarg; 218 219 switch (com) { 220 221 case FIONBIO: 222 u.u_error = fset(fp, FNDELAY, *(int *)data); 223 return; 224 225 case FIOASYNC: 226 u.u_error = fset(fp, FASYNC, *(int *)data); 227 return; 228 229 case FIOSETOWN: 230 u.u_error = fsetown(fp, *(int *)data); 231 return; 232 233 case FIOGETOWN: 234 u.u_error = fgetown(fp, (int *)data); 235 return; 236 } 237 u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, data); 238 /* 239 * Copy any data to user, size was 240 * already set and checked above. 241 */ 242 if (u.u_error == 0 && (com&IOC_OUT) && size) 243 u.u_error = copyout(data, uap->cmarg, (u_int)size); 244 } 245 246 int unselect(); 247 int nselcoll; 248 249 /* 250 * Select uses bit masks of file descriptors in ints. 251 * These macros manipulate such bit fields (the filesystem macros use chars). 252 */ 253 #define NBI (sizeof(int) * NBBY) /* bits per int */ 254 #define NI howmany(NOFILE, NBI) 255 #define tbit(p, n) ((p)[(n)/NBI] & (1 << ((n) % NBI))) 256 #define sbit(p, n) ((p)[(n)/NBI] |= (1 << ((n) % NBI))) 257 #define cbit(p, n) ((p)[(n)/NBI] &= ~(1 << ((n) % NBI))) 258 259 /* 260 * Select system call. 261 */ 262 select() 263 { 264 register struct uap { 265 int nd; 266 int *in, *ou, *ex; 267 struct timeval *tv; 268 } *uap = (struct uap *)u.u_ap; 269 int ibits[3][NI], obits[3][NI]; 270 struct timeval atv; 271 int s, ncoll, ni; 272 label_t lqsave; 273 274 bzero(ibits, sizeof(ibits)); 275 bzero(obits, sizeof(obits)); 276 if (uap->nd > NOFILE) 277 uap->nd = NOFILE; /* forgiving, if slightly wrong */ 278 ni = howmany(uap->nd, NBI); 279 280 #define getbits(name, x) \ 281 if (uap->name) { \ 282 u.u_error = copyin((caddr_t)uap->name, (caddr_t)ibits[x], \ 283 ni * sizeof(int)); \ 284 if (u.u_error) \ 285 goto done; \ 286 } 287 getbits(in, 0); 288 getbits(ou, 1); 289 getbits(ex, 2); 290 #undef getbits 291 292 if (uap->tv) { 293 u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 294 sizeof (atv)); 295 if (u.u_error) 296 goto done; 297 if (itimerfix(&atv)) { 298 u.u_error = EINVAL; 299 goto done; 300 } 301 s = splhigh(); timevaladd(&atv, &time); splx(s); 302 } 303 retry: 304 ncoll = nselcoll; 305 u.u_procp->p_flag |= SSEL; 306 u.u_r.r_val1 = selscan(ibits, obits, uap->nd); 307 if (u.u_error || u.u_r.r_val1) 308 goto done; 309 s = splhigh(); 310 /* this should be timercmp(&time, &atv, >=) */ 311 if (uap->tv && (time.tv_sec > atv.tv_sec || 312 time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) { 313 splx(s); 314 goto done; 315 } 316 if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) { 317 u.u_procp->p_flag &= ~SSEL; 318 splx(s); 319 goto retry; 320 } 321 u.u_procp->p_flag &= ~SSEL; 322 if (uap->tv) { 323 lqsave = u.u_qsave; 324 if (setjmp(&u.u_qsave)) { 325 untimeout(unselect, (caddr_t)u.u_procp); 326 u.u_error = EINTR; 327 splx(s); 328 goto done; 329 } 330 timeout(unselect, (caddr_t)u.u_procp, hzto(&atv)); 331 } 332 sleep((caddr_t)&selwait, PZERO+1); 333 if (uap->tv) { 334 u.u_qsave = lqsave; 335 untimeout(unselect, (caddr_t)u.u_procp); 336 } 337 splx(s); 338 goto retry; 339 done: 340 #define putbits(name, x) \ 341 if (uap->name) { \ 342 int error = copyout((caddr_t)obits[x], (caddr_t)uap->name, \ 343 ni * sizeof(int)); \ 344 if (error) \ 345 u.u_error = error; \ 346 } 347 putbits(in, 0); 348 putbits(ou, 1); 349 putbits(ex, 2); 350 #undef putbits 351 } 352 353 unselect(p) 354 register struct proc *p; 355 { 356 register int s = splhigh(); 357 358 switch (p->p_stat) { 359 360 case SSLEEP: 361 setrun(p); 362 break; 363 364 case SSTOP: 365 unsleep(p); 366 break; 367 } 368 splx(s); 369 } 370 371 selscan(ibits, obits, nfd) 372 int (*ibits)[NI], (*obits)[NI]; 373 { 374 register int which, bits, i, j; 375 int flag; 376 struct file *fp; 377 int n = 0; 378 379 for (which = 0; which < 3; which++) { 380 switch (which) { 381 382 case 0: 383 flag = FREAD; break; 384 385 case 1: 386 flag = FWRITE; break; 387 388 case 2: 389 flag = 0; break; 390 } 391 for (i = 0; i < nfd; i += NBI) { 392 bits = ibits[which][i/NBI]; 393 while ((j = ffs(bits)) && i + --j < nfd) { 394 bits &= ~(1 << j); 395 fp = u.u_ofile[i + j]; 396 if (fp == NULL) { 397 u.u_error = EBADF; 398 break; 399 } 400 if ((*fp->f_ops->fo_select)(fp, flag)) { 401 sbit(obits[which], i + j); 402 n++; 403 } 404 } 405 } 406 } 407 return (n); 408 } 409 410 /*ARGSUSED*/ 411 seltrue(dev, flag) 412 dev_t dev; 413 int flag; 414 { 415 416 return (1); 417 } 418 419 selwakeup(p, coll) 420 register struct proc *p; 421 int coll; 422 { 423 424 if (coll) { 425 nselcoll++; 426 wakeup((caddr_t)&selwait); 427 } 428 if (p) { 429 int s = splhigh(); 430 if (p->p_wchan == (caddr_t)&selwait) { 431 if (p->p_stat == SSLEEP) 432 setrun(p); 433 else 434 unsleep(p); 435 } else if (p->p_flag & SSEL) 436 p->p_flag &= ~SSEL; 437 splx(s); 438 } 439 } 440