kernel/fs: Translate ioctl(FIONBIO) into fcntl(F_SETFL).

This way, FIONBIO and O_NONBLOCK will no longer get out of sync,
and additionally, FIONBIO can be used to change non-blocking
status of regular (non-socket) FDs, too (which some applications
seem to take advantage of, to avoid needing to fetch the open_mode
before calling fcntl.)

Change-Id: Id894fe76c79ac373c0121a003d68180a3d9b6560
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7697
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Augustin Cavalier 2024-05-27 20:45:28 -04:00 committed by waddlesplash
parent e08f7fd12b
commit 45383846d8
3 changed files with 21 additions and 37 deletions

View File

@ -459,24 +459,6 @@ status_t
socket_control(net_socket* socket, uint32 op, void* data, size_t length)
{
switch (op) {
case FIONBIO:
{
if (data == NULL)
return B_BAD_VALUE;
int value;
if (is_syscall()) {
if (!IS_USER_ADDRESS(data)
|| user_memcpy(&value, data, sizeof(int)) != B_OK) {
return B_BAD_ADDRESS;
}
} else
value = *(int*)data;
return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value,
sizeof(int));
}
case FIONREAD:
{
if (data == NULL || (socket->options & SO_ACCEPTCONN) != 0)

View File

@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <OS.h>
@ -472,6 +473,26 @@ fd_ioctl(bool kernelFD, int fd, uint32 op, void* buffer, size_t length)
if (!descriptor.IsSet())
return B_FILE_ERROR;
// Special case: translate FIONBIO into fcntl(F_SETFL).
if (op == FIONBIO) {
if (buffer == NULL)
return B_BAD_VALUE;
int value;
if (is_called_via_syscall()) {
if (!IS_USER_ADDRESS(buffer)
|| user_memcpy(&value, buffer, sizeof(int)) != B_OK) {
return B_BAD_ADDRESS;
}
} else
value = *(int*)buffer;
size_t argument = descriptor->open_mode & ~O_NONBLOCK;
argument |= (value ? O_NONBLOCK : 0);
return (kernelFD ? _kern_fcntl : _user_fcntl)(fd, F_SETFL, argument);
}
status_t status;
if (descriptor->ops->fd_ioctl)
status = descriptor->ops->fd_ioctl(descriptor.Get(), op, buffer, length);

View File

@ -1065,25 +1065,6 @@ fifo_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, uint32 op,
_node, _cookie, op, buffer, length);
switch (op) {
case FIONBIO:
{
if (buffer == NULL)
return B_BAD_VALUE;
int value;
if (is_called_via_syscall()) {
if (!IS_USER_ADDRESS(buffer)
|| user_memcpy(&value, buffer, sizeof(int)) != B_OK) {
return B_BAD_ADDRESS;
}
} else
value = *(int*)buffer;
MutexLocker locker(inode->RequestLock());
cookie->SetNonBlocking(value != 0);
return B_OK;
}
case FIONREAD:
{
if (buffer == NULL)