From owner-freebsd-hackers Wed Sep 3 19:49:21 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id TAA27313 for hackers-outgoing; Wed, 3 Sep 1997 19:49:21 -0700 (PDT) Received: from word.smith.net.au (ppp20.portal.net.au [202.12.71.120]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id TAA27300 for ; Wed, 3 Sep 1997 19:49:11 -0700 (PDT) Received: from word.smith.net.au (localhost.smith.net.au [127.0.0.1]) by word.smith.net.au (8.8.7/8.8.5) with ESMTP id MAA00870; Thu, 4 Sep 1997 12:17:26 +0930 (CST) Message-Id: <199709040247.MAA00870@word.smith.net.au> X-Mailer: exmh version 2.0zeta 7/24/97 To: Simon Shapiro cc: Mike Smith , freebsd-hackers@freebsd.org Subject: Re: IOCTL Commands - Where is my mistake? In-reply-to: Your message of "Wed, 03 Sep 1997 19:35:42 MST." Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Thu, 04 Sep 1997 12:17:22 +0930 From: Mike Smith Sender: owner-freebsd-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk > > > > > #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? > > > > dpt_perf_t is common lingo for a structure definition. If you mean > > that it is a pointer, then you should not be calling it that. > > I almost agree. It is a common syntax for user defined data types, as in > u_int8_t (which is not a structure, last I checked :-) Ok, you can have a pedant's hat too. It's *not* common lingo for a pointer. > Now, as you point below, the _IO{R,W,WR) macros, use the thrid argument > as the argument of sizeof. Last I checked, given ``int x;'', sizeof(int) > and sizeof(x) are the same. But given my limited knwoledge in this > matters, I must be mistaken. Just to try and prove you right, I tried > both ways. You aren't understanding me. You claim that IOC_INOUT | 1 works, however that has an encoded size of _zero_. Note that the value of the ioctl (cmd) argument DEPENDS ON THE SIZE OF THE ARGUMENT IN THE _IO* MACRO. > > Given that I am also assuming that a userspace pointer fits in a > > "word", the extra cast didn't seem worth the effort. If/when fuaddr() > > comes into the picture, I'll start using it. > > This assumption is just that; Assumption. In my days, we did NOT assume > anything about data types and what fits where. In any case, this is not > where my mistake is. Your original code was erroneous in that you were attempting to perform a copyout() operation to an address in kernel space, which is not possible. It appears that you didn't actually compare the difference between your code and mine. > > Have you bothered to print the address that you are trying to copy out > > to? You quoted this, but didn't reply. Have you? uprintf() is your friend! > > #define _IOC(inout,group,num,len) \ > > (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) > > #define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) > > #define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) > > #define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) > > /* this should be _IORW, but stdio got there first */ > > #define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) > > I read those. I still fail to see where I erred. Please nderstand, I > made a mistake. Foolish one, no doubt. But what? I was attempting to grind the sizeof() call in your face. > > I have, indeed, indicated your error. The object supplied as an > > argument to the ioctl is copied to/from kernel space dependant on the > > _IO macro flavour. The *address* of this copied object is passed to > > your ioctl handler in (cmdarg). You can either pass a user-space > > address in, and use this address as the argument to a copyout, or you > > can request that the entire structure be copied out and supply an > > entire structure. > > I tried both ways. It does not work. Thanx for the attempt... You haven't tried *correctly*. When you do, it will (surprise) work. It would appear that I have managed to confuse you, so I will try again. Following on the divergent discussion thread, the correct approach would seem to be : struct foo { int a, b; }; #define FOO_IOCTL _IOWR('F', 1, struct foo) ... struct foo bar; ... ioctl(fd, FOO_IOCTL, bar); ... case FOO_IOCTL: { struct foo oof = (struct foo *)cmdarg; ... ... } This will copy the 'bar' structure into and out of the kernel (tune with the macro to suit), and allow you to call the ioctl handler from within the kernel (eg. from one of the ABI emulation layers). I hope this a) makes sense, and b) works for you. mike