From 75015ff525050d1d716f499732c566956c6078ad Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 11 Apr 2008 16:13:47 +0000 Subject: [PATCH] * Renamed THREAD_FLAGS_IOCTL_SYSCALL to THREAD_FLAGS_SYSCALL, syscall_restart_ioctl_is_restarted() to syscall_restart_is_restarted, IoctlSyscallFlagUnsetter to SyscallFlagUnsetter, and IoctlSyscallRestartWrapper to SyscallRestartWrapper, as they are no longer only used for ioctl(). * Removed unused syscall_restart_ioctl_handle_post(). * Made SyscallRestartWrapper a lot fancier. Instead of storing a reference to the result value, it stores the value itself, and it features all the interesting operators that make it appear like that value. This simplifies the use of the class quite a bit. * THREAD_FLAGS_SYSCALL is now set for all socket function and the read[v](), write[v]() syscalls. * Added is_syscall() function and net_stack hook to the net stack. * Removed "kernel" parameter from all net_stack_interface and net_socket module hooks. They aren't need any longer, since is_syscall() can be used instead. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24914 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/syscall_restart.h | 78 +++---- headers/private/kernel/thread_types.h | 3 +- headers/private/net/net_socket.h | 2 +- headers/private/net/net_stack.h | 1 + headers/private/net/net_stack_interface.h | 20 +- .../kernel/network/stack/net_socket.cpp | 13 +- src/add-ons/kernel/network/stack/stack.cpp | 1 + .../kernel/network/stack/stack_interface.cpp | 37 ++-- src/add-ons/kernel/network/stack/utility.cpp | 12 +- src/add-ons/kernel/network/stack/utility.h | 1 + src/system/kernel/fs/fd.cpp | 194 +++++++++--------- src/system/kernel/fs/socket.cpp | 141 +++++++------ 12 files changed, 253 insertions(+), 250 deletions(-) diff --git a/headers/private/kernel/syscall_restart.h b/headers/private/kernel/syscall_restart.h index 4f2eeee1ec..1735e33d59 100644 --- a/headers/private/kernel/syscall_restart.h +++ b/headers/private/kernel/syscall_restart.h @@ -90,69 +90,73 @@ syscall_restart_handle_post(status_t error) static inline bool -syscall_restart_ioctl_is_restarted() +syscall_restart_is_restarted() { struct thread* thread = thread_get_current_thread(); - return (thread->flags & THREAD_FLAGS_IOCTL_SYSCALL) != 0 + return (thread->flags & THREAD_FLAGS_SYSCALL) != 0 && (thread->flags & THREAD_FLAGS_SYSCALL_RESTARTED) != 0; } -static inline status_t -syscall_restart_ioctl_handle_post(status_t error) -{ - if (error == B_INTERRUPTED) { - // interrupted -- set flag for syscall restart - struct thread* thread = thread_get_current_thread(); - if ((thread->flags & THREAD_FLAGS_IOCTL_SYSCALL) != 0) - atomic_or(&thread->flags, THREAD_FLAGS_RESTART_SYSCALL); +struct SyscallFlagUnsetter { + SyscallFlagUnsetter() + { + fThread = thread_get_current_thread(); + fWasSyscall = (atomic_and(&fThread->flags, ~THREAD_FLAGS_SYSCALL) + & THREAD_FLAGS_SYSCALL) != 0; } - return error; -} - - -struct IoctlSyscallFlagUnsetter { - IoctlSyscallFlagUnsetter() + ~SyscallFlagUnsetter() { - struct thread *thread = thread_get_current_thread(); - fWasSyscall = (atomic_and(&thread->flags, ~THREAD_FLAGS_IOCTL_SYSCALL) - & THREAD_FLAGS_IOCTL_SYSCALL) != 0; - } - - ~IoctlSyscallFlagUnsetter() - { - struct thread *thread = thread_get_current_thread(); if (fWasSyscall) - atomic_or(&thread->flags, THREAD_FLAGS_IOCTL_SYSCALL); + atomic_or(&fThread->flags, THREAD_FLAGS_SYSCALL); } private: - bool fWasSyscall; + struct thread* fThread; + bool fWasSyscall; }; template -struct IoctlSyscallRestartWrapper { - IoctlSyscallRestartWrapper(const Type& result) - : fResult(result) +struct SyscallRestartWrapper { + SyscallRestartWrapper(Type initialValue = 0) + : fResult(initialValue) { - struct thread *thread = thread_get_current_thread(); - atomic_or(&thread->flags, THREAD_FLAGS_IOCTL_SYSCALL); + fThread = thread_get_current_thread(); + atomic_or(&fThread->flags, THREAD_FLAGS_SYSCALL); } - ~IoctlSyscallRestartWrapper() + ~SyscallRestartWrapper() { - struct thread *thread = thread_get_current_thread(); - atomic_and(&thread->flags, ~THREAD_FLAGS_IOCTL_SYSCALL); + atomic_and(&fThread->flags, ~THREAD_FLAGS_SYSCALL); - if (fResult < 0) - syscall_restart_ioctl_handle_post(fResult); + if (fResult == B_INTERRUPTED) { + // interrupted -- set flag for syscall restart + if ((fThread->flags & THREAD_FLAGS_SYSCALL) != 0) + atomic_or(&fThread->flags, THREAD_FLAGS_RESTART_SYSCALL); + } } + SyscallRestartWrapper& operator=(const Type& other) + { + fResult = other; + return *this; + } + + bool operator==(const Type& other) const { return fResult == other; } + bool operator!=(const Type& other) const { return fResult != other; } + bool operator<=(const Type& other) const { return fResult <= other; } + bool operator>=(const Type& other) const { return fResult >= other; } + bool operator<(const Type& other) const { return fResult < other; } + bool operator>(const Type& other) const { return fResult > other; } + + operator Type() const { return fResult; } + private: - const Type& fResult; + Type fResult; + struct thread* fThread; }; diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 567b0d95e5..3ef4532423 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -311,7 +311,8 @@ struct thread_queue { #define THREAD_FLAGS_RESTART_SYSCALL 0x0040 #define THREAD_FLAGS_DONT_RESTART_SYSCALL 0x0080 #define THREAD_FLAGS_SYSCALL_RESTARTED 0x0100 -#define THREAD_FLAGS_IOCTL_SYSCALL 0x0200 +#define THREAD_FLAGS_SYSCALL 0x0200 + // Note: Set only for certain syscalls. #endif /* _KERNEL_THREAD_TYPES_H */ diff --git a/headers/private/net/net_socket.h b/headers/private/net/net_socket.h index 7231bcd900..2e7d8c23c9 100644 --- a/headers/private/net/net_socket.h +++ b/headers/private/net/net_socket.h @@ -53,7 +53,7 @@ struct net_socket_module_info { status_t (*writev)(net_socket *socket, const iovec *vecs, size_t vecCount, size_t *_length); status_t (*control)(net_socket *socket, int32 op, void *data, - size_t length, bool kernel); + size_t length); ssize_t (*read_avail)(net_socket *socket); ssize_t (*send_avail)(net_socket *socket); diff --git a/headers/private/net/net_stack.h b/headers/private/net/net_stack.h index a5a5a572c4..1ca720f95e 100644 --- a/headers/private/net/net_stack.h +++ b/headers/private/net/net_stack.h @@ -135,6 +135,7 @@ struct net_stack_module_info { bool (*is_timer_active)(struct net_timer *timer); // syscall restart + bool (*is_syscall)(void); bool (*is_restarted_syscall)(void); void (*store_syscall_restart_timeout)(bigtime_t timeout); bigtime_t (*restore_syscall_restart_timeout)(void); diff --git a/headers/private/net/net_stack_interface.h b/headers/private/net/net_stack_interface.h index 34f3f7b32e..b641bc82e8 100644 --- a/headers/private/net/net_stack_interface.h +++ b/headers/private/net/net_stack_interface.h @@ -29,29 +29,27 @@ struct net_stack_interface_module_info { status_t (*free)(net_socket* socket); status_t (*bind)(net_socket* socket, const struct sockaddr* address, - socklen_t addressLength, bool kernel); + socklen_t addressLength); status_t (*shutdown)(net_socket* socket, int how); status_t (*connect)(net_socket* socket, const struct sockaddr* address, - socklen_t addressLength, bool kernel); + socklen_t addressLength); status_t (*listen)(net_socket* socket, int backlog); status_t (*accept)(net_socket* socket, struct sockaddr* address, socklen_t* _addressLength, net_socket** _acceptedSocket); - ssize_t (*recv)(net_socket* socket, void* data, size_t length, int flags, - bool kernel); + ssize_t (*recv)(net_socket* socket, void* data, size_t length, int flags); ssize_t (*recvfrom)(net_socket* socket, void* data, size_t length, int flags, struct sockaddr* address, - socklen_t* _addressLength, bool kernel); - ssize_t (*recvmsg)(net_socket* socket, struct msghdr* message, int flags, - bool kernel); + socklen_t* _addressLength); + ssize_t (*recvmsg)(net_socket* socket, struct msghdr* message, int flags); ssize_t (*send)(net_socket* socket, const void* data, size_t length, - int flags, bool kernel); + int flags); ssize_t (*sendto)(net_socket* socket, const void* data, size_t length, int flags, const struct sockaddr* address, - socklen_t addressLength, bool kernel); + socklen_t addressLength); ssize_t (*sendmsg)(net_socket* socket, const struct msghdr* message, - int flags, bool kernel); + int flags); status_t (*getsockopt)(net_socket* socket, int level, int option, void* value, socklen_t* _length); @@ -69,7 +67,7 @@ struct net_stack_interface_module_info { net_socket* _sockets[2]); status_t (*ioctl)(net_socket* socket, uint32 op, void *buffer, - size_t length, bool kernel); + size_t length); status_t (*select)(net_socket* socket, uint8 event, struct selectsync *sync); status_t (*deselect)(net_socket* socket, uint8 event, diff --git a/src/add-ons/kernel/network/stack/net_socket.cpp b/src/add-ons/kernel/network/stack/net_socket.cpp index c838d68539..9cdff52758 100644 --- a/src/add-ons/kernel/network/stack/net_socket.cpp +++ b/src/add-ons/kernel/network/stack/net_socket.cpp @@ -30,6 +30,8 @@ #include #include +#include "utility.h" + struct net_socket_private : net_socket { struct list_link link; @@ -243,8 +245,7 @@ socket_writev(net_socket *socket, const iovec *vecs, size_t vecCount, status_t -socket_control(net_socket *socket, int32 op, void *data, size_t length, - bool kernel) +socket_control(net_socket *socket, int32 op, void *data, size_t length) { switch (op) { case FIONBIO: @@ -253,14 +254,14 @@ socket_control(net_socket *socket, int32 op, void *data, size_t length, return B_BAD_VALUE; int value; - if (kernel) { - value = *(int*)data; - } else { + 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)); } diff --git a/src/add-ons/kernel/network/stack/stack.cpp b/src/add-ons/kernel/network/stack/stack.cpp index 1363f02183..7cf6be04f2 100644 --- a/src/add-ons/kernel/network/stack/stack.cpp +++ b/src/add-ons/kernel/network/stack/stack.cpp @@ -918,6 +918,7 @@ net_stack_module_info gNetStackModule = { cancel_timer, is_timer_active, + is_syscall, is_restarted_syscall, store_syscall_restart_timeout, restore_syscall_restart_timeout, diff --git a/src/add-ons/kernel/network/stack/stack_interface.cpp b/src/add-ons/kernel/network/stack/stack_interface.cpp index 4d62487ad6..67ec0c5e7a 100644 --- a/src/add-ons/kernel/network/stack/stack_interface.cpp +++ b/src/add-ons/kernel/network/stack/stack_interface.cpp @@ -1,5 +1,7 @@ - - +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ #include "stack_private.h" @@ -31,9 +33,8 @@ stack_interface_free(net_socket* socket) static status_t stack_interface_bind(net_socket* socket, const struct sockaddr* address, - socklen_t addressLength, bool kernel) + socklen_t addressLength) { -// TODO: Pass kernel flag! return gNetSocketModule.bind(socket, address, addressLength); } @@ -47,9 +48,8 @@ stack_interface_shutdown(net_socket* socket, int how) static status_t stack_interface_connect(net_socket* socket, const struct sockaddr* address, - socklen_t addressLength, bool kernel) + socklen_t addressLength) { -// TODO: Pass kernel flag! return gNetSocketModule.connect(socket, address, addressLength); } @@ -71,17 +71,15 @@ stack_interface_accept(net_socket* socket, struct sockaddr* address, static ssize_t -stack_interface_recv(net_socket* socket, void* data, size_t length, int flags, - bool kernel) +stack_interface_recv(net_socket* socket, void* data, size_t length, int flags) { -// TODO: Pass kernel flag! return gNetSocketModule.receive(socket, NULL, data, length, flags); } static ssize_t stack_interface_recvfrom(net_socket* socket, void* data, size_t length, - int flags, struct sockaddr* address, socklen_t* _addressLength, bool kernel) + int flags, struct sockaddr* address, socklen_t* _addressLength) { msghdr message; iovec vecs[1] = { { data, length } }; @@ -93,7 +91,6 @@ stack_interface_recvfrom(net_socket* socket, void* data, size_t length, message.msg_controllen = 0; message.msg_flags = 0; -// TODO: Pass kernel flag! status_t error = gNetSocketModule.receive(socket, &message, data, length, flags); if (error != B_OK) @@ -105,8 +102,7 @@ stack_interface_recvfrom(net_socket* socket, void* data, size_t length, static ssize_t -stack_interface_recvmsg(net_socket* socket, struct msghdr* message, int flags, - bool kernel) +stack_interface_recvmsg(net_socket* socket, struct msghdr* message, int flags) { void* buffer = NULL; size_t len = 0; @@ -115,24 +111,21 @@ stack_interface_recvmsg(net_socket* socket, struct msghdr* message, int flags, len = message->msg_iov[0].iov_len; } -// TODO: Pass kernel flag! return gNetSocketModule.receive(socket, message, buffer, len, flags); } static ssize_t stack_interface_send(net_socket* socket, const void* data, size_t length, - int flags, bool kernel) + int flags) { -// TODO: Pass kernel flag! return gNetSocketModule.send(socket, NULL, data, length, flags); } static ssize_t stack_interface_sendto(net_socket* socket, const void* data, size_t length, - int flags, const struct sockaddr* address, socklen_t addressLength, - bool kernel) + int flags, const struct sockaddr* address, socklen_t addressLength) { msghdr message; iovec vecs[1] = { { (void*)data, length } }; @@ -144,14 +137,13 @@ stack_interface_sendto(net_socket* socket, const void* data, size_t length, message.msg_controllen = 0; message.msg_flags = 0; -// TODO: Pass kernel flag! return gNetSocketModule.send(socket, &message, data, length, flags); } static ssize_t stack_interface_sendmsg(net_socket* socket, const struct msghdr* message, - int flags, bool kernel) + int flags) { void* buffer = NULL; size_t len = 0; @@ -160,7 +152,6 @@ stack_interface_sendmsg(net_socket* socket, const struct msghdr* message, len = message->msg_iov[0].iov_len; } -// TODO: Pass kernel flag! return gNetSocketModule.send(socket, (msghdr*)message, buffer, len, flags); } @@ -219,9 +210,9 @@ stack_interface_socketpair(int family, int type, int protocol, static status_t stack_interface_ioctl(net_socket* socket, uint32 op, void *buffer, - size_t length, bool kernel) + size_t length) { - return gNetSocketModule.control(socket, op, buffer, length, kernel); + return gNetSocketModule.control(socket, op, buffer, length); } diff --git a/src/add-ons/kernel/network/stack/utility.cpp b/src/add-ons/kernel/network/stack/utility.cpp index caacfaba9d..6bcd68c2ea 100644 --- a/src/add-ons/kernel/network/stack/utility.cpp +++ b/src/add-ons/kernel/network/stack/utility.cpp @@ -575,10 +575,18 @@ uninit_timers(void) // #pragma mark - Syscall restart +bool +is_syscall(void) +{ + struct thread* thread = thread_get_current_thread(); + return (thread->flags & THREAD_FLAGS_SYSCALL) != 0; +} + + bool is_restarted_syscall(void) { - return syscall_restart_ioctl_is_restarted(); + return syscall_restart_is_restarted(); } @@ -586,7 +594,7 @@ void store_syscall_restart_timeout(bigtime_t timeout) { struct thread* thread = thread_get_current_thread(); - if ((thread->flags & THREAD_FLAGS_IOCTL_SYSCALL) != 0) + if ((thread->flags & THREAD_FLAGS_SYSCALL) != 0) *(bigtime_t*)thread->syscall_restart.parameters = timeout; } diff --git a/src/add-ons/kernel/network/stack/utility.h b/src/add-ons/kernel/network/stack/utility.h index c27afce92e..fa542ba5e2 100644 --- a/src/add-ons/kernel/network/stack/utility.h +++ b/src/add-ons/kernel/network/stack/utility.h @@ -102,6 +102,7 @@ status_t init_timers(void); void uninit_timers(void); // syscall restart +bool is_syscall(void); bool is_restarted_syscall(void); void store_syscall_restart_timeout(bigtime_t timeout); bigtime_t restore_syscall_restart_timeout(void); diff --git a/src/system/kernel/fs/fd.cpp b/src/system/kernel/fs/fd.cpp index 9e4dd03bb5..a0d64bd5e4 100644 --- a/src/system/kernel/fs/fd.cpp +++ b/src/system/kernel/fs/fd.cpp @@ -651,14 +651,15 @@ common_user_io(int fd, off_t pos, void *buffer, size_t length, bool write) return B_BAD_VALUE; } - status_t status; + SyscallRestartWrapper status; + if (write) status = descriptor->ops->fd_write(descriptor, pos, buffer, &length); else status = descriptor->ops->fd_read(descriptor, pos, buffer, &length); if (status < B_OK) - return syscall_restart_handle_post(status); + return status; if (movePosition) descriptor->pos = pos + length; @@ -710,10 +711,11 @@ common_user_vector_io(int fd, off_t pos, const iovec *userVecs, size_t count, return B_BAD_VALUE; } + SyscallRestartWrapper status; + ssize_t bytesTransferred = 0; for (uint32 i = 0; i < count; i++) { size_t length = vecs[i].iov_len; - status_t status; if (write) { status = descriptor->ops->fd_write(descriptor, pos, vecs[i].iov_base, &length); @@ -724,7 +726,8 @@ common_user_vector_io(int fd, off_t pos, const iovec *userVecs, size_t count, if (status < B_OK) { if (bytesTransferred == 0) - return syscall_restart_handle_post(status); + return status; + status = B_OK; break; } @@ -819,13 +822,9 @@ _user_ioctl(int fd, ulong op, void *buffer, size_t length) TRACE(("user_ioctl: fd %d\n", fd)); - struct thread *thread = thread_get_current_thread(); - atomic_or(&thread->flags, THREAD_FLAGS_IOCTL_SYSCALL); + SyscallRestartWrapper status; - status_t status = fd_ioctl(false, fd, op, buffer, length); - - atomic_and(&thread->flags, ~THREAD_FLAGS_IOCTL_SYSCALL); - return status; + return status = fd_ioctl(false, fd, op, buffer, length); } @@ -908,19 +907,16 @@ _user_dup2(int ofd, int nfd) ssize_t _kern_read(int fd, off_t pos, void *buffer, size_t length) { - struct file_descriptor *descriptor; - ssize_t bytesRead; - if (pos < -1) return B_BAD_VALUE; - descriptor = get_fd(get_current_io_context(true), fd); + FDGetter fdGetter; + struct file_descriptor *descriptor = fdGetter.SetTo(fd, true); + if (!descriptor) return B_FILE_ERROR; - if ((descriptor->open_mode & O_RWMASK) == O_WRONLY) { - put_fd(descriptor); + if ((descriptor->open_mode & O_RWMASK) == O_WRONLY) return B_FILE_ERROR; - } bool movePosition = false; if (pos == -1) { @@ -928,21 +924,23 @@ _kern_read(int fd, off_t pos, void *buffer, size_t length) movePosition = true; } - if (descriptor->ops->fd_read) { - bytesRead = descriptor->ops->fd_read(descriptor, pos, buffer, &length); - if (bytesRead >= B_OK) { - if (length > SSIZE_MAX) - bytesRead = SSIZE_MAX; - else - bytesRead = (ssize_t)length; + SyscallFlagUnsetter _; - if (movePosition) - descriptor->pos = pos + length; - } - } else - bytesRead = B_BAD_VALUE; + if (descriptor->ops->fd_read == NULL) + return B_BAD_VALUE; + + ssize_t bytesRead = descriptor->ops->fd_read(descriptor, pos, buffer, + &length); + if (bytesRead >= B_OK) { + if (length > SSIZE_MAX) + bytesRead = SSIZE_MAX; + else + bytesRead = (ssize_t)length; + + if (movePosition) + descriptor->pos = pos + length; + } - put_fd(descriptor); return bytesRead; } @@ -950,52 +948,53 @@ _kern_read(int fd, off_t pos, void *buffer, size_t length) ssize_t _kern_readv(int fd, off_t pos, const iovec *vecs, size_t count) { - struct file_descriptor *descriptor; bool movePosition = false; - ssize_t bytesRead = 0; status_t status; uint32 i; if (pos < -1) return B_BAD_VALUE; - descriptor = get_fd(get_current_io_context(true), fd); + FDGetter fdGetter; + struct file_descriptor *descriptor = fdGetter.SetTo(fd, true); + if (!descriptor) return B_FILE_ERROR; - if ((descriptor->open_mode & O_RWMASK) == O_WRONLY) { - put_fd(descriptor); + if ((descriptor->open_mode & O_RWMASK) == O_WRONLY) return B_FILE_ERROR; - } if (pos == -1) { pos = descriptor->pos; movePosition = true; } - if (descriptor->ops->fd_read) { - for (i = 0; i < count; i++) { - size_t length = vecs[i].iov_len; - status = descriptor->ops->fd_read(descriptor, pos, vecs[i].iov_base, - &length); - if (status < B_OK) { - bytesRead = status; - break; - } + if (descriptor->ops->fd_read == NULL) + return B_BAD_VALUE; - if ((uint64)bytesRead + length > SSIZE_MAX) - bytesRead = SSIZE_MAX; - else - bytesRead += (ssize_t)length; + SyscallFlagUnsetter _; - pos += vecs[i].iov_len; + ssize_t bytesRead = 0; + + for (i = 0; i < count; i++) { + size_t length = vecs[i].iov_len; + status = descriptor->ops->fd_read(descriptor, pos, vecs[i].iov_base, + &length); + if (status < B_OK) { + bytesRead = status; + break; } - } else - bytesRead = B_BAD_VALUE; + + if ((uint64)bytesRead + length > SSIZE_MAX) + bytesRead = SSIZE_MAX; + else + bytesRead += (ssize_t)length; + + pos += vecs[i].iov_len; + } if (movePosition) descriptor->pos = pos; - put_fd(descriptor); return bytesRead; } @@ -1003,19 +1002,16 @@ _kern_readv(int fd, off_t pos, const iovec *vecs, size_t count) ssize_t _kern_write(int fd, off_t pos, const void *buffer, size_t length) { - struct file_descriptor *descriptor; - ssize_t bytesWritten; - if (pos < -1) return B_BAD_VALUE; - descriptor = get_fd(get_current_io_context(true), fd); + FDGetter fdGetter; + struct file_descriptor *descriptor = fdGetter.SetTo(fd, true); + if (descriptor == NULL) return B_FILE_ERROR; - if ((descriptor->open_mode & O_RWMASK) == O_RDONLY) { - put_fd(descriptor); + if ((descriptor->open_mode & O_RWMASK) == O_RDONLY) return B_FILE_ERROR; - } bool movePosition = false; if (pos == -1) { @@ -1023,22 +1019,23 @@ _kern_write(int fd, off_t pos, const void *buffer, size_t length) movePosition = true; } - if (descriptor->ops->fd_write) { - bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, - &length); - if (bytesWritten >= B_OK) { - if (length > SSIZE_MAX) - bytesWritten = SSIZE_MAX; - else - bytesWritten = (ssize_t)length; + if (descriptor->ops->fd_write == NULL) + return B_BAD_VALUE; - if (movePosition) - descriptor->pos = pos + length; - } - } else - bytesWritten = B_BAD_VALUE; + SyscallFlagUnsetter _; + + ssize_t bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, + &length); + if (bytesWritten >= B_OK) { + if (length > SSIZE_MAX) + bytesWritten = SSIZE_MAX; + else + bytesWritten = (ssize_t)length; + + if (movePosition) + descriptor->pos = pos + length; + } - put_fd(descriptor); return bytesWritten; } @@ -1046,52 +1043,53 @@ _kern_write(int fd, off_t pos, const void *buffer, size_t length) ssize_t _kern_writev(int fd, off_t pos, const iovec *vecs, size_t count) { - struct file_descriptor *descriptor; bool movePosition = false; - ssize_t bytesWritten = 0; status_t status; uint32 i; if (pos < -1) return B_BAD_VALUE; - descriptor = get_fd(get_current_io_context(true), fd); + FDGetter fdGetter; + struct file_descriptor *descriptor = fdGetter.SetTo(fd, true); + if (!descriptor) return B_FILE_ERROR; - if ((descriptor->open_mode & O_RWMASK) == O_RDONLY) { - put_fd(descriptor); + if ((descriptor->open_mode & O_RWMASK) == O_RDONLY) return B_FILE_ERROR; - } if (pos == -1) { pos = descriptor->pos; movePosition = true; } - if (descriptor->ops->fd_write) { - for (i = 0; i < count; i++) { - size_t length = vecs[i].iov_len; - status = descriptor->ops->fd_write(descriptor, pos, - vecs[i].iov_base, &length); - if (status < B_OK) { - bytesWritten = status; - break; - } + if (descriptor->ops->fd_write == NULL) + return B_BAD_VALUE; - if ((uint64)bytesWritten + length > SSIZE_MAX) - bytesWritten = SSIZE_MAX; - else - bytesWritten += (ssize_t)length; + SyscallFlagUnsetter _; - pos += vecs[i].iov_len; + ssize_t bytesWritten = 0; + + for (i = 0; i < count; i++) { + size_t length = vecs[i].iov_len; + status = descriptor->ops->fd_write(descriptor, pos, + vecs[i].iov_base, &length); + if (status < B_OK) { + bytesWritten = status; + break; } - } else - bytesWritten = B_BAD_VALUE; + + if ((uint64)bytesWritten + length > SSIZE_MAX) + bytesWritten = SSIZE_MAX; + else + bytesWritten += (ssize_t)length; + + pos += vecs[i].iov_len; + } if (movePosition) descriptor->pos = pos; - put_fd(descriptor); return bytesWritten; } @@ -1120,7 +1118,7 @@ _kern_ioctl(int fd, ulong op, void *buffer, size_t length) { TRACE(("kern_ioctl: fd %d\n", fd)); - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; return fd_ioctl(true, fd, op, buffer, length); } diff --git a/src/system/kernel/fs/socket.cpp b/src/system/kernel/fs/socket.cpp index ae6e8ebd5d..e826c1547e 100644 --- a/src/system/kernel/fs/socket.cpp +++ b/src/system/kernel/fs/socket.cpp @@ -189,7 +189,7 @@ socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer, size_t *_length) { ssize_t bytesRead = sStackInterface->recv(descriptor->u.socket, buffer, - *_length, 0, !IS_USER_ADDRESS(buffer)); + *_length, 0); *_length = bytesRead >= 0 ? bytesRead : 0; return bytesRead >= 0 ? B_OK : bytesRead; } @@ -200,7 +200,7 @@ socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, size_t *_length) { ssize_t bytesWritten = sStackInterface->send(descriptor->u.socket, buffer, - *_length, 0, !IS_USER_ADDRESS(buffer)); + *_length, 0); *_length = bytesWritten >= 0 ? bytesWritten : 0; return bytesWritten >= 0 ? B_OK : bytesWritten; } @@ -210,8 +210,7 @@ static status_t socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer, size_t length) { - return sStackInterface->ioctl(descriptor->u.socket, op, buffer, - length, !IS_USER_ADDRESS(buffer)); + return sStackInterface->ioctl(descriptor->u.socket, op, buffer, length); } @@ -341,8 +340,7 @@ common_bind(int fd, const struct sockaddr *address, socklen_t addressLength, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FDPutter _(descriptor); - return sStackInterface->bind(descriptor->u.socket, address, addressLength, - kernel); + return sStackInterface->bind(descriptor->u.socket, address, addressLength); } @@ -366,7 +364,7 @@ common_connect(int fd, const struct sockaddr *address, FDPutter _(descriptor); return sStackInterface->connect(descriptor->u.socket, address, - addressLength, kernel); + addressLength); } @@ -413,8 +411,7 @@ common_recv(int fd, void *data, size_t length, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FDPutter _(descriptor); - return sStackInterface->recv(descriptor->u.socket, data, length, flags, - kernel); + return sStackInterface->recv(descriptor->u.socket, data, length, flags); } @@ -427,7 +424,7 @@ common_recvfrom(int fd, void *data, size_t length, int flags, FDPutter _(descriptor); return sStackInterface->recvfrom(descriptor->u.socket, data, length, - flags, address, _addressLength, kernel); + flags, address, _addressLength); } @@ -438,8 +435,7 @@ common_recvmsg(int fd, struct msghdr *message, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FDPutter _(descriptor); - return sStackInterface->recvmsg(descriptor->u.socket, message, flags, - kernel); + return sStackInterface->recvmsg(descriptor->u.socket, message, flags); } @@ -450,8 +446,7 @@ common_send(int fd, const void *data, size_t length, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FDPutter _(descriptor); - return sStackInterface->send(descriptor->u.socket, data, length, flags, - kernel); + return sStackInterface->send(descriptor->u.socket, data, length, flags); } @@ -464,7 +459,7 @@ common_sendto(int fd, const void *data, size_t length, int flags, FDPutter _(descriptor); return sStackInterface->sendto(descriptor->u.socket, data, length, flags, - address, addressLength, kernel); + address, addressLength); } @@ -475,8 +470,7 @@ common_sendmsg(int fd, const struct msghdr *message, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FDPutter _(descriptor); - return sStackInterface->sendmsg(descriptor->u.socket, message, flags, - kernel); + return sStackInterface->sendmsg(descriptor->u.socket, message, flags); } @@ -585,6 +579,7 @@ common_get_next_socket_stat(int family, uint32 *cookie, struct net_stat *stat) int socket(int family, int type, int protocol) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_socket(family, type, protocol, true)); } @@ -592,6 +587,7 @@ socket(int family, int type, int protocol) int bind(int socket, const struct sockaddr *address, socklen_t addressLength) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_bind(socket, address, addressLength, true)); } @@ -599,6 +595,7 @@ bind(int socket, const struct sockaddr *address, socklen_t addressLength) int shutdown(int socket, int how) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_shutdown(socket, how, true)); } @@ -606,7 +603,7 @@ shutdown(int socket, int how) int connect(int socket, const struct sockaddr *address, socklen_t addressLength) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_connect(socket, address, addressLength, true)); } @@ -614,6 +611,7 @@ connect(int socket, const struct sockaddr *address, socklen_t addressLength) int listen(int socket, int backlog) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_listen(socket, backlog, true)); } @@ -621,7 +619,7 @@ listen(int socket, int backlog) int accept(int socket, struct sockaddr *address, socklen_t *_addressLength) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_accept(socket, address, _addressLength, true)); } @@ -629,7 +627,7 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength) ssize_t recv(int socket, void *data, size_t length, int flags) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_recv(socket, data, length, flags, true)); } @@ -638,7 +636,7 @@ ssize_t recvfrom(int socket, void *data, size_t length, int flags, struct sockaddr *address, socklen_t *_addressLength) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_recvfrom(socket, data, length, flags, address, _addressLength, true)); } @@ -647,7 +645,7 @@ recvfrom(int socket, void *data, size_t length, int flags, ssize_t recvmsg(int socket, struct msghdr *message, int flags) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_recvmsg(socket, message, flags, true)); } @@ -655,7 +653,7 @@ recvmsg(int socket, struct msghdr *message, int flags) ssize_t send(int socket, const void *data, size_t length, int flags) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_send(socket, data, length, flags, true)); } @@ -664,7 +662,7 @@ ssize_t sendto(int socket, const void *data, size_t length, int flags, const struct sockaddr *address, socklen_t addressLength) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_sendto(socket, data, length, flags, address, addressLength, true)); } @@ -673,7 +671,7 @@ sendto(int socket, const void *data, size_t length, int flags, ssize_t sendmsg(int socket, const struct msghdr *message, int flags) { - IoctlSyscallFlagUnsetter _; + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_sendmsg(socket, message, flags, true)); } @@ -681,6 +679,7 @@ sendmsg(int socket, const struct msghdr *message, int flags) int getsockopt(int socket, int level, int option, void *value, socklen_t *_length) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_getsockopt(socket, level, option, value, _length, true)); } @@ -690,6 +689,7 @@ int setsockopt(int socket, int level, int option, const void *value, socklen_t length) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_setsockopt(socket, level, option, value, length, true)); } @@ -698,6 +698,7 @@ setsockopt(int socket, int level, int option, const void *value, int getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_getpeername(socket, address, _addressLength, true)); } @@ -706,6 +707,7 @@ getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength) int getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_getsockname(socket, address, _addressLength, true)); } @@ -714,6 +716,7 @@ getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength) int sockatmark(int socket) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_sockatmark(socket, true)); } @@ -721,6 +724,7 @@ sockatmark(int socket) int socketpair(int family, int type, int protocol, int socketVector[2]) { + SyscallFlagUnsetter _; RETURN_AND_SET_ERRNO(common_socketpair(family, type, protocol, socketVector, true)); } @@ -732,7 +736,8 @@ socketpair(int family, int type, int protocol, int socketVector[2]) int _user_socket(int family, int type, int protocol) { - return common_socket(family, type, protocol, false); + SyscallRestartWrapper result; + return result = common_socket(family, type, protocol, false); } @@ -750,14 +755,17 @@ _user_bind(int socket, const struct sockaddr *userAddress, return B_BAD_ADDRESS; } - return common_bind(socket, (sockaddr*)address, addressLength, false); + SyscallRestartWrapper error; + return error = common_bind(socket, (sockaddr*)address, addressLength, + false); } status_t _user_shutdown_socket(int socket, int how) { - return common_shutdown(socket, how, false); + SyscallRestartWrapper error; + return error = common_shutdown(socket, how, false); } @@ -775,19 +783,18 @@ _user_connect(int socket, const struct sockaddr *userAddress, return B_BAD_ADDRESS; } - status_t error; - IoctlSyscallRestartWrapper restartWrapper(error); + SyscallRestartWrapper error; - error = common_connect(socket, (sockaddr*)address, addressLength, false); - - return error; + return error = common_connect(socket, (sockaddr*)address, addressLength, + false); } status_t _user_listen(int socket, int backlog) { - return common_listen(socket, backlog, false); + SyscallRestartWrapper error; + return error = common_listen(socket, backlog, false); } @@ -803,8 +810,7 @@ _user_accept(int socket, struct sockaddr *userAddress, return error; // accept() - int result; - IoctlSyscallRestartWrapper restartWrapper(result); + SyscallRestartWrapper result; char address[MAX_SOCKET_ADDRESS_LEN]; result = common_accept(socket, @@ -826,12 +832,8 @@ _user_accept(int socket, struct sockaddr *userAddress, ssize_t _user_recv(int socket, void *data, size_t length, int flags) { - ssize_t result; - IoctlSyscallRestartWrapper restartWrapper(result); - - result = common_recv(socket, data, length, flags, false); - - return result; + SyscallRestartWrapper result; + return result = common_recv(socket, data, length, flags, false); } @@ -847,8 +849,7 @@ _user_recvfrom(int socket, void *data, size_t length, int flags, return error; // recvfrom() - ssize_t result; - IoctlSyscallRestartWrapper restartWrapper(result); + SyscallRestartWrapper result; char address[MAX_SOCKET_ADDRESS_LEN]; result = common_recvfrom(socket, data, length, flags, @@ -884,8 +885,7 @@ _user_recvmsg(int socket, struct msghdr *userMessage, int flags) return error; // recvmsg() - ssize_t result; - IoctlSyscallRestartWrapper restartWrapper(result); + SyscallRestartWrapper result; result = common_recvmsg(socket, &message, flags, false); if (result < 0) @@ -906,12 +906,8 @@ _user_recvmsg(int socket, struct msghdr *userMessage, int flags) ssize_t _user_send(int socket, const void *data, size_t length, int flags) { - ssize_t result; - IoctlSyscallRestartWrapper restartWrapper(result); - - result = common_send(socket, data, length, flags, false); - - return result; + SyscallRestartWrapper result; + return result = common_send(socket, data, length, flags, false); } @@ -934,12 +930,10 @@ _user_sendto(int socket, const void *data, size_t length, int flags, } // sendto() - ssize_t result; - IoctlSyscallRestartWrapper restartWrapper(result); + SyscallRestartWrapper result; - result = common_sendto(socket, data, length, flags, (sockaddr*)address, - addressLength, false); - return result; + return result = common_sendto(socket, data, length, flags, + (sockaddr*)address, addressLength, false); } @@ -965,11 +959,9 @@ _user_sendmsg(int socket, const struct msghdr *userMessage, int flags) } // sendmsg() - ssize_t result; - IoctlSyscallRestartWrapper restartWrapper(result); + SyscallRestartWrapper result; - result = common_sendmsg(socket, &message, flags, false); - return result; + return result = common_sendmsg(socket, &message, flags, false); } @@ -993,7 +985,8 @@ _user_getsockopt(int socket, int level, int option, void *userValue, // getsockopt() char value[MAX_SOCKET_OPTION_LEN]; - status_t error = common_getsockopt(socket, level, option, value, &length, + SyscallRestartWrapper error; + error = common_getsockopt(socket, level, option, value, &length, false); if (error != B_OK) return error; @@ -1022,7 +1015,9 @@ _user_setsockopt(int socket, int level, int option, const void *userValue, } // setsockopt(); - return common_setsockopt(socket, level, option, value, length, false); + SyscallRestartWrapper error; + return error = common_setsockopt(socket, level, option, value, length, + false); } @@ -1032,8 +1027,9 @@ _user_getpeername(int socket, struct sockaddr *userAddress, { // check parameters socklen_t addressLength = 0; - status_t error = prepare_userland_address_result(userAddress, - _addressLength, addressLength, true); + SyscallRestartWrapper error; + error = prepare_userland_address_result(userAddress, _addressLength, + addressLength, true); if (error != B_OK) return error; @@ -1062,8 +1058,9 @@ _user_getsockname(int socket, struct sockaddr *userAddress, { // check parameters socklen_t addressLength = 0; - status_t error = prepare_userland_address_result(userAddress, - _addressLength, addressLength, true); + SyscallRestartWrapper error; + error = prepare_userland_address_result(userAddress, _addressLength, + addressLength, true); if (error != B_OK) return error; @@ -1089,7 +1086,8 @@ _user_getsockname(int socket, struct sockaddr *userAddress, int _user_sockatmark(int socket) { - return common_sockatmark(socket, false); + SyscallRestartWrapper error; + return error = common_sockatmark(socket, false); } @@ -1104,8 +1102,8 @@ _user_socketpair(int family, int type, int protocol, int *userSocketVector) // socketpair() int socketVector[2]; - status_t error = common_socketpair(family, type, protocol, socketVector, - false); + SyscallRestartWrapper error; + error = common_socketpair(family, type, protocol, socketVector, false); if (error != B_OK) return error; @@ -1135,7 +1133,8 @@ _user_get_next_socket_stat(int family, uint32 *_cookie, struct net_stat *_stat) } net_stat stat; - status_t error = common_get_next_socket_stat(family, &cookie, &stat); + SyscallRestartWrapper error; + error = common_get_next_socket_stat(family, &cookie, &stat); if (error != B_OK) return error;