Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 04 Sep 1997 12:17:22 +0930
From:      Mike Smith <mike@smith.net.au>
To:        Simon Shapiro <Shimon@i-Connect.Net>
Cc:        Mike Smith <mike@smith.net.au>, freebsd-hackers@freebsd.org
Subject:   Re: IOCTL Commands - Where is my mistake? 
Message-ID:  <199709040247.MAA00870@word.smith.net.au>
In-Reply-To: Your message of "Wed, 03 Sep 1997 19:35:42 MST." <XFMail.970903193542.Shimon@i-Connect.Net> 

next in thread | previous in thread | raw e-mail | index | archive | help
> > > > >     #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;
...
		<access foo via oof>
...
	}

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




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