POSIX: ioctl(fd, op, arg) equals ioctl(fd, op, arg, 0)
The ioctl call cannot know the expected number of arguments because it depends on the specific ioctl being used, and the same value could be used to do different things by different devices. Without knowing that, it is not safe to use va_arg (at best a random value will be read from the stack, at worst, it will just crash). This changes the implementation of ioctl in two ways: - For C++ code: a 4 argument function with default values for arguments 3 and 4. - For C code: wrap arguments 3 and 4 in a struct with the help of a macro, providing something that behaves like the C++ version. So, with this new code: - Calling ioctl with only 3 arguments sets the 4th one to 0 - Calling ioctl with only 2 arguments sets the 3rd and 4th to 0 - Calling with 1 or 5+ arguments is a compile time error The existing ioctl symbol is preserved for ABI compatibility. Change-Id: I6d4d1d38fccd8cc9bd94203d3e11aeac6da8efc3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3360 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
3349a731ef
commit
7065a89fc6
@@ -190,7 +190,23 @@ extern int symlinkat(const char *toPath, int fd, const char *symlinkPath);
|
||||
|
||||
extern int ftruncate(int fd, off_t newSize);
|
||||
extern int truncate(const char *path, off_t newSize);
|
||||
struct ioctl_args {
|
||||
void* argument;
|
||||
size_t size;
|
||||
};
|
||||
int __ioctl(int fd, ulong cmd, struct ioctl_args args);
|
||||
#ifndef __cplusplus
|
||||
extern int ioctl(int fd, unsigned long op, ...);
|
||||
#ifndef _KERNEL_MODE
|
||||
#define ioctl(a, b, c...) __ioctl(a, b, (struct ioctl_args){ c })
|
||||
#endif
|
||||
#else
|
||||
inline int
|
||||
ioctl(int fd, unsigned long op, void* argument = NULL, size_t size = 0)
|
||||
{
|
||||
return __ioctl(fd, op, (struct ioctl_args){ argument, size });
|
||||
}
|
||||
#endif
|
||||
|
||||
extern ssize_t read(int fd, void *buffer, size_t count);
|
||||
extern ssize_t read_pos(int fd, off_t pos, void *buffer, size_t count);
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
#include <syscall_utils.h>
|
||||
|
||||
|
||||
int
|
||||
__ioctl(int fd, ulong cmd, struct ioctl_args args)
|
||||
{
|
||||
RETURN_AND_SET_ERRNO(_kern_ioctl(fd, cmd, args.argument, args.size));
|
||||
}
|
||||
|
||||
|
||||
#undef ioctl
|
||||
int
|
||||
ioctl(int fd, ulong cmd, ...)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user