From owner-freebsd-hackers Mon Apr 22 01:47:42 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id BAA22598 for hackers-outgoing; Mon, 22 Apr 1996 01:47:42 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id BAA22593 Mon, 22 Apr 1996 01:47:34 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.12/8.6.9) id SAA26914; Mon, 22 Apr 1996 18:44:16 +1000 Date: Mon, 22 Apr 1996 18:44:16 +1000 From: Bruce Evans Message-Id: <199604220844.SAA26914@godzilla.zeta.org.au> To: dchapes@zeus.leitch.com, jfrancis@frii.com Subject: Re: Device Driver ioctl() help Cc: hackers@FreeBSD.org, hsu@FreeBSD.org Sender: owner-hackers@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk >> 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. 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