-
-/*
- * Convert a user supplied file descriptor into a pointer
- * to a file structure. Only task is to check range of the descriptor.
- * Critical paths should use the GETF macro, defined in inline.h.
- */
-struct file *
-getf(f)
- register int f;
-{
- register struct file *fp;
-
- if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL) {
- u.u_error = EBADF;
- return (NULL);
- }
- return (fp);
-}
-
-/*
- * Internal form of close.
- * Decrement reference count on
- * file structure.
- * Also make sure the pipe protocol
- * does not constipate.
- *
- * Decrement reference count on the inode following
- * removal to the referencing file structure.
- * Call device handler on last close.
- * Nouser indicates that the user isn't available to present
- * errors to.
- */
-closef(fp, nouser)
- register struct file *fp;
-{
- register struct inode *ip;
- register struct mount *mp;
- int flag, mode;
- dev_t dev;
- register int (*cfunc)();
-
- if (fp == NULL)
- return;
- if (fp->f_count > 1) {
- fp->f_count--;
- return;
- }
- flag = fp->f_flag;
- if (flag & FSOCKET) {
- u.u_error = 0; /* XXX */
- soclose(fp->f_socket, nouser);
- if (nouser == 0 && u.u_error)
- return;
- fp->f_socket = 0;
- fp->f_count = 0;
- return;
- }
- ip = fp->f_inode;
- dev = (dev_t)ip->i_rdev;
- mode = ip->i_mode & IFMT;
- ilock(ip);
- iput(ip);
- fp->f_count = 0;
-
- switch (mode) {
-
- case IFCHR:
- cfunc = cdevsw[major(dev)].d_close;
- break;
-
- case IFBLK:
- /*
- * We don't want to really close the device if it is mounted
- */
- for (mp = mount; mp < &mount[NMOUNT]; mp++)
- if (mp->m_bufp != NULL && mp->m_dev == dev)
- return;
- cfunc = bdevsw[major(dev)].d_close;
- break;
-
- default:
- return;
- }
- for (fp = file; fp < fileNFILE; fp++) {
- if (fp->f_flag & FSOCKET)
- continue;
- if (fp->f_count && (ip = fp->f_inode) &&
- ip->i_rdev == dev && (ip->i_mode&IFMT) == mode)
- return;
- }
- if (mode == IFBLK) {
- /*
- * On last close of a block device (that isn't mounted)
- * we must invalidate any in core blocks
- */
- bflush(dev);
- binval(dev);
- }
- (*cfunc)(dev, flag, fp);
-}