Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Jul 2006 20:08:01 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 100651 for review
Message-ID:  <200607052008.k65K8196044539@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100651

Change 100651 by jhb@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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607052008.k65K8196044539>