From owner-freebsd-hackers Wed Sep 3 18:35:16 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id SAA23102 for hackers-outgoing; Wed, 3 Sep 1997 18:35:16 -0700 (PDT) Received: from sendero-ppp.i-connect.net (sendero-ppp.i-Connect.Net [206.190.143.100]) by hub.freebsd.org (8.8.7/8.8.7) with SMTP id SAA23095 for ; Wed, 3 Sep 1997 18:35:10 -0700 (PDT) Received: (qmail 11071 invoked by uid 1000); 4 Sep 1997 01:35:25 -0000 Message-ID: X-Mailer: XFMail 1.2-alpha [p0] on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit MIME-Version: 1.0 In-Reply-To: <199709030821.RAA00286@word.smith.net.au> Date: Wed, 03 Sep 1997 18:35:25 -0700 (PDT) Organization: Atlas Telecom From: Simon Shapiro To: Mike Smith Subject: Re: IOCTL Commands - Where is my mistake? Cc: freebsd-hackers@freebsd.org Sender: owner-freebsd-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Thax for the help Mike! Hi Mike Smith; On 03-Sep-97 you wrote: > > I want to pass IOCTL commands to a driver. This is what I do: > > > > #define DPT_IOCTL_INTERNAL_METRICS _IOW('D', 1, dpt_perf_t) > > You want to pass a pointer to the struct, not the struct itself. I do. what gave you the idea I do not? > > > switch (cmd) { > > case DPT_IOCTL_INTERNAL_METRICS: > > result = copyout((char *)&dpt->performance, > > (dpt_softc_t *)(*(caddr_t *)cmdarg), > > sizeof(dpt_perf_t)); > > This is *hideously* bogus. Try : > > caddr_t dest; > > /* get address in userspace */ > dest = fuword(*(caddr_t *)cmdarg); This is *hideously* not portable :-) You assume an integer and a char * are the same. Should be dest = (caddr_t)fuword.... > /* copy out to userspace */ > return(copyout(&dpt->performance, dest, > sizeof(dpt->performance)) > > > ie. cmdarg is a pointer in kernel space to a *copy* of the value > passed as an argument to the ioctl. This is all fine and dandy, BUT, > > You could also define the ioctl : > > #define DPT_IOCTL_INTERNAL_METRICS _IOR('D', 1, dpt_perf_t) > > and then in the kernel say : > > memcpy(cmdarg, &dpt->performance, > sizeof(dpt->performance)); > > however this will perform two copies; once as you copy it to the arg > area, and another when the ioctl returns the copy to userspace. This > approach is somewhat discouraged from an efficiency point of view. > > You would call this as : > > ioctl(fd, DPT_IOCTL_INTERNAL_METRICS, metrics) > > ie. pass the structure, not a pointer to it. Think of an ioctl define > as being like a function prototype. I did. I am still getting the SAME result. Maybe I should re-state that: If I do: #define DPT_IOCTL_INTERNAL_METRICS _IOR('D', 1, dpt_perf_t) Then copyout fails! BUT if I do: #define DPT_IOCTL_INTERNAL_METRICS (IOC_INOUT | 1) Then it WORKS. The fact that the contents of cmd (NOT the identity of cmdarg!) changes the outcome of copyout, coupled with the fact that your version, although not nearly as *hideously* bogus as mine, does NOT work, coupled to the fact that ioctl does work, leads me to belive that I am making a stupid mistake, but your solution is not indicating my error. Can we try again? Thanx! > > mike > > --- Sincerely Yours, (Sent on 03-Sep-97, 18:22:33 by XF-Mail) Simon Shapiro Atlas Telecom Senior Architect 14355 SW Allen Blvd., Suite 130 Beaverton OR 97005 Shimon@i-Connect.Net Voice: 503.643.5559, Emergency: 503.799.2313