# 2.11BSD#431 - /usr/src/sys/sys/sys_generic.c

##### Functions

    ioctl             X
    pselect           X
    read              X
    readv             X
    select            X
    selscan           X
    seltrue           X
    selwakeup         X
    socls             X
    soctl             X
    sorw              X
    sosel             X
    write             X
    writev            X

##### Variables

    Fops              X
    nselcoll          X
    socketops         X

##### Macros

    getbits           X
    putbits           X

##### struct's

    a                 X
    pselect_args      X
    uap               X

       1: /*
       2:  * Copyright (c) 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	1.8 (2.11BSD) 2000/2/28
       7:  */
       8:
       9: #include "param.h"
      10: #include "../machine/seg.h"
      11:
      12: #include "user.h"
      13: #include "proc.h"
      14: #include "signalvar.h"
      15: #include "inode.h"
      16: #include "file.h"
      17: #include "ioctl.h"
      18: #include "conf.h"
      19: #include "uio.h"
      20: #include "pty.h"
      21: #include "kernel.h"
      22: #include "systm.h"
      23:
      24: /*
      25:  * this is consolidated here rather than being scattered all over the
      26:  * place.  the socketops table has to be in kernel space, but since
      27:  * networking might not be defined an appropriate error has to be set
      28: */
      29:
      30:     int sorw(), soctl(), sosel(), socls();
      31:     struct  fileops socketops =
      32:         { sorw, soctl, sosel, socls };
      33: extern  struct  fileops inodeops, pipeops;
      34:     struct  fileops *Fops[] = { NULL, &inodeops, &socketops, &pipeops };
      35:
      36: /*
      37:  * Read system call.
      38:  */
      39: read()
      40: {
      41:     register struct a {
      42:         int fdes;
      43:         char    *cbuf;
      44:         unsigned count;
      45:     } *uap = (struct a *)u.u_ap;
      46:     struct uio auio;
      47:     struct iovec aiov;
      48:
      49:     aiov.iov_base = (caddr_t)uap->cbuf;
      50:     aiov.iov_len = uap->count;
      51:     auio.uio_iov = &aiov;
      52:     auio.uio_iovcnt = 1;
      53:     auio.uio_rw = UIO_READ;
      54:     rwuio(&auio);
      55: }
      56:
      57: readv()
      58: {
      59:     register struct a {
      60:         int fdes;
      61:         struct  iovec *iovp;
      62:         unsigned iovcnt;
      63:     } *uap = (struct a *)u.u_ap;
      64:     struct uio auio;
      65:     struct iovec aiov[16];      /* XXX */
      66:
      67:     if (uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) {
      68:         u.u_error = EINVAL;
      69:         return;
      70:     }
      71:     auio.uio_iov = aiov;
      72:     auio.uio_iovcnt = uap->iovcnt;
      73:     auio.uio_rw = UIO_READ;
      74:     u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov,
      75:         uap->iovcnt * sizeof (struct iovec));
      76:     if (u.u_error)
      77:         return;
      78:     rwuio(&auio);
      79: }
      80:
      81: /*
      82:  * Write system call
      83:  */
      84: write()
      85: {
      86:     register struct a {
      87:         int fdes;
      88:         char    *cbuf;
      89:         unsigned count;
      90:     } *uap = (struct a *)u.u_ap;
      91:     struct uio auio;
      92:     struct iovec aiov;
      93:
      94:     auio.uio_iov = &aiov;
      95:     auio.uio_iovcnt = 1;
      96:     auio.uio_rw = UIO_WRITE;
      97:     aiov.iov_base = uap->cbuf;
      98:     aiov.iov_len = uap->count;
      99:     rwuio(&auio);
     100: }
     101:
     102: writev()
     103: {
     104:     register struct a {
     105:         int fdes;
     106:         struct  iovec *iovp;
     107:         unsigned iovcnt;
     108:     } *uap = (struct a *)u.u_ap;
     109:     struct uio auio;
     110:     struct iovec aiov[16];      /* XXX */
     111:
     112:     if (uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) {
     113:         u.u_error = EINVAL;
     114:         return;
     115:     }
     116:     auio.uio_iov = aiov;
     117:     auio.uio_iovcnt = uap->iovcnt;
     118:     auio.uio_rw = UIO_WRITE;
     119:     u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov,
     120:         uap->iovcnt * sizeof (struct iovec));
     121:     if (u.u_error)
     122:         return;
     123:     rwuio(&auio);
     124: }
     125:
     126: static
     127: rwuio(uio)
     128:     register struct uio *uio;
     129: {
     130:     struct a {
     131:         int fdes;
     132:     };
     133:     register struct file *fp;
     134:     register struct iovec *iov;
     135:     u_int i, count;
     136:     off_t   total;
     137:
     138:     GETF(fp, ((struct a *)u.u_ap)->fdes);
     139:     if ((fp->f_flag & (uio->uio_rw == UIO_READ ? FREAD : FWRITE)) == 0) {
     140:         u.u_error = EBADF;
     141:         return;
     142:     }
     143:     total =(off_t)0;
     144:     uio->uio_resid = 0;
     145:     uio->uio_segflg = UIO_USERSPACE;
     146:     for (iov = uio->uio_iov, i = 0; i < uio->uio_iovcnt; i++, iov++)
     147:         total += iov->iov_len;
     148:
     149:     uio->uio_resid = total;
     150:     if  (uio->uio_resid != total)   /* check wraparound */
     151:         return(u.u_error = EINVAL);
     152:
     153:     count = uio->uio_resid;
     154:     if  (setjmp(&u.u_qsave))
     155:         {
     156: /*
     157:  * The ONLY way we can get here is via the longjump in sleep.  Thus signals
     158:  * have been checked and u_error set accordingly.  If no bytes have been
     159:  * transferred then all that needs to be done now is 'return'; the system
     160:  * call will either be restarted or reported as interrupted.  If bytes have
     161:  * been transferred then we need to calculate the number of bytes transferred.
     162: */
     163:         if  (uio->uio_resid == count)
     164:             return;
     165:         else
     166:             u.u_error = 0;
     167:         }
     168:     else
     169:         u.u_error = (*Fops[fp->f_type]->fo_rw)(fp, uio);
     170:     u.u_r.r_val1 = count - uio->uio_resid;
     171: }
     172:
     173: /*
     174:  * Ioctl system call
     175:  */
     176: ioctl()
     177: {
     178:     register struct file *fp;
     179:     register struct a {
     180:         int fdes;
     181:         long    cmd;
     182:         caddr_t cmarg;
     183:     } *uap;
     184:     long com;
     185:     u_int k_com;
     186:     register u_int size;
     187:     char data[IOCPARM_MASK+1];
     188:
     189:     uap = (struct a *)u.u_ap;
     190:     if ((fp = getf(uap->fdes)) == NULL)
     191:         return;
     192:     if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
     193:         u.u_error = EBADF;
     194:         return;
     195:     }
     196:     com = uap->cmd;
     197:
     198:     /* THE 2.11 KERNEL STILL THINKS THAT IOCTL COMMANDS ARE 16 BITS */
     199:     k_com = (u_int)com;
     200:
     201:     if (k_com == FIOCLEX) {
     202:         u.u_pofile[uap->fdes] |= UF_EXCLOSE;
     203:         return;
     204:     }
     205:     if (k_com == FIONCLEX) {
     206:         u.u_pofile[uap->fdes] &= ~UF_EXCLOSE;
     207:         return;
     208:     }
     209:
     210:     /*
     211: 	 * Interpret high order word to find
     212: 	 * amount of data to be copied to/from the
     213: 	 * user's address space.
     214: 	 */
     215:     size = (com &~ (IOC_INOUT|IOC_VOID)) >> 16;
     216:     if (size > sizeof (data)) {
     217:         u.u_error = EFAULT;
     218:         return;
     219:     }
     220:     if (com&IOC_IN) {
     221:         if (size) {
     222:             if (((u_int)uap->cmarg|size)&1)
     223:                 u.u_error =
     224:                 vcopyin(uap->cmarg, (caddr_t)data, size);
     225:             else
     226:                 u.u_error =
     227:                 copyin(uap->cmarg, (caddr_t)data, size);
     228:             if (u.u_error)
     229:                 return;
     230:         } else
     231:             *(caddr_t *)data = uap->cmarg;
     232:     } else if ((com&IOC_OUT) && size)
     233:         /*
     234: 		 * Zero the buffer on the stack so the user
     235: 		 * always gets back something deterministic.
     236: 		 */
     237:         bzero((caddr_t)data, size);
     238:     else if (com&IOC_VOID)
     239:         *(caddr_t *)data = uap->cmarg;
     240:
     241:     switch (k_com) {
     242:
     243:     case FIONBIO:
     244:         u.u_error = fset(fp, FNONBLOCK, *(int *)data);
     245:         return;
     246:
     247:     case FIOASYNC:
     248:         u.u_error = fset(fp, FASYNC, *(int *)data);
     249:         return;
     250:
     251:     case FIOSETOWN:
     252:         u.u_error = fsetown(fp, *(int *)data);
     253:         return;
     254:
     255:     case FIOGETOWN:
     256:         u.u_error = fgetown(fp, (int *)data);
     257:         return;
     258:     }
     259:     u.u_error = (*Fops[fp->f_type]->fo_ioctl)(fp, k_com, data);
     260:     /*
     261: 	 * Copy any data to user, size was
     262: 	 * already set and checked above.
     263: 	 */
     264:     if (u.u_error == 0 && (com&IOC_OUT) && size)
     265:         if (((u_int)uap->cmarg|size)&1)
     266:             u.u_error = vcopyout(data, uap->cmarg, size);
     267:         else
     268:             u.u_error = copyout(data, uap->cmarg, size);
     269: }
     270:
     271: int nselcoll;
     272:
     273: struct  pselect_args
     274:     {
     275:     int     nd;
     276:     fd_set      *in;
     277:     fd_set      *ou;
     278:     fd_set      *ex;
     279:     struct  timespec *ts;
     280:     sigset_t    *maskp;
     281:     };
     282:
     283: /*
     284:  * Select system call.
     285: */
     286: int
     287: select()
     288:     {
     289:     struct uap
     290:         {
     291:         int nd;
     292:         fd_set  *in, *ou, *ex;
     293:         struct  timeval *tv;
     294:         } *uap = (struct uap *)u.u_ap;
     295:     register struct pselect_args *pselargs = (struct pselect_args *)uap;
     296:
     297:     /*
     298: 	 * Fake the 6th parameter of pselect.  See the comment below about the
     299: 	 * number of parameters!
     300: 	*/
     301:     pselargs->maskp = 0;
     302:     return(u.u_error = select1(pselargs, 0));
     303:     }
     304:
     305: /*
     306:  * pselect (posix select)
     307:  *
     308:  * N.B.  There is only room for 6 arguments - see user.h - so pselect() is
     309:  *       at the maximum!  See user.h
     310: */
     311: int
     312: pselect()
     313:     {
     314:     register struct pselect_args *uap = (struct pselect_args *)u.u_ap;
     315:
     316:     return(u.u_error = select1(uap, 1));
     317:     }
     318:
     319: /*
     320:  * Select helper function common to both select() and pselect()
     321:  */
     322: static int
     323: select1(uap, is_pselect)
     324:     register struct pselect_args *uap;
     325:     int is_pselect;
     326:     {
     327:     fd_set ibits[3], obits[3];
     328:     struct timeval atv;
     329:     sigset_t sigmsk;
     330:     unsigned int timo = 0;
     331:     register int error, ni;
     332:     int ncoll, s;
     333:
     334:     bzero((caddr_t)ibits, sizeof(ibits));
     335:     bzero((caddr_t)obits, sizeof(obits));
     336:     if (uap->nd > NOFILE)
     337:         uap->nd = NOFILE;   /* forgiving, if slightly wrong */
     338:     ni = howmany(uap->nd, NFDBITS);
     339:
     340: #define getbits(name, x) \
     341:     if (uap->name) { \
     342:         error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
     343:             (unsigned)(ni * sizeof(fd_mask))); \
     344:         if (error) \
     345:             goto done; \
     346:     }
     347:     getbits(in, 0);
     348:     getbits(ou, 1);
     349:     getbits(ex, 2);
     350: #undef  getbits
     351:
     352:     if  (uap->maskp)
     353:         {
     354:         error = copyin(uap->maskp, &sigmsk, sizeof(sigmsk));
     355:         sigmsk &= ~sigcantmask;
     356:         if  (error)
     357:             goto done;
     358:         }
     359:     if  (uap->ts)
     360:         {
     361:         error = copyin((caddr_t)uap->ts, (caddr_t)&atv, sizeof (atv));
     362:         if  (error)
     363:             goto done;
     364: /*
     365:  * nanoseconds ('struct timespec') on a PDP-11 are stupid since a 50 or 60 hz
     366:  * clock is all we have.   Keeping the names and logic made porting easier
     367:  * though.
     368: */
     369:         if  (is_pselect)
     370:             {
     371:             struct  timespec *ts = (struct timespec *)&atv;
     372:
     373:             if  (ts->tv_sec == 0 && ts->tv_nsec < 1000)
     374:                     atv.tv_usec = 1;
     375:                 else
     376:                     atv.tv_usec = ts->tv_nsec / 1000;
     377:             }
     378:         if  (itimerfix(&atv))
     379:             {
     380:             error = EINVAL;
     381:             goto done;
     382:             }
     383:         s = splhigh();
     384:         time.tv_usec = lbolt * mshz;
     385:         timevaladd(&atv, &time);
     386:         splx(s);
     387:         }
     388: retry:
     389:     ncoll = nselcoll;
     390:     u.u_procp->p_flag |= P_SELECT;
     391:     error = selscan(ibits, obits, uap->nd, &u.u_r.r_val1);
     392:     if  (error || u.u_r.r_val1)
     393:         goto done;
     394:     s = splhigh();
     395:     if  (uap->ts)
     396:         {
     397:         /* this should be timercmp(&time, &atv, >=) */
     398:         if  ((time.tv_sec > atv.tv_sec || (time.tv_sec == atv.tv_sec
     399:                     && lbolt * mshz >= atv.tv_usec)))
     400:             {
     401:             splx(s);
     402:             goto done;
     403:             }
     404:         timo = hzto(&atv);
     405:         if  (timo == 0)
     406:             timo = 1;
     407:         }
     408:     if  ((u.u_procp->p_flag & P_SELECT) == 0 || nselcoll != ncoll)
     409:         {
     410:         u.u_procp->p_flag &= ~P_SELECT;
     411:         splx(s);
     412:         goto retry;
     413:         }
     414:     u.u_procp->p_flag &= ~P_SELECT;
     415: /*
     416:  * If doing a pselect() need to set a temporary mask while in tsleep.
     417:  * Returning from pselect after catching a signal the old mask has to be
     418:  * restored.  Save it here and set the appropriate flag.
     419: */
     420:     if  (uap->maskp)
     421:         {
     422:         u.u_oldmask = u.u_procp->p_sigmask;
     423:         u.u_psflags |= SAS_OLDMASK;
     424:         u.u_procp->p_sigmask = sigmsk;
     425:         }
     426:     error = tsleep(&selwait, PSOCK | PCATCH, timo);
     427:     if  (uap->maskp)
     428:         u.u_procp->p_sigmask = u.u_oldmask;
     429:     splx(s);
     430:     if  (error == 0)
     431:         goto retry;
     432: done:
     433:     u.u_procp->p_flag &= ~P_SELECT;
     434:     /* select is not restarted after signals... */
     435:     if  (error == ERESTART)
     436:         error = EINTR;
     437:     if  (error == EWOULDBLOCK)
     438:         error = 0;
     439: #define putbits(name, x) \
     440:     if (uap->name && \
     441:         (error2 = copyout(&obits[x],uap->name,(ni*sizeof(fd_mask))))) \
     442:             error = error2;
     443:
     444:     if  (error == 0)
     445:         {
     446:         int error2;
     447:
     448:         putbits(in, 0);
     449:         putbits(ou, 1);
     450:         putbits(ex, 2);
     451: #undef putbits
     452:         }
     453:     return(error);
     454:     }
     455:
     456: selscan(ibits, obits, nfd, retval)
     457:     fd_set *ibits, *obits;
     458:     int nfd, *retval;
     459: {
     460:     register int i, j, flag;
     461:     fd_mask bits;
     462:     struct file *fp;
     463:     int which, n = 0;
     464:
     465:     for (which = 0; which < 3; which++) {
     466:         switch (which) {
     467:
     468:         case 0:
     469:             flag = FREAD; break;
     470:
     471:         case 1:
     472:             flag = FWRITE; break;
     473:
     474:         case 2:
     475:             flag = 0; break;
     476:         }
     477:         for (i = 0; i < nfd; i += NFDBITS) {
     478:             bits = ibits[which].fds_bits[i/NFDBITS];
     479:             while ((j = ffs(bits)) && i + --j < nfd) {
     480:                 bits &= ~(1L << j);
     481:                 fp = u.u_ofile[i + j];
     482:                 if (fp == NULL)
     483:                     return(EBADF);
     484:                 if ((*Fops[fp->f_type]->fo_select)(fp,flag)) {
     485:                     FD_SET(i + j, &obits[which]);
     486:                     n++;
     487:                 }
     488:             }
     489:         }
     490:     }
     491:     *retval = n;
     492:     return(0);
     493: }
     494:
     495: /*ARGSUSED*/
     496: seltrue(dev, flag)
     497:     dev_t dev;
     498:     int flag;
     499: {
     500:
     501:     return (1);
     502: }
     503:
     504: selwakeup(p, coll)
     505:     register struct proc *p;
     506:     long coll;
     507: {
     508:     mapinfo map;
     509:
     510:     savemap(map);
     511:     if (coll) {
     512:         nselcoll++;
     513:         wakeup((caddr_t)&selwait);
     514:     }
     515:     if (p) {
     516:         register int s = splhigh();
     517:         if (p->p_wchan == (caddr_t)&selwait) {
     518:             if (p->p_stat == SSLEEP)
     519:                 setrun(p);
     520:             else
     521:                 unsleep(p);
     522:         } else if (p->p_flag & P_SELECT)
     523:             p->p_flag &= ~P_SELECT;
     524:         splx(s);
     525:     }
     526:     restormap(map);
     527: }
     528:
     529: sorw(fp, uio)
     530:     register struct file *fp;
     531:     register struct uio *uio;
     532: {
     533: #ifdef  INET
     534:     if (uio->uio_rw == UIO_READ)
     535:         return(SORECEIVE((struct socket *)fp->f_socket, 0, uio, 0, 0));
     536:     return(SOSEND((struct socket *)fp->f_socket, 0, uio, 0, 0));
     537: #else
     538:     return (EOPNOTSUPP);
     539: #endif
     540: }
     541:
     542: soctl(fp, com, data)
     543:     struct file *fp;
     544:     u_int   com;
     545:     char    *data;
     546:     {
     547: #ifdef  INET
     548:     return (SOO_IOCTL(fp, com, data));
     549: #else
     550:     return (EOPNOTSUPP);
     551: #endif
     552: }
     553:
     554: sosel(fp, flag)
     555:     struct file *fp;
     556:     int flag;
     557: {
     558: #ifdef  INET
     559:     return (SOO_SELECT(fp, flag));
     560: #else
     561:     return (EOPNOTSUPP);
     562: #endif
     563: }
     564:
     565: socls(fp)
     566:     register struct file *fp;
     567: {
     568:     register int error = 0;
     569:
     570: #ifdef  INET
     571:     if  (fp->f_data)
     572:         error = SOCLOSE((struct socket *)fp->f_data);
     573:     fp->f_data = 0;
     574: #else
     575:     error = EOPNOTSUPP;
     576: #endif
     577:     return(error);
     578: }

#### Defined functions

ioctl defined in line 176; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 54, 164

pselect defined in line 311; used 3 times

- in /usr/src/sys/h/select.h line 65
- in /usr/src/sys/sys/init_sysent.c line 43, 175

read defined in line 39; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 54, 113

readv defined in line 57; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 54, 230

rwuio defined in line 126; used 4 times

- in line 54, 78, 99, 123

select defined in line 286; used 3 times

- in /usr/src/sys/h/select.h line 64
- in /usr/src/sys/sys/init_sysent.c line 43, 203

select1 defined in line 322; used 2 times

- in line 302, 316

selscan defined in line 456; used 1 times

- in line 391

seltrue defined in line 496; used 16 times

- in /usr/src/sys/pdp/conf.c line 357, 386-394(3), 410-446(10), 454, 462

selwakeup defined in line 504; used 14 times

- in /usr/src/sys/pdp/net_mac.h line 82-84(2)
- in /usr/src/sys/pdpuba/dz.c line 426
- in /usr/src/sys/sys/subr_log.c line 214
- in /usr/src/sys/sys/sys_pipe.c line 145, 215, 285, 291
- in /usr/src/sys/sys/tty.c line 136, 201, 1688
- in /usr/src/sys/sys/tty_pty.c line 184, 192, 289

socls defined in line 565; used 2 times

- in line 30-32(2)

soctl defined in line 542; used 2 times

- in line 30-32(2)

sorw defined in line 529; used 2 times

- in line 30-32(2)

sosel defined in line 554; used 2 times

- in line 30-32(2)

write defined in line 84; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 54, 114

writev defined in line 102; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 54, 231

#### Defined variables

Fops defined in line 34; used 5 times

- in line 169, 259, 484
- in /usr/src/sys/sys/kern_descrip.c line 215, 362

nselcoll defined in line 271; used 3 times

- in line 389, 408, 512

socketops defined in line 31; used 1 times

- in line 34

#### Defined struct's

a defined in line 179; used 12 times

- in line 45(2), 63(2), 90(2), 108(2), 138(2), 189(2)

pselect_args defined in line 273; used 10 times

- in line 295(4), 314(4), 324(2)

uap defined in line 289; used 2 times

- in line 294(2)

#### Defined macros

getbits defined in line 340; used 4 times

- in line 347-350(4)

putbits defined in line 439; used 4 times

- in line 448-451(4)

Last modified: 2000-02-29 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2136 |