Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Sep 1997 21:28:11 -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.970903212811.Shimon@i-Connect.Net>
In-Reply-To: <199709040247.MAA00870@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: 
> > > > > >     #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
>  

---


Sincerely Yours,           (Sent on 03-Sep-97, 19:56:49 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.970903212811.Shimon>