Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Sep 1997 19:35:42 -0700 (PDT)
From:      Simon Shapiro <Shimon@i-Connect.Net>
To:        Mike Smith <mike@smith.net.au>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: IOCTL Commands - Where is my mistake?
Message-ID:  <XFMail.970903193542.Shimon@i-Connect.Net>
In-Reply-To: <199709040209.LAA00716@word.smith.net.au>

next in thread | previous in thread | raw e-mail | index | archive | help

Hi Mike Smith;  On 04-Sep-97 you wrote: 
> > 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?
>  
>  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 :-)
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.

>  
> > > >     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....
>  
>  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.

> > 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!
>  
>  Have you bothered to print the address that you are trying to copy out 
>  to?
>  
> > BUT if I do:
> > 
> > #define DPT_IOCTL_INTERNAL_METRICS   (IOC_INOUT | 1)
> > 
> > Then it WORKS.
>  
>  So what?  You're the benficiary of a fencepost error in that you 
>  shouldn't be getting anything copied in or out at all.  Look at the 
>  definition of the _IO* macros :
>  
> #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?

>  
> > 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.
>  
>  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...

---


Sincerely Yours,           (Sent on 03-Sep-97, 19:25:24 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



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