static int devfs_fo_close(struct file *fp) { struct vnode *vp = (struct vnode *)fp->f_data; int error; fp->f_ops = &badfileops; error = vn_close(vp, fp->f_flag, fp); devfs_clear_cdevpriv(fp); return (error); }
/* drm_open_helper is called whenever a process opens /dev/drm. */ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, struct drm_device *dev) { struct drm_file *priv; int m = dev2unit(kdev); int retcode; if (flags & O_EXCL) return EBUSY; /* No exclusive opens */ dev->flags = flags; DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO); if (priv == NULL) { return ENOMEM; } retcode = devfs_set_cdevpriv(priv, drm_close); if (retcode != 0) { free(priv, DRM_MEM_FILES); return retcode; } DRM_LOCK(); priv->dev = dev; priv->uid = p->td_ucred->cr_svuid; priv->pid = p->td_proc->p_pid; priv->minor = m; priv->ioctl_count = 0; /* for compatibility root is always authenticated */ priv->authenticated = DRM_SUSER(p); if (dev->driver->open) { /* shared code returns -errno */ retcode = -dev->driver->open(dev, priv); if (retcode != 0) { devfs_clear_cdevpriv(); free(priv, DRM_MEM_FILES); DRM_UNLOCK(); return retcode; } } /* first opener automatically becomes master */ priv->master = TAILQ_EMPTY(&dev->files); TAILQ_INSERT_TAIL(&dev->files, priv, link); DRM_UNLOCK(); kdev->si_drv1 = dev; return 0; }