fixed the way accept() works in regards to the cookie pointer. It is no longer visible to userspace, we pass the fd instead. Also renamed kernel's shutdown() to system_shutdown as it collides with Posix's shutdown().
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21223 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
be2f6ac347
commit
77bf99deb0
@ -86,6 +86,8 @@ extern void fd_set_close_on_exec(struct io_context *context, int fd, bool closeF
|
||||
|
||||
static struct io_context *get_current_io_context(bool kernel);
|
||||
|
||||
extern status_t user_fd_kernel_ioctl(int fd, ulong op, void *buffer, size_t length);
|
||||
|
||||
/* The prototypes of the (sys|user)_ functions are currently defined in vfs.h */
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ extern bool kernel_startup;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t shutdown(bool reboot);
|
||||
status_t system_shutdown(bool reboot);
|
||||
status_t _user_shutdown(bool reboot);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -23,7 +23,7 @@ enum {
|
||||
|
||||
// ops not acting on an existing socket
|
||||
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
||||
NET_STACK_GET_COOKIE, // void **
|
||||
NET_STACK_GET_COOKIE, // void **
|
||||
NET_STACK_CONTROL_NET_MODULE, // control_net_module_args *
|
||||
NET_STACK_GET_NEXT_STAT, // get_next_stat_args *
|
||||
|
||||
@ -72,13 +72,13 @@ struct socket_args { // used by NET_STACK_SOCKET
|
||||
};
|
||||
|
||||
struct socketpair_args { // used by NET_STACK_SOCKETPAIR
|
||||
void *cookie;
|
||||
int second_socket;
|
||||
};
|
||||
|
||||
struct accept_args { // used by NET_STACK_ACCEPT
|
||||
void *cookie;
|
||||
struct sockaddr *address;
|
||||
socklen_t address_length;
|
||||
struct accept_args { // used by NET_STACK_ACCEPT
|
||||
int accept_socket;
|
||||
struct sockaddr *address;
|
||||
socklen_t address_length;
|
||||
};
|
||||
|
||||
struct get_next_stat_args { // used by NET_STACK_GET_NEXT_STAT
|
||||
|
@ -11,6 +11,7 @@ if ( $(TARGET_PLATFORM) != haiku ) {
|
||||
}
|
||||
|
||||
UsePrivateHeaders kernel net ;
|
||||
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||
|
||||
# a) Userland stack version:
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <kernel.h> // IS_KERNEL_ADDRESS
|
||||
#include <fs/fd.h> // user_fd_kernel_ioctl
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -194,6 +197,17 @@ opcode_name(int op)
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
static status_t
|
||||
resolve_cookie(int kernel, int socket, net_stack_cookie **cookie)
|
||||
{
|
||||
if (kernel)
|
||||
return ioctl(socket, NET_STACK_GET_COOKIE, cookie, sizeof(*cookie));
|
||||
else
|
||||
return user_fd_kernel_ioctl(socket, NET_STACK_GET_COOKIE, cookie,
|
||||
sizeof(*cookie));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - device
|
||||
|
||||
|
||||
@ -297,10 +311,10 @@ net_stack_control(void *_cookie, uint32 op, void *data, size_t length)
|
||||
}
|
||||
|
||||
case NET_STACK_GET_COOKIE:
|
||||
// This is needed by accept() call, allowing libnet.so accept() to pass back
|
||||
// in NET_STACK_ACCEPT opcode the cookie (aka the net_stack_cookie!)
|
||||
// of the file descriptor to use for the new accepted socket
|
||||
return user_memcpy(data, &cookie, sizeof(void *));
|
||||
if (!IS_KERNEL_ADDRESS(data))
|
||||
return B_BAD_ADDRESS;
|
||||
*((net_stack_cookie **)data) = cookie;
|
||||
return B_OK;
|
||||
|
||||
case NET_STACK_GET_NEXT_STAT:
|
||||
{
|
||||
@ -349,18 +363,22 @@ net_stack_control(void *_cookie, uint32 op, void *data, size_t length)
|
||||
|
||||
case NET_STACK_ACCEPT:
|
||||
{
|
||||
int kernel = IS_KERNEL_ADDRESS(data);
|
||||
sockaddr_storage address;
|
||||
accept_args args;
|
||||
|
||||
status = check_args_and_address(args, address, data, length, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// args.cookie is the net_stack_cookie of the already opened socket
|
||||
// TODO: find a safer way to do this!
|
||||
net_stack_cookie *accept_cookie;
|
||||
status = resolve_cookie(kernel, args.accept_socket,
|
||||
&accept_cookie);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
net_stack_cookie *acceptCookie = (net_stack_cookie *)args.cookie;
|
||||
status = sSocket->accept(cookie->socket, args.address,
|
||||
&args.address_length, &acceptCookie->socket);
|
||||
&args.address_length, &accept_cookie->socket);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
|
@ -84,18 +84,8 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
if (acceptSocket < 0)
|
||||
return -1;
|
||||
|
||||
// The network stack driver will need to know to which net_stack_cookie to
|
||||
// *bind* with the new accepted socket. It can't itself find out, so we need
|
||||
// to pass it the cookie used internally.
|
||||
// TODO: change this to a safer approach using IDs!
|
||||
void *cookie;
|
||||
if (ioctl(acceptSocket, NET_STACK_GET_COOKIE, &cookie) < 0) {
|
||||
close(acceptSocket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
accept_args args;
|
||||
args.cookie = cookie;
|
||||
args.accept_socket = acceptSocket;
|
||||
args.address = address;
|
||||
args.address_length = _addressLength ? *_addressLength : 0;
|
||||
|
||||
@ -315,14 +305,8 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
||||
if (socketVector[1] < 0)
|
||||
goto err1;
|
||||
|
||||
// TODO: find a better way to do this!
|
||||
void *cookie;
|
||||
if (ioctl(socketVector[1], NET_STACK_GET_COOKIE, &cookie) < 0)
|
||||
goto err2;
|
||||
|
||||
socketpair_args args;
|
||||
args.cookie = cookie;
|
||||
// this way driver can use the right fd/cookie!
|
||||
args.second_socket = socketVector[1];
|
||||
|
||||
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
||||
goto err2;
|
||||
@ -330,7 +314,7 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
close(socketVector[1]);
|
||||
close(socketVector[1]);
|
||||
err1:
|
||||
close(socketVector[0]);
|
||||
return -1;
|
||||
|
@ -249,21 +249,11 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
if (acceptSocket < 0)
|
||||
return -1;
|
||||
|
||||
// The network stack driver will need to know to which net_stack_cookie to
|
||||
// *bind* with the new accepted socket. It can't itself find out, so we need
|
||||
// to pass it the cookie used internally.
|
||||
// TODO: change this to a safer approach using IDs!
|
||||
void *cookie;
|
||||
if (ioctl(acceptSocket, NET_STACK_GET_COOKIE, &cookie) < 0) {
|
||||
close(acceptSocket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool r5compatible = check_r5_compatibility();
|
||||
struct sockaddr r5addr;
|
||||
accept_args args;
|
||||
|
||||
args.cookie = cookie;
|
||||
args.accept_socket = acceptSocket;
|
||||
|
||||
if (r5compatible && address != NULL) {
|
||||
args.address = &r5addr;
|
||||
@ -549,14 +539,8 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
||||
if (socketVector[1] < 0)
|
||||
goto err1;
|
||||
|
||||
// TODO: find a better way to do this!
|
||||
void *cookie;
|
||||
if (ioctl(socketVector[1], NET_STACK_GET_COOKIE, &cookie) < 0)
|
||||
goto err2;
|
||||
|
||||
socketpair_args args;
|
||||
args.cookie = cookie;
|
||||
// this way driver can use the right fd/cookie!
|
||||
args.second_socket = socketVector[1];
|
||||
|
||||
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
||||
goto err2;
|
||||
@ -564,7 +548,7 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
close(socketVector[1]);
|
||||
close(socketVector[1]);
|
||||
err1:
|
||||
close(socketVector[0]);
|
||||
return -1;
|
||||
|
@ -956,15 +956,15 @@ _kern_seek(int fd, off_t pos, int seekType)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_kern_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
static status_t
|
||||
_fd_ioctl(bool kernel_fd, int fd, ulong op, void *buffer, size_t length)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
int status;
|
||||
|
||||
TRACE(("sys_ioctl: fd %d\n", fd));
|
||||
|
||||
descriptor = get_fd(get_current_io_context(true), fd);
|
||||
descriptor = get_fd(get_current_io_context(kernel_fd), fd);
|
||||
if (descriptor == NULL)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
@ -978,6 +978,20 @@ _kern_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_kern_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
{
|
||||
return _fd_ioctl(true, fd, op, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_fd_kernel_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
{
|
||||
return _fd_ioctl(false, fd, op, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
_kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize, uint32 maxCount)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
status_t
|
||||
shutdown(bool reboot)
|
||||
system_shutdown(bool reboot)
|
||||
{
|
||||
// ToDo: shutdown all system services!
|
||||
|
||||
@ -27,6 +27,6 @@ _user_shutdown(bool reboot)
|
||||
{
|
||||
if (geteuid() != 0)
|
||||
return B_NOT_ALLOWED;
|
||||
return shutdown(reboot);
|
||||
return system_shutdown(reboot);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user