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

##### Functions

    close             X
    closef            X
    dup               X
    dup2              X
    dupfdopen         X
    dupit             X
    falloc            X
    fcntl             X
    fdopen            X
    fgetown           X
    fioctl            X
    flock             X
    fset              X
    fsetown           X
    fstat             X
    getdtablesize     X
    getf              X
    ufalloc           X

##### Variables

    lastf             X

##### struct's

    a                 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:  *	@(#)kern_descrip.c	1.6 (2.11BSD) 1999/9/13
       7:  */
       8:
       9: #include "param.h"
      10: #include "user.h"
      11: #include "proc.h"
      12: #include "file.h"
      13: #include "systm.h"
      14: #include "inode.h"
      15: #include "ioctl.h"
      16: #include "stat.h"
      17: #include "conf.h"
      18: #ifdef INET
      19: #include "socket.h"
      20: #include "socketvar.h"
      21: #endif
      22: #include <syslog.h>
      23:
      24: /*
      25:  * Descriptor management.
      26:  */
      27:
      28: /*
      29:  * System calls on descriptors.
      30:  */
      31: getdtablesize()
      32: {
      33:
      34:     u.u_r.r_val1 = NOFILE;
      35: }
      36:
      37: dup()
      38: {
      39:     register struct a {
      40:         int i;
      41:     } *uap = (struct a *) u.u_ap;
      42:     register struct file *fp;
      43:     register int j;
      44:
      45:     if (uap->i &~ 077) { uap->i &= 077; dup2(); return; }   /* XXX */
      46:
      47:     GETF(fp, uap->i);
      48:     j = ufalloc(0);
      49:     if (j < 0)
      50:         return;
      51:     dupit(j, fp, u.u_pofile[uap->i] &~ UF_EXCLOSE);
      52: }
      53:
      54: dup2()
      55: {
      56:     register struct a {
      57:         int i, j;
      58:     } *uap = (struct a *) u.u_ap;
      59:     register struct file *fp;
      60:
      61:     GETF(fp, uap->i);
      62:     if (uap->j < 0 || uap->j >= NOFILE) {
      63:         u.u_error = EBADF;
      64:         return;
      65:     }
      66:     u.u_r.r_val1 = uap->j;
      67:     if (uap->i == uap->j)
      68:         return;
      69:     if (u.u_ofile[uap->j])
      70:         /*
      71: 		 * dup2 must succeed even if the close has an error.
      72: 		 */
      73:         (void) closef(u.u_ofile[uap->j]);
      74:     dupit(uap->j, fp, u.u_pofile[uap->i] &~ UF_EXCLOSE);
      75: }
      76:
      77: dupit(fd, fp, flags)
      78:     register int fd;
      79:     register struct file *fp;
      80:     int flags;
      81: {
      82:
      83:     u.u_ofile[fd] = fp;
      84:     u.u_pofile[fd] = flags;
      85:     fp->f_count++;
      86:     if (fd > u.u_lastfile)
      87:         u.u_lastfile = fd;
      88: }
      89:
      90: /*
      91:  * The file control system call.
      92:  */
      93: fcntl()
      94: {
      95:     register struct file *fp;
      96:     register struct a {
      97:         int fdes;
      98:         int cmd;
      99:         int arg;
     100:     } *uap;
     101:     register i;
     102:     register char *pop;
     103:
     104:     uap = (struct a *)u.u_ap;
     105:     if ((fp = getf(uap->fdes)) == NULL)
     106:         return;
     107:     pop = &u.u_pofile[uap->fdes];
     108:     switch(uap->cmd) {
     109:     case F_DUPFD:
     110:         i = uap->arg;
     111:         if (i < 0 || i >= NOFILE) {
     112:             u.u_error = EINVAL;
     113:             return;
     114:         }
     115:         if ((i = ufalloc(i)) < 0)
     116:             return;
     117:         dupit(i, fp, *pop &~ UF_EXCLOSE);
     118:         break;
     119:
     120:     case F_GETFD:
     121:         u.u_r.r_val1 = *pop & 1;
     122:         break;
     123:
     124:     case F_SETFD:
     125:         *pop = (*pop &~ 1) | (uap->arg & 1);
     126:         break;
     127:
     128:     case F_GETFL:
     129:         u.u_r.r_val1 = OFLAGS(fp->f_flag);
     130:         break;
     131:
     132:     case F_SETFL:
     133:         fp->f_flag &= ~FCNTLFLAGS;
     134:         fp->f_flag |= (FFLAGS(uap->arg)) & FCNTLFLAGS;
     135:         u.u_error = fset(fp, FNONBLOCK, fp->f_flag & FNONBLOCK);
     136:         if (u.u_error)
     137:             break;
     138:         u.u_error = fset(fp, FASYNC, fp->f_flag & FASYNC);
     139:         if (u.u_error)
     140:             (void) fset(fp, FNONBLOCK, 0);
     141:         break;
     142:
     143:     case F_GETOWN:
     144:         u.u_error = fgetown(fp, &u.u_r.r_val1);
     145:         break;
     146:
     147:     case F_SETOWN:
     148:         u.u_error = fsetown(fp, uap->arg);
     149:         break;
     150:
     151:     default:
     152:         u.u_error = EINVAL;
     153:     }
     154: }
     155:
     156: fset(fp, bit, value)
     157: register struct file *fp;
     158:     int bit, value;
     159: {
     160:
     161:     if (value)
     162:         fp->f_flag |= bit;
     163:     else
     164:         fp->f_flag &= ~bit;
     165:     return (fioctl(fp, (u_int)(bit == FNONBLOCK ? FIONBIO : FIOASYNC),
     166:             (caddr_t)&value));
     167: }
     168:
     169: fgetown(fp, valuep)
     170:     register struct file *fp;
     171:     register int *valuep;
     172: {
     173:     register int error;
     174:
     175: #ifdef INET
     176:     if (fp->f_type == DTYPE_SOCKET) {
     177:         *valuep = mfsd(&fp->f_socket->so_pgrp);
     178:         return (0);
     179:     }
     180: #endif
     181:     error = fioctl(fp, (u_int)TIOCGPGRP, (caddr_t)valuep);
     182:     *valuep = -*valuep;
     183:     return (error);
     184: }
     185:
     186: fsetown(fp, value)
     187:     register struct file *fp;
     188:     int value;
     189: {
     190:
     191: #ifdef INET
     192:     if (fp->f_type == DTYPE_SOCKET) {
     193:         mtsd(&fp->f_socket->so_pgrp, value);
     194:         return (0);
     195:     }
     196: #endif
     197:     if (value > 0) {
     198:         register struct proc *p = pfind(value);
     199:         if (p == 0)
     200:             return (ESRCH);
     201:         value = p->p_pgrp;
     202:     } else
     203:         value = -value;
     204:     return (fioctl(fp, (u_int)TIOCSPGRP, (caddr_t)&value));
     205: }
     206:
     207: extern  struct  fileops *Fops[];
     208:
     209: fioctl(fp, cmd, value)
     210: register struct file *fp;
     211:     u_int cmd;
     212:     caddr_t value;
     213: {
     214:
     215:     return ((*Fops[fp->f_type]->fo_ioctl)(fp, cmd, value));
     216: }
     217:
     218: close()
     219: {
     220:     register struct a {
     221:         int i;
     222:     } *uap = (struct a *)u.u_ap;
     223:     register struct file *fp;
     224:
     225:     GETF(fp, uap->i);
     226:     u.u_ofile[uap->i] = NULL;
     227:     while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
     228:         u.u_lastfile--;
     229:     u.u_error = closef(fp);
     230:     /* WHAT IF u.u_error ? */
     231: }
     232:
     233: fstat()
     234: {
     235:     register struct file *fp;
     236:     register struct a {
     237:         int fdes;
     238:         struct  stat *sb;
     239:     } *uap;
     240:     struct stat ub;
     241:
     242:     uap = (struct a *)u.u_ap;
     243:     if ((fp = getf(uap->fdes)) == NULL)
     244:         return;
     245:     switch (fp->f_type) {
     246:
     247:     case DTYPE_PIPE:
     248:     case DTYPE_INODE:
     249:         u.u_error = ino_stat((struct inode *)fp->f_data, &ub);
     250:         if (fp->f_type == DTYPE_PIPE)
     251:             ub.st_size -= fp->f_offset;
     252:         break;
     253:
     254: #ifdef INET
     255:     case DTYPE_SOCKET:
     256:         u.u_error = SOO_STAT(fp->f_socket, &ub);
     257:         break;
     258: #endif
     259:     default:
     260:         u.u_error = EINVAL;
     261:         break;
     262:     }
     263:     if (u.u_error == 0)
     264:         u.u_error = copyout((caddr_t)&ub, (caddr_t)uap->sb,
     265:             sizeof (ub));
     266: }
     267:
     268: /* copied, for supervisory networking, to sys_net.c */
     269: /*
     270:  * Allocate a user file descriptor.
     271:  */
     272: ufalloc(i)
     273:     register int i;
     274: {
     275:
     276:     for (; i < NOFILE; i++)
     277:         if (u.u_ofile[i] == NULL) {
     278:             u.u_r.r_val1 = i;
     279:             u.u_pofile[i] = 0;
     280:             if (i > u.u_lastfile)
     281:                 u.u_lastfile = i;
     282:             return (i);
     283:         }
     284:     u.u_error = EMFILE;
     285:     return (-1);
     286: }
     287:
     288: struct  file *lastf;
     289: /*
     290:  * Allocate a user file descriptor
     291:  * and a file structure.
     292:  * Initialize the descriptor
     293:  * to point at the file structure.
     294:  */
     295: struct file *
     296: falloc()
     297: {
     298:     register struct file *fp;
     299:     register i;
     300:
     301:     i = ufalloc(0);
     302:     if (i < 0)
     303:         return (NULL);
     304:     if (lastf == 0)
     305:         lastf = file;
     306:     for (fp = lastf; fp < fileNFILE; fp++)
     307:         if (fp->f_count == 0)
     308:             goto slot;
     309:     for (fp = file; fp < lastf; fp++)
     310:         if (fp->f_count == 0)
     311:             goto slot;
     312:     tablefull("file");
     313:     u.u_error = ENFILE;
     314:     return (NULL);
     315: slot:
     316:     u.u_ofile[i] = fp;
     317:     fp->f_count = 1;
     318:     fp->f_data = 0;
     319:     fp->f_offset = 0;
     320:     lastf = fp + 1;
     321:     return (fp);
     322: }
     323:
     324: /*
     325:  * Convert a user supplied file descriptor into a pointer
     326:  * to a file structure.  Only task is to check range of the descriptor.
     327:  * Critical paths should use the GETF macro unless code size is a
     328:  * consideration.
     329:  */
     330: struct file *
     331: getf(f)
     332:     register int f;
     333: {
     334:     register struct file *fp;
     335:
     336:     if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL) {
     337:         u.u_error = EBADF;
     338:         return (NULL);
     339:     }
     340:     return (fp);
     341: }
     342:
     343: /*
     344:  * Internal form of close.
     345:  * Decrement reference count on file structure.
     346:  */
     347: closef(fp)
     348:     register struct file *fp;
     349: {
     350:     int error;
     351:
     352:     if (fp == NULL)
     353:         return(0);
     354:     if (fp->f_count > 1) {
     355:         fp->f_count--;
     356:         return(0);
     357:     }
     358:
     359:     if  ((fp->f_flag & (FSHLOCK|FEXLOCK)) && fp->f_type == DTYPE_INODE)
     360:         ino_unlock(fp, FSHLOCK|FEXLOCK);
     361:
     362:     error = (*Fops[fp->f_type]->fo_close)(fp);
     363:     fp->f_count = 0;
     364:     return(error);
     365: }
     366:
     367: /*
     368:  * Apply an advisory lock on a file descriptor.
     369:  */
     370: flock()
     371: {
     372:     register struct a {
     373:         int fd;
     374:         int how;
     375:     } *uap = (struct a *)u.u_ap;
     376:     register struct file *fp;
     377:     int error;
     378:
     379:     if ((fp = getf(uap->fd)) == NULL)
     380:         return;
     381:     if (fp->f_type != DTYPE_INODE) {
     382:         u.u_error = EOPNOTSUPP;
     383:         return;
     384:     }
     385:     if (uap->how & LOCK_UN) {
     386:         ino_unlock(fp, FSHLOCK | FEXLOCK);
     387:         return;
     388:     }
     389:     if ((uap->how & (LOCK_SH | LOCK_EX)) == 0)
     390:         return;                 /* error? */
     391:     if (uap->how & LOCK_EX)
     392:         uap->how &= ~LOCK_SH;
     393:     /* avoid work... */
     394:     if ((fp->f_flag & FEXLOCK) && (uap->how & LOCK_EX) ||
     395:         (fp->f_flag & FSHLOCK) && (uap->how & LOCK_SH))
     396:         return;
     397:     error = ino_lock(fp, uap->how);
     398:     return(u.u_error = error);
     399: }
     400:
     401: /*
     402:  * File Descriptor pseudo-device driver (/dev/fd/).
     403:  *
     404:  * Opening minor device N dup()s the file (if any) connected to file
     405:  * descriptor N belonging to the calling process.  Note that this driver
     406:  * consists of only the ``open()'' routine, because all subsequent
     407:  * references to this file will be direct to the other driver.
     408:  */
     409: /* ARGSUSED */
     410: fdopen(dev, mode, type)
     411:     dev_t dev;
     412:     int mode, type;
     413:     {
     414:
     415:     /*
     416: 	 * XXX Kludge: set u.u_dupfd to contain the value of the
     417: 	 * the file descriptor being sought for duplication. The error
     418: 	 * return ensures that the vnode for this device will be released
     419: 	 * by vn_open. Open will detect this special error and take the
     420: 	 * actions in dupfdopen below. Other callers of vn_open will
     421: 	 * simply report the error.
     422: 	 */
     423:     u.u_dupfd = minor(dev);
     424:     return(ENODEV);
     425:     }
     426:
     427: /*
     428:  * Duplicate the specified descriptor to a free descriptor.
     429:  */
     430: dupfdopen(indx, dfd, mode, error)
     431:     register int indx, dfd;
     432:     int mode;
     433:     int error;
     434:     {
     435:     register register struct file *wfp;
     436:     struct file *fp;
     437:
     438:     /*
     439: 	 * If the to-be-dup'd fd number is greater than the allowed number
     440: 	 * of file descriptors, or the fd to be dup'd has already been
     441: 	 * closed, reject.  Note, check for new == old is necessary as
     442: 	 * falloc could allocate an already closed to-be-dup'd descriptor
     443: 	 * as the new descriptor.
     444: 	 */
     445:     fp = u.u_ofile[indx];
     446:     if  (dfd >= NOFILE || (wfp = u.u_ofile[dfd]) == NULL || fp == wfp)
     447:         return(EBADF);
     448:
     449:     /*
     450: 	 * There are two cases of interest here.
     451: 	 *
     452: 	 * For ENODEV simply dup (dfd) to file descriptor
     453: 	 * (indx) and return.
     454: 	 *
     455: 	 * For ENXIO steal away the file structure from (dfd) and
     456: 	 * store it in (indx).  (dfd) is effectively closed by
     457: 	 * this operation.
     458: 	 *
     459: 	 * NOTE: ENXIO only comes out of the 'portal fs' code of 4.4 - since
     460: 	 * 2.11BSD does not implement the portal fs the code is ifdef'd out
     461: 	 * and a short message output.
     462: 	 *
     463: 	 * Any other error code is just returned.
     464: 	 */
     465:     switch  (error) {
     466:     case ENODEV:
     467:         /*
     468: 		 * Check that the mode the file is being opened for is a
     469: 		 * subset of the mode of the existing descriptor.
     470: 		 */
     471:         if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
     472:             return(EACCES);
     473:         u.u_ofile[indx] = wfp;
     474:         u.u_pofile[indx] = u.u_pofile[dfd];
     475:         wfp->f_count++;
     476:         if  (indx > u.u_lastfile)
     477:             u.u_lastfile = indx;
     478:         return(0);
     479: #ifdef  haveportalfs
     480:     case ENXIO:
     481:         /*
     482: 		 * Steal away the file pointer from dfd, and stuff it into indx.
     483: 		 */
     484:         fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
     485:         fdp->fd_ofiles[dfd] = NULL;
     486:         fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
     487:         fdp->fd_ofileflags[dfd] = 0;
     488:         /*
     489: 		 * Complete the clean up of the filedesc structure by
     490: 		 * recomputing the various hints.
     491: 		 */
     492:         if (indx > fdp->fd_lastfile)
     493:             fdp->fd_lastfile = indx;
     494:         else
     495:             while (fdp->fd_lastfile > 0 &&
     496:                    fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
     497:                 fdp->fd_lastfile--;
     498:             if (dfd < fdp->fd_freefile)
     499:                 fdp->fd_freefile = dfd;
     500:         return (0);
     501: #else
     502:         log(LOG_NOTICE, "dupfdopen");
     503:         /* FALLTHROUGH */
     504: #endif
     505:     default:
     506:         return(error);
     507:     }
     508:     /* NOTREACHED */
     509: }

#### Defined functions

close defined in line 218; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 42, 116

closef defined in line 347; used 6 times

- in line 73, 229
- in /usr/src/sys/sys/kern_exec.c line 352
- in /usr/src/sys/sys/kern_exit.c line 68
- in /usr/src/sys/sys/sys_kern.c line 172
- in /usr/src/sys/sys/ufs_syscalls.c line 184

dup defined in line 37; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 42, 151

dup2 defined in line 54; used 3 times

- in line 45
- in /usr/src/sys/sys/init_sysent.c line 42, 200

dupfdopen defined in line 430; used 1 times

- in /usr/src/sys/sys/ufs_syscalls.c line 160

dupit defined in line 77; used 3 times

- in line 51, 74, 117

falloc defined in line 295; used 8 times

- in /usr/src/sys/h/file.h line 47
- in /usr/src/sys/sys/sys_pipe.c line 65, 71
- in /usr/src/sys/sys/ufs_syscalls.c line 132
- in /usr/src/sys/sys/uipc_syscalls.c line 61, 159, 257, 264

fcntl defined in line 93; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 43, 202

fdopen defined in line 410; used 2 times

- in /usr/src/sys/pdp/conf.c line 356, 465

fgetown defined in line 169; used 2 times

- in line 144
- in /usr/src/sys/sys/sys_generic.c line 256

fioctl defined in line 209; used 3 times

- in line 165, 181, 204

flock defined in line 370; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 43, 241

fset defined in line 156; used 5 times

- in line 135-140(3)
- in /usr/src/sys/sys/sys_generic.c line 244-248(2)

fsetown defined in line 186; used 2 times

- in line 148
- in /usr/src/sys/sys/sys_generic.c line 252

fstat defined in line 233; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 59, 172

getdtablesize defined in line 31; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 42, 199

getf defined in line 330; used 8 times

- in line 105, 243, 379
- in /usr/src/sys/h/file.h line 46
- in /usr/src/sys/sys/sys_generic.c line 190
- in /usr/src/sys/sys/ufs_syscalls.c line 747
- in /usr/src/sys/sys/ufs_syscalls2.c line 220
- in /usr/src/sys/sys/uipc_syscalls.c line 771

ufalloc defined in line 272; used 5 times

- in line 48, 115, 301
- in /usr/src/sys/sys/uipc_syscalls.c line 155
- in /usr/src/sys/sys/uipc_usrreq.c line 508

#### Defined variables

lastf defined in line 288; used 5 times

- in line 304-309(4), 320

#### Defined struct's

a defined in line 372; used 12 times

- in line 41(2), 58(2), 104(2), 222(2), 242(2), 375(2)

Last modified: 1999-09-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1486 |