Ejemplo n.º 1
0
int
ptyfs_close(void *v)
{
	struct vop_close_args /* {
		struct vnode *a_vp;
		int  a_fflag;
		kauth_cred_t a_cred;
	} */ *ap = v;
	struct vnode *vp = ap->a_vp;
	struct ptyfsnode *ptyfs = VTOPTYFS(vp);

	mutex_enter(&vp->v_interlock);
	if (vp->v_usecount > 1)
		PTYFS_ITIMES(ptyfs, NULL, NULL, NULL);
	mutex_exit(&vp->v_interlock);

	switch (ptyfs->ptyfs_type) {
	case PTYFSpts:
	case PTYFSptc:
		return spec_close(v);
	case PTYFSroot:
		return 0;
	default:
		return EINVAL;
	}
}
Ejemplo n.º 2
0
static int
ptyfs_update(struct vnode *vp, const struct timespec *acc,
    const struct timespec *mod, int flags)
{
	struct ptyfsnode *ptyfs = VTOPTYFS(vp);

	if (vp->v_mount->mnt_flag & MNT_RDONLY)
		return 0;

	PTYFS_ITIMES(ptyfs, acc, mod, NULL);
	return 0;
}
Ejemplo n.º 3
0
/*
 * Invent attributes for ptyfsnode (vp) and store
 * them in (vap).
 * Directories lengths are returned as zero since
 * any real length would require the genuine size
 * to be computed, and nothing cares anyway.
 *
 * this is relatively minimal for ptyfs.
 */
int
ptyfs_getattr(void *v)
{
	struct vop_getattr_args /* {
		struct vnode *a_vp;
		struct vattr *a_vap;
		kauth_cred_t a_cred;
	} */ *ap = v;
	struct ptyfsnode *ptyfs = VTOPTYFS(ap->a_vp);
	struct vattr *vap = ap->a_vap;

	PTYFS_ITIMES(ptyfs, NULL, NULL, NULL);

	/* start by zeroing out the attributes */
	VATTR_NULL(vap);

	/* next do all the common fields */
	vap->va_type = ap->a_vp->v_type;
	vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
	vap->va_fileid = ptyfs->ptyfs_fileno;
	vap->va_gen = 0;
	vap->va_flags = 0;
	vap->va_nlink = 1;
	vap->va_blocksize = PAGE_SIZE;

	vap->va_atime = ptyfs->ptyfs_atime;
	vap->va_mtime = ptyfs->ptyfs_mtime;
	vap->va_ctime = ptyfs->ptyfs_ctime;
	vap->va_birthtime = ptyfs->ptyfs_birthtime;
	vap->va_mode = ptyfs->ptyfs_mode;
	vap->va_flags = ptyfs->ptyfs_flags;
	vap->va_uid = ptyfs->ptyfs_uid;
	vap->va_gid = ptyfs->ptyfs_gid;

	switch (ptyfs->ptyfs_type) {
	case PTYFSpts:
	case PTYFSptc:
		if (pty_isfree(ptyfs->ptyfs_pty, 1))
			return ENOENT;
		vap->va_bytes = vap->va_size = 0;
		vap->va_rdev = ap->a_vp->v_rdev;
		break;
	case PTYFSroot:
		vap->va_rdev = 0;
		vap->va_bytes = vap->va_size = DEV_BSIZE;
		break;

	default:
		return EOPNOTSUPP;
	}

	return 0;
}
static void
ptyfs_getinfo(struct ptyfsnode *ptyfs, struct lwp *l)
{
	extern struct ptm_pty *ptyfs_save_ptm, ptm_ptyfspty;

	if (ptyfs->ptyfs_type == PTYFSroot) {
		ptyfs->ptyfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|
		    S_IROTH|S_IXOTH;
		goto out;
	} else
		ptyfs->ptyfs_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
		    S_IROTH|S_IWOTH;

	if (ptyfs_save_ptm != NULL && ptyfs_save_ptm != &ptm_ptyfspty) {
		int error;
		struct pathbuf *pb;
		struct nameidata nd;
		char ttyname[64];
		kauth_cred_t cred;
		struct vattr va;

		/*
		 * We support traditional ptys, so we copy the info
		 * from the inode
		 */
		if ((error = (*ptyfs_save_ptm->makename)(
			ptyfs_save_ptm, l, ttyname, sizeof(ttyname),
			ptyfs->ptyfs_pty, ptyfs->ptyfs_type == PTYFSpts ? 't'
			: 'p')) != 0)
				goto out;
		pb = pathbuf_create(ttyname);
		if (pb == NULL) {
			error = ENOMEM;
 			goto out;
		}
		NDINIT(&nd, LOOKUP, NOFOLLOW|LOCKLEAF, pb);
		if ((error = namei(&nd)) != 0) {
			pathbuf_destroy(pb);
			goto out;
		}
		cred = kauth_cred_alloc();
		error = VOP_GETATTR(nd.ni_vp, &va, cred);
		kauth_cred_free(cred);
		VOP_UNLOCK(nd.ni_vp);
		vrele(nd.ni_vp);
		pathbuf_destroy(pb);
		if (error)
			goto out;
		ptyfs->ptyfs_uid = va.va_uid;
		ptyfs->ptyfs_gid = va.va_gid;
		ptyfs->ptyfs_mode = va.va_mode;
		ptyfs->ptyfs_flags = va.va_flags;
		ptyfs->ptyfs_birthtime = va.va_birthtime;
		ptyfs->ptyfs_ctime = va.va_ctime;
		ptyfs->ptyfs_mtime = va.va_mtime;
		ptyfs->ptyfs_atime = va.va_atime;
		return;
	}
out:
	ptyfs->ptyfs_uid = ptyfs->ptyfs_gid = 0;
	ptyfs->ptyfs_status |= PTYFS_CHANGE;
	PTYFS_ITIMES(ptyfs, NULL, NULL, NULL);
	ptyfs->ptyfs_birthtime = ptyfs->ptyfs_mtime =
	    ptyfs->ptyfs_atime = ptyfs->ptyfs_ctime;
	ptyfs->ptyfs_flags = 0;
}