S
sheffmail
In linux, macros for defining device ioctl codes are:
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK
(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK
(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),
(_IOC_TYPECHECK(size)))
they use _IOC_TYPECHECK for checking validity of type's size, the
macro is defined like this:
/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
the fact that __invalid_size_argument_for_IOC is in expression
prevents using ioctl codes in constant
expressions in C++ (not in C!), for example the following code
compiles successfully in C, but not in C++:
switch (a)
{
case _IOW('0', 0, int):
{
}
}
In linux/ioctl.h there're also other macroses for defining ioctl
codes:
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof
(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof
(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),
(nr),sizeof(size))
which don't use _IOC_TYPECHECK and ioctl codes defined using these can
be compiled as constant expressions in C++, but I don't like that _BAD
suffix, may be there is another way to use _IOX in C++ ?
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK
(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK
(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),
(_IOC_TYPECHECK(size)))
they use _IOC_TYPECHECK for checking validity of type's size, the
macro is defined like this:
/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
the fact that __invalid_size_argument_for_IOC is in expression
prevents using ioctl codes in constant
expressions in C++ (not in C!), for example the following code
compiles successfully in C, but not in C++:
switch (a)
{
case _IOW('0', 0, int):
{
}
}
In linux/ioctl.h there're also other macroses for defining ioctl
codes:
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof
(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof
(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),
(nr),sizeof(size))
which don't use _IOC_TYPECHECK and ioctl codes defined using these can
be compiled as constant expressions in C++, but I don't like that _BAD
suffix, may be there is another way to use _IOX in C++ ?