Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/devfs/devfs_vnops.c
Show First 20 Lines • Show All 761 Lines • ▼ Show 20 Lines | devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td) | ||||
fpop = td->td_fpop; | fpop = td->td_fpop; | ||||
td->td_fpop = fp; | td->td_fpop = fp; | ||||
error = vnops.fo_ioctl(fp, com, data, cred, td); | error = vnops.fo_ioctl(fp, com, data, cred, td); | ||||
td->td_fpop = fpop; | td->td_fpop = fpop; | ||||
return (error); | return (error); | ||||
} | } | ||||
void * | |||||
fiodgname_buf_get_ptr(void *fgnp, u_long com) | |||||
{ | |||||
union { | |||||
struct fiodgname_arg fgn; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
struct fiodgname_arg32 fgn32; | |||||
#endif | |||||
} *fgnup; | |||||
fgnup = fgnp; | |||||
switch (com) { | |||||
case FIODGNAME: | |||||
return (fgnup->fgn.buf); | |||||
#ifdef COMPAT_FREEBSD32 | |||||
case FIODGNAME_32: | |||||
return ((void *)(uintptr_t)fgnup->fgn32.buf); | |||||
#endif | |||||
default: | |||||
panic("Unhandled ioctl command %ld", com); | |||||
} | |||||
} | |||||
static int | static int | ||||
devfs_ioctl(struct vop_ioctl_args *ap) | devfs_ioctl(struct vop_ioctl_args *ap) | ||||
{ | { | ||||
struct fiodgname_arg *fgn; | struct fiodgname_arg *fgn; | ||||
struct vnode *vpold, *vp; | struct vnode *vpold, *vp; | ||||
struct cdevsw *dsw; | struct cdevsw *dsw; | ||||
struct thread *td; | struct thread *td; | ||||
struct cdev *dev; | struct cdev *dev; | ||||
int error, ref, i; | int error, ref, i; | ||||
const char *p; | const char *p; | ||||
u_long com; | u_long com; | ||||
vp = ap->a_vp; | vp = ap->a_vp; | ||||
com = ap->a_command; | com = ap->a_command; | ||||
td = ap->a_td; | td = ap->a_td; | ||||
dsw = devvn_refthread(vp, &dev, &ref); | dsw = devvn_refthread(vp, &dev, &ref); | ||||
if (dsw == NULL) | if (dsw == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
KASSERT(dev->si_refcount > 0, | KASSERT(dev->si_refcount > 0, | ||||
("devfs: un-referenced struct cdev *(%s)", devtoname(dev))); | ("devfs: un-referenced struct cdev *(%s)", devtoname(dev))); | ||||
if (com == FIODTYPE) { | switch (com) { | ||||
case FIODTYPE: | |||||
*(int *)ap->a_data = dsw->d_flags & D_TYPEMASK; | *(int *)ap->a_data = dsw->d_flags & D_TYPEMASK; | ||||
error = 0; | error = 0; | ||||
goto out; | break; | ||||
} else if (com == FIODGNAME) { | case FIODGNAME: | ||||
#ifdef COMPAT_FREEBSD32 | |||||
case FIODGNAME_32: | |||||
#endif | |||||
fgn = ap->a_data; | fgn = ap->a_data; | ||||
p = devtoname(dev); | p = devtoname(dev); | ||||
i = strlen(p) + 1; | i = strlen(p) + 1; | ||||
if (i > fgn->len) | if (i > fgn->len) | ||||
error = EINVAL; | error = EINVAL; | ||||
else | else | ||||
error = copyout(p, fgn->buf, i); | error = copyout(p, fiodgname_buf_get_ptr(fgn, com), i); | ||||
goto out; | break; | ||||
default: | |||||
error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td); | |||||
} | } | ||||
error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td); | |||||
out: | |||||
dev_relthread(dev, ref); | dev_relthread(dev, ref); | ||||
if (error == ENOIOCTL) | if (error == ENOIOCTL) | ||||
error = ENOTTY; | error = ENOTTY; | ||||
if (error == 0 && com == TIOCSCTTY) { | if (error == 0 && com == TIOCSCTTY) { | ||||
/* Do nothing if reassigning same control tty */ | /* Do nothing if reassigning same control tty */ | ||||
sx_slock(&proctree_lock); | sx_slock(&proctree_lock); | ||||
if (td->td_proc->p_session->s_ttyvp == vp) { | if (td->td_proc->p_session->s_ttyvp == vp) { | ||||
▲ Show 20 Lines • Show All 1,149 Lines • Show Last 20 Lines |