fdesc_vnops.c

来自「早期freebsd实现」· C语言 代码 · 共 975 行 · 第 1/2 页

C
975
字号
	/*	 * Can't mess with the root vnode	 */	switch (VTOFDESC(ap->a_vp)->fd_type) {	case Fdesc:		break;	case Fctty:		return (0);	default:		return (EACCES);	}	fd = VTOFDESC(ap->a_vp)->fd_fd;	if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {		return (EBADF);	}	/*	 * Can setattr the underlying vnode, but not sockets!	 */	switch (fp->f_type) {	case DTYPE_VNODE:		error = VOP_SETATTR((struct vnode *) fp->f_data, ap->a_vap, ap->a_cred, ap->a_p);		break;	case DTYPE_SOCKET:		error = 0;		break;	default:		panic("fdesc setattr");		break;	}	return (error);}#define UIO_MX 16static struct dirtmp {	u_long d_fileno;	u_short d_reclen;	u_short d_namlen;	char d_name[8];} rootent[] = {	{ FD_DEVFD, UIO_MX, 2, "fd" },	{ FD_STDIN, UIO_MX, 5, "stdin" },	{ FD_STDOUT, UIO_MX, 6, "stdout" },	{ FD_STDERR, UIO_MX, 6, "stderr" },	{ FD_CTTY, UIO_MX, 3, "tty" },	{ 0 }};intfdesc_readdir(ap)	struct vop_readdir_args /* {		struct vnode *a_vp;		struct uio *a_uio;		struct ucred *a_cred;	} */ *ap;{	struct uio *uio = ap->a_uio;	struct filedesc *fdp;	int i;	int error;	switch (VTOFDESC(ap->a_vp)->fd_type) {	case Fctty:		return (0);	case Fdesc:		return (ENOTDIR);	default:		break;	}	fdp = uio->uio_procp->p_fd;	if (VTOFDESC(ap->a_vp)->fd_type == Froot) {		struct dirent d;		struct dirent *dp = &d;		struct dirtmp *dt;		i = uio->uio_offset / UIO_MX;		error = 0;		while (uio->uio_resid > 0) {			dt = &rootent[i];			if (dt->d_fileno == 0) {				/**eofflagp = 1;*/				break;			}			i++;						switch (dt->d_fileno) {			case FD_CTTY:				if (cttyvp(uio->uio_procp) == NULL)					continue;				break;			case FD_STDIN:			case FD_STDOUT:			case FD_STDERR:				if ((dt->d_fileno-FD_STDIN) >= fdp->fd_nfiles)					continue;				if (fdp->fd_ofiles[dt->d_fileno-FD_STDIN] == NULL)					continue;				break;			}			bzero((caddr_t) dp, UIO_MX);			dp->d_fileno = dt->d_fileno;			dp->d_namlen = dt->d_namlen;			dp->d_type = DT_UNKNOWN;			dp->d_reclen = dt->d_reclen;			bcopy(dt->d_name, dp->d_name, dp->d_namlen+1);			error = uiomove((caddr_t) dp, UIO_MX, uio);			if (error)				break;		}		uio->uio_offset = i * UIO_MX;		return (error);	}	i = uio->uio_offset / UIO_MX;	error = 0;	while (uio->uio_resid > 0) {		if (i >= fdp->fd_nfiles)			break;		if (fdp->fd_ofiles[i] != NULL) {			struct dirent d;			struct dirent *dp = &d;			bzero((caddr_t) dp, UIO_MX);			dp->d_namlen = sprintf(dp->d_name, "%d", i);			dp->d_reclen = UIO_MX;			dp->d_type = DT_UNKNOWN;			dp->d_fileno = i + FD_STDIN;			/*			 * And ship to userland			 */			error = uiomove((caddr_t) dp, UIO_MX, uio);			if (error)				break;		}		i++;	}	uio->uio_offset = i * UIO_MX;	return (error);}intfdesc_readlink(ap)	struct vop_readlink_args /* {		struct vnode *a_vp;		struct uio *a_uio;		struct ucred *a_cred;	} */ *ap;{	struct vnode *vp = ap->a_vp;	int error;	if (vp->v_type != VLNK)		return (EPERM);	if (VTOFDESC(vp)->fd_type == Flink) {		char *ln = VTOFDESC(vp)->fd_link;		error = uiomove(ln, strlen(ln), ap->a_uio);	} else {		error = EOPNOTSUPP;	}	return (error);}intfdesc_read(ap)	struct vop_read_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap;{	int error = EOPNOTSUPP;	switch (VTOFDESC(ap->a_vp)->fd_type) {	case Fctty:		error = cttyread(devctty, ap->a_uio, ap->a_ioflag);		break;	default:		error = EOPNOTSUPP;		break;	}		return (error);}intfdesc_write(ap)	struct vop_write_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap;{	int error = EOPNOTSUPP;	switch (VTOFDESC(ap->a_vp)->fd_type) {	case Fctty:		error = cttywrite(devctty, ap->a_uio, ap->a_ioflag);		break;	default:		error = EOPNOTSUPP;		break;	}		return (error);}intfdesc_ioctl(ap)	struct vop_ioctl_args /* {		struct vnode *a_vp;		int  a_command;		caddr_t  a_data;		int  a_fflag;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	int error = EOPNOTSUPP;	switch (VTOFDESC(ap->a_vp)->fd_type) {	case Fctty:		error = cttyioctl(devctty, ap->a_command, ap->a_data,					ap->a_fflag, ap->a_p);		break;	default:		error = EOPNOTSUPP;		break;	}		return (error);}intfdesc_select(ap)	struct vop_select_args /* {		struct vnode *a_vp;		int  a_which;		int  a_fflags;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	int error = EOPNOTSUPP;	switch (VTOFDESC(ap->a_vp)->fd_type) {	case Fctty:		error = cttyselect(devctty, ap->a_fflags, ap->a_p);		break;	default:		error = EOPNOTSUPP;		break;	}		return (error);}intfdesc_inactive(ap)	struct vop_inactive_args /* {		struct vnode *a_vp;	} */ *ap;{	struct vnode *vp = ap->a_vp;	/*	 * Clear out the v_type field to avoid	 * nasty things happening in vgone().	 */	vp->v_type = VNON;	return (0);}intfdesc_reclaim(ap)	struct vop_reclaim_args /* {		struct vnode *a_vp;	} */ *ap;{	struct vnode *vp = ap->a_vp;	remque(VTOFDESC(vp));	FREE(vp->v_data, M_TEMP);	vp->v_data = 0;	return (0);}/* * Return POSIX pathconf information applicable to special devices. */fdesc_pathconf(ap)	struct vop_pathconf_args /* {		struct vnode *a_vp;		int a_name;		int *a_retval;	} */ *ap;{	switch (ap->a_name) {	case _PC_LINK_MAX:		*ap->a_retval = LINK_MAX;		return (0);	case _PC_MAX_CANON:		*ap->a_retval = MAX_CANON;		return (0);	case _PC_MAX_INPUT:		*ap->a_retval = MAX_INPUT;		return (0);	case _PC_PIPE_BUF:		*ap->a_retval = PIPE_BUF;		return (0);	case _PC_CHOWN_RESTRICTED:		*ap->a_retval = 1;		return (0);	case _PC_VDISABLE:		*ap->a_retval = _POSIX_VDISABLE;		return (0);	default:		return (EINVAL);	}	/* NOTREACHED */}/* * Print out the contents of a /dev/fd vnode. *//* ARGSUSED */intfdesc_print(ap)	struct vop_print_args /* {		struct vnode *a_vp;	} */ *ap;{	printf("tag VT_NON, fdesc vnode\n");	return (0);}/*void*/intfdesc_vfree(ap)	struct vop_vfree_args /* {		struct vnode *a_pvp;		ino_t a_ino;		int a_mode;	} */ *ap;{	return (0);}/* * /dev/fd vnode unsupported operation */intfdesc_enotsupp(){	return (EOPNOTSUPP);}/* * /dev/fd "should never get here" operation */intfdesc_badop(){	panic("fdesc: bad op");	/* NOTREACHED */}/* * /dev/fd vnode null operation */intfdesc_nullop(){	return (0);}#define fdesc_create ((int (*) __P((struct  vop_create_args *)))fdesc_enotsupp)#define fdesc_mknod ((int (*) __P((struct  vop_mknod_args *)))fdesc_enotsupp)#define fdesc_close ((int (*) __P((struct  vop_close_args *)))nullop)#define fdesc_access ((int (*) __P((struct  vop_access_args *)))nullop)#define fdesc_mmap ((int (*) __P((struct  vop_mmap_args *)))fdesc_enotsupp)#define fdesc_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)#define fdesc_seek ((int (*) __P((struct  vop_seek_args *)))nullop)#define fdesc_remove ((int (*) __P((struct  vop_remove_args *)))fdesc_enotsupp)#define fdesc_link ((int (*) __P((struct  vop_link_args *)))fdesc_enotsupp)#define fdesc_rename ((int (*) __P((struct  vop_rename_args *)))fdesc_enotsupp)#define fdesc_mkdir ((int (*) __P((struct  vop_mkdir_args *)))fdesc_enotsupp)#define fdesc_rmdir ((int (*) __P((struct  vop_rmdir_args *)))fdesc_enotsupp)#define fdesc_symlink ((int (*) __P((struct vop_symlink_args *)))fdesc_enotsupp)#define fdesc_abortop ((int (*) __P((struct  vop_abortop_args *)))nullop)#define fdesc_lock ((int (*) __P((struct  vop_lock_args *)))nullop)#define fdesc_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)#define fdesc_bmap ((int (*) __P((struct  vop_bmap_args *)))fdesc_badop)#define fdesc_strategy ((int (*) __P((struct  vop_strategy_args *)))fdesc_badop)#define fdesc_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)#define fdesc_advlock ((int (*) __P((struct vop_advlock_args *)))fdesc_enotsupp)#define fdesc_blkatoff \	((int (*) __P((struct  vop_blkatoff_args *)))fdesc_enotsupp)#define fdesc_vget ((int (*) __P((struct  vop_vget_args *)))fdesc_enotsupp)#define fdesc_valloc ((int(*) __P(( \		struct vnode *pvp, \		int mode, \		struct ucred *cred, \		struct vnode **vpp))) fdesc_enotsupp)#define fdesc_truncate \	((int (*) __P((struct  vop_truncate_args *)))fdesc_enotsupp)#define fdesc_update ((int (*) __P((struct  vop_update_args *)))fdesc_enotsupp)#define fdesc_bwrite ((int (*) __P((struct  vop_bwrite_args *)))fdesc_enotsupp)int (**fdesc_vnodeop_p)();struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {	{ &vop_default_desc, vn_default_error },	{ &vop_lookup_desc, fdesc_lookup },	/* lookup */	{ &vop_create_desc, fdesc_create },	/* create */	{ &vop_mknod_desc, fdesc_mknod },	/* mknod */	{ &vop_open_desc, fdesc_open },		/* open */	{ &vop_close_desc, fdesc_close },	/* close */	{ &vop_access_desc, fdesc_access },	/* access */	{ &vop_getattr_desc, fdesc_getattr },	/* getattr */	{ &vop_setattr_desc, fdesc_setattr },	/* setattr */	{ &vop_read_desc, fdesc_read },		/* read */	{ &vop_write_desc, fdesc_write },	/* write */	{ &vop_ioctl_desc, fdesc_ioctl },	/* ioctl */	{ &vop_select_desc, fdesc_select },	/* select */	{ &vop_mmap_desc, fdesc_mmap },		/* mmap */	{ &vop_fsync_desc, fdesc_fsync },	/* fsync */	{ &vop_seek_desc, fdesc_seek },		/* seek */	{ &vop_remove_desc, fdesc_remove },	/* remove */	{ &vop_link_desc, fdesc_link },		/* link */	{ &vop_rename_desc, fdesc_rename },	/* rename */	{ &vop_mkdir_desc, fdesc_mkdir },	/* mkdir */	{ &vop_rmdir_desc, fdesc_rmdir },	/* rmdir */	{ &vop_symlink_desc, fdesc_symlink },	/* symlink */	{ &vop_readdir_desc, fdesc_readdir },	/* readdir */	{ &vop_readlink_desc, fdesc_readlink },	/* readlink */	{ &vop_abortop_desc, fdesc_abortop },	/* abortop */	{ &vop_inactive_desc, fdesc_inactive },	/* inactive */	{ &vop_reclaim_desc, fdesc_reclaim },	/* reclaim */	{ &vop_lock_desc, fdesc_lock },		/* lock */	{ &vop_unlock_desc, fdesc_unlock },	/* unlock */	{ &vop_bmap_desc, fdesc_bmap },		/* bmap */	{ &vop_strategy_desc, fdesc_strategy },	/* strategy */	{ &vop_print_desc, fdesc_print },	/* print */	{ &vop_islocked_desc, fdesc_islocked },	/* islocked */	{ &vop_pathconf_desc, fdesc_pathconf },	/* pathconf */	{ &vop_advlock_desc, fdesc_advlock },	/* advlock */	{ &vop_blkatoff_desc, fdesc_blkatoff },	/* blkatoff */	{ &vop_valloc_desc, fdesc_valloc },	/* valloc */	{ &vop_vfree_desc, fdesc_vfree },	/* vfree */	{ &vop_truncate_desc, fdesc_truncate },	/* truncate */	{ &vop_update_desc, fdesc_update },	/* update */	{ &vop_bwrite_desc, fdesc_bwrite },	/* bwrite */	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }};struct vnodeopv_desc fdesc_vnodeop_opv_desc =	{ &fdesc_vnodeop_p, fdesc_vnodeop_entries };

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?