diff --git a/docs/user/Doxyfile b/docs/user/Doxyfile index 80359b2ef2..fa43259da9 100644 --- a/docs/user/Doxyfile +++ b/docs/user/Doxyfile @@ -948,6 +948,7 @@ INPUT = . \ ../../headers/os/support \ ../../headers/os/translation \ ../../headers/posix/syslog.h \ + ../../headers/posix/unistd.h \ ../../src/kits/game/GameProducer.h # This tag can be used to specify the character encoding of the source files diff --git a/docs/user/posix/_libroot.dox b/docs/user/posix/_libroot.dox index 7a21c1278f..41f9227b75 100644 --- a/docs/user/posix/_libroot.dox +++ b/docs/user/posix/_libroot.dox @@ -7,7 +7,7 @@ */ /*! -\page libroot C, POSIX, GNU and BSD functions +\defgroup libroot C, POSIX, GNU and BSD functions Haiku implements a standard library containing the standard functions from C (https://www.iso.org/standard/29237.html) and POSIX diff --git a/docs/user/posix/unistd.dox b/docs/user/posix/unistd.dox new file mode 100644 index 0000000000..a827e16abf --- /dev/null +++ b/docs/user/posix/unistd.dox @@ -0,0 +1,48 @@ +/* + * Copyright 2023 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Adrien Destugues, pulkomandy@pulkomandy.tk + * + * Corresponds to: + * headers/posix/unistd.h hrev56953 + */ + +/*! + \file unistd.h + \ingroup libroot + \brief Standard symbolic constants and types +*/ + +/*! + \fn int ioctl(int fd, unsigned long op, void* argument, size_t size) + \brief Send a control command to a device through a file descriptor + + ioctls are usually sent to file descriptors corresponding to files in the devfs filesystem + (mounted in /dev). It allows sending commands to devices that wouldn't fit the usual flow of + the read and write operations. + + The action to perform is identified by the "op" parameter. Each driver can implement its own + custom operations as needed, depending on the device being controlled. There are also a few + standard ones implemented by most drivers. + + In the standard UNIX version of this function, there is support for only one extra argument, + which can be either an integer, or a pointer, either pointing to some data to send to the + driver, or some buffer to receive a response. In most UNIX systems, further details about the + operation are encoded in the "op" parameter, with bits indicating the direction and size of + the buffer. + + In BeOS and Haiku, the allocation of "op" values is done freely in each driver, and no bits are + reserved for such use. Instead, a 4th argument is allowed, and can be used to indicate the + buffer size. There is no need to encode the transfer direction, as this can be agreed between + the calling application and the driver. + + Both the 3rd and 4th parameters are optional. In C++, this is done using C++ function default + arguments and causes no problems. However, the C language has no such feature. Therefore, the + C implementation is a macro implementing a similar behavior. + + To avoid these divergences between implementations of ioctl, portable applications should + consider using the newly standardized posix_devctl function from POSIX 1.2024, which is + equivalent to the BeOS/Haiku implementation of ioctl and also has an explicit size parameter. +*/ diff --git a/headers/posix/unistd.h b/headers/posix/unistd.h index f541ca07ff..f02ada8aa9 100644 --- a/headers/posix/unistd.h +++ b/headers/posix/unistd.h @@ -362,6 +362,17 @@ 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); +/* We want the 3rd and 4th arguments to ioctl to be optional, but we can't use varargs because + * then we have no way to know if the optional arguments are present, and calling va_next is + * undefined behavior (it may or may not work depending on the calling convention). + * + * In C++, we implement ioctl using default function arguments, but in C this isn't possible. + * So, the C implementation is done as vararg macro that use preprocessor magic to call the + * 4 argument function and fill in the omitted arguments. + * + * The legacy ioctl function in C with vararg arguments is still provided for ABI compatibility + * with existing applications, but should not be used anymore by newly compiled code. + */ extern int __ioctl(int fd, ulong cmd, void* argument, size_t size); #ifndef __cplusplus extern int ioctl(int fd, unsigned long op, ...);