PERFORCE change 100651 for review
John Baldwin
jhb at FreeBSD.org
Wed Jul 5 20:08:10 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100651
Change 100651 by jhb at jhb_mutex on 2006/07/05 20:07:11
Add a kern_ioctl() which assumes data points to a KVM buffer for
ioctl's that act on buffers and use it in xenix_rdchk() to stop
using stackgap. There might be several places that currently do
fget() / fo_ioctl() / fdrop() themselves that might be able to be
simplified slightly to just do kern_ioctl() now.
Affected files ...
.. //depot/projects/smpng/sys/i386/ibcs2/ibcs2_xenix.c#14 edit
.. //depot/projects/smpng/sys/kern/sys_generic.c#44 edit
.. //depot/projects/smpng/sys/sys/syscallsubr.h#40 edit
Differences ...
==== //depot/projects/smpng/sys/i386/ibcs2/ibcs2_xenix.c#14 (text+ko) ====
@@ -84,18 +84,15 @@
struct thread *td;
struct xenix_rdchk_args *uap;
{
- int error;
- struct ioctl_args sa;
- caddr_t sg = stackgap_init();
+ int data, error;
DPRINTF(("IBCS2: 'xenix rdchk'\n"));
- sa.fd = uap->fd;
- sa.com = FIONREAD;
- sa.data = stackgap_alloc(&sg, sizeof(int));
- if ((error = ioctl(td, &sa)) != 0)
- return error;
- td->td_retval[0] = (*((int*)sa.data)) ? 1 : 0;
- return 0;
+
+ error = kern_ioctl(td, uap->fd, FIONREAD, &data);
+ if (error)
+ return (error);
+ td->td_retval[0] = data ? 1 : 0;
+ return (0);
}
int
==== //depot/projects/smpng/sys/kern/sys_generic.c#44 (text+ko) ====
@@ -523,13 +523,10 @@
int
ioctl(struct thread *td, struct ioctl_args *uap)
{
- struct file *fp;
- struct filedesc *fdp;
u_long com;
- int error = 0;
+ int error;
u_int size;
caddr_t data, memp;
- int tmp;
if (uap->com > 0xffffffff) {
printf(
@@ -537,27 +534,7 @@
td->td_proc->p_pid, td->td_proc->p_comm, uap->com);
uap->com &= 0xffffffff;
}
- if ((error = fget(td, uap->fd, &fp)) != 0)
- return (error);
- if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
- fdrop(fp, td);
- return (EBADF);
- }
- fdp = td->td_proc->p_fd;
- switch (com = uap->com) {
- case FIONCLEX:
- FILEDESC_LOCK_FAST(fdp);
- fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
- FILEDESC_UNLOCK_FAST(fdp);
- fdrop(fp, td);
- return (0);
- case FIOCLEX:
- FILEDESC_LOCK_FAST(fdp);
- fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
- FILEDESC_UNLOCK_FAST(fdp);
- fdrop(fp, td);
- return (0);
- }
+ com = uap->com;
/*
* Interpret high order word to find amount of data to be
@@ -571,10 +548,8 @@
#else
((com & (IOC_IN | IOC_OUT)) && size == 0) ||
#endif
- ((com & IOC_VOID) && size > 0)) {
- fdrop(fp, td);
+ ((com & IOC_VOID) && size > 0))
return (ENOTTY);
- }
if (size > 0) {
memp = malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
@@ -587,7 +562,6 @@
error = copyin(uap->data, data, (u_int)size);
if (error) {
free(memp, M_IOCTLOPS);
- fdrop(fp, td);
return (error);
}
} else if (com & IOC_OUT) {
@@ -598,7 +572,43 @@
bzero(data, size);
}
- if (com == FIONBIO) {
+ error = kern_ioctl(td, uap->fd, com, data);
+
+ if (error == 0 && (com & IOC_OUT))
+ error = copyout(data, uap->data, (u_int)size);
+
+ if (memp != NULL)
+ free(memp, M_IOCTLOPS);
+ return (error);
+}
+
+int
+kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data)
+{
+ struct file *fp;
+ struct filedesc *fdp;
+ int error;
+ int tmp;
+
+ if ((error = fget(td, fd, &fp)) != 0)
+ return (error);
+ if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
+ fdrop(fp, td);
+ return (EBADF);
+ }
+ fdp = td->td_proc->p_fd;
+ switch (com) {
+ case FIONCLEX:
+ FILEDESC_LOCK_FAST(fdp);
+ fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
+ FILEDESC_UNLOCK_FAST(fdp);
+ goto out;
+ case FIOCLEX:
+ FILEDESC_LOCK_FAST(fdp);
+ fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
+ FILEDESC_UNLOCK_FAST(fdp);
+ goto out;
+ case FIONBIO:
FILE_LOCK(fp);
if ((tmp = *(int *)data))
fp->f_flag |= FNONBLOCK;
@@ -606,7 +616,8 @@
fp->f_flag &= ~FNONBLOCK;
FILE_UNLOCK(fp);
data = (void *)&tmp;
- } else if (com == FIOASYNC) {
+ break;
+ case FIOASYNC:
FILE_LOCK(fp);
if ((tmp = *(int *)data))
fp->f_flag |= FASYNC;
@@ -614,15 +625,11 @@
fp->f_flag &= ~FASYNC;
FILE_UNLOCK(fp);
data = (void *)&tmp;
+ break;
}
error = fo_ioctl(fp, com, data, td->td_ucred, td);
-
- if (error == 0 && (com & IOC_OUT))
- error = copyout(data, uap->data, (u_int)size);
-
- if (memp != NULL)
- free(memp, M_IOCTLOPS);
+out:
fdrop(fp, td);
return (error);
}
==== //depot/projects/smpng/sys/sys/syscallsubr.h#40 (text+ko) ====
@@ -92,6 +92,7 @@
socklen_t *alen);
int kern_getsockopt(struct thread *td, int s, int level, int name,
void *optval, enum uio_seg valseg, socklen_t *valsize);
+int kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data);
int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout);
int kern_kldload(struct thread *td, const char *file, int *fileid);
More information about the p4-projects
mailing list