Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Apr 1996 18:44:16 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        dchapes@zeus.leitch.com, jfrancis@frii.com
Cc:        hackers@FreeBSD.org, hsu@FreeBSD.org
Subject:   Re: Device Driver ioctl() help
Message-ID:  <199604220844.SAA26914@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>>	In my user-level code, I can call `ioctl(fd,STUFF,0x69)'.  In

>    Ack!!  RTFM, ioctl's third argument is a pointer.

`man ioctl' says that it is a pointer of type `char *', but this is yet
another bug in the man pages, or perhaps in the system headers.
<sys/ioctl.h> says that the third arg is `...'.  Some ioctls don't require
it.  The system assumes that the arg is a `void *'.  Most applications
probably pass an `int *' or a `struct foo *' and the change from `char *'
to `...' broke these on systems where `int *' and `struct foo *' aren't
like `char *' (no conversions occur for `...').

>ie: header:
>	#define MYDEV_CMD1	_IOW(0,1,int)
>user code:
>	int arg = 42;
>	ioctl(fd,MYDEV_CMD1,&arg)
                            ^^^^ one of "most applications" :-)

>int
>mydev_ioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p)
                                 ^^^^^^^
The `int *' has become a caddr_t via one bogus conversion, one copy operation
and one non-bogus conversion.  This is all hidden in the upper layers of
ioctl() - drivers don't have to worry about it.

>{
>	switch(cmd) {
>	case MYDEV_CMD1:
>		if( *(int*)data == 42 )
                    ^^^^^^^

Drivers do have to worry about converting back to the original type of
the data.

Bruce



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