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

Defined functions

ioctl defined in line 155; never used
read defined in line 23; never used
readv defined in line 40; used 2 times
rwuio defined in line 106; used 4 times
select defined in line 257; used 2 times
selscan defined in line 368; used 1 times
seltrue defined in line 409; used 23 times
unselect defined in line 350; used 4 times
write defined in line 66; never used
writev defined in line 83; used 2 times

Defined variables

nselcoll defined in line 252; used 3 times

Defined struct's

a defined in line 158; used 12 times
uap defined in line 259; used 2 times
  • in line 263(2)

Defined macros

getbits defined in line 275; used 4 times
putbits defined in line 335; used 4 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1736
Valid CSS Valid XHTML 1.0 Strict