mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 07:46:42 +00:00
parent
8dda68a1bd
commit
88757a674a
@ -82,6 +82,8 @@ namespace Socket_fs {
|
||||
struct Local_functor;
|
||||
|
||||
Plugin & plugin();
|
||||
|
||||
enum { MAX_CONTROL_PATH_LEN = 16 };
|
||||
}
|
||||
|
||||
|
||||
@ -447,7 +449,7 @@ extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||
/* TODO EOPNOTSUPP - no SOCK_STREAM */
|
||||
/* TODO ECONNABORTED */
|
||||
|
||||
char accept_socket[10];
|
||||
char accept_socket[MAX_CONTROL_PATH_LEN];
|
||||
{
|
||||
int n = 0;
|
||||
/* XXX currently reading accept may return without new connection */
|
||||
@ -503,8 +505,9 @@ extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrl
|
||||
int const len = strlen(addr_string.base());
|
||||
int const n = write(context->bind_fd(), addr_string.base(), len);
|
||||
if (n != len) return Errno(EACCES);
|
||||
fsync(context->bind_fd());
|
||||
return 0;
|
||||
|
||||
/* sync to block for write completion */
|
||||
return fsync(context->bind_fd());
|
||||
} catch (Socket_fs::Context::Inaccessible) {
|
||||
return Errno(EINVAL);
|
||||
}
|
||||
@ -537,7 +540,8 @@ extern "C" int socket_fs_connect(int libc_fd, sockaddr const *addr, socklen_t ad
|
||||
int const n = write(context->connect_fd(), addr_string.base(), len);
|
||||
if (n != len) return Errno(ECONNREFUSED);
|
||||
|
||||
return 0;
|
||||
/* sync to block for write completion */
|
||||
return fsync(context->connect_fd());
|
||||
}
|
||||
|
||||
|
||||
@ -549,7 +553,7 @@ extern "C" int socket_fs_listen(int libc_fd, int backlog)
|
||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||
if (!context) return Errno(ENOTSOCK);
|
||||
|
||||
char buf[10];
|
||||
char buf[MAX_CONTROL_PATH_LEN];
|
||||
int const len = snprintf(buf, sizeof(buf), "%d", backlog);
|
||||
int const n = write(context->listen_fd(), buf, len);
|
||||
if (n != len) return Errno(EOPNOTSUPP);
|
||||
@ -742,23 +746,23 @@ extern "C" int socket_fs_shutdown(int libc_fd, int how)
|
||||
}
|
||||
|
||||
|
||||
static Genode::String<16> new_socket(Absolute_path const &path)
|
||||
static Genode::String<MAX_CONTROL_PATH_LEN> new_socket(Absolute_path const &path)
|
||||
{
|
||||
Absolute_path new_socket("new_socket", path.base());
|
||||
|
||||
int const fd = open(new_socket.base(), O_RDONLY);
|
||||
if (fd == -1) {
|
||||
Genode::error(__func__, ": new_socket file not accessible - socket fs not mounted?");
|
||||
Genode::error(__func__, ": ", new_socket, " file not accessible - socket fs not mounted?");
|
||||
throw New_socket_failed();
|
||||
}
|
||||
char buf[10];
|
||||
char buf[MAX_CONTROL_PATH_LEN];
|
||||
int const n = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
if (n == -1 || !n || n >= (int)sizeof(buf) - 1)
|
||||
throw New_socket_failed();
|
||||
buf[n] = 0;
|
||||
|
||||
return Genode::String<16>(buf);
|
||||
return Genode::String<MAX_CONTROL_PATH_LEN>(buf);
|
||||
}
|
||||
|
||||
|
||||
@ -789,7 +793,7 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol)
|
||||
case Proto::UDP: proto_path.append("/udp"); break;
|
||||
}
|
||||
|
||||
Genode::String<16> socket_path = new_socket(proto_path);
|
||||
auto socket_path = new_socket(proto_path);
|
||||
path.append("/");
|
||||
path.append(socket_path.string());
|
||||
} catch (New_socket_failed) { return Errno(EACCES); }
|
||||
|
@ -884,8 +884,7 @@ int Libc::Vfs_plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
int Libc::Vfs_plugin::fsync(Libc::File_descriptor *fd)
|
||||
{
|
||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||
_vfs_sync(handle);
|
||||
return 0;
|
||||
return _vfs_sync(handle);
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <libc/component.h>
|
||||
#include "task.h"
|
||||
|
||||
/* libc includes */
|
||||
#include <fcntl.h>
|
||||
@ -28,6 +27,11 @@
|
||||
#include <libc-plugin/plugin.h>
|
||||
#include <libc-plugin/fd_alloc.h>
|
||||
|
||||
/* local includes */
|
||||
#include "task.h"
|
||||
#include "libc_errno.h"
|
||||
|
||||
|
||||
namespace Libc { class Vfs_plugin; }
|
||||
|
||||
|
||||
@ -76,8 +80,14 @@ class Libc::Vfs_plugin : public Libc::Plugin
|
||||
}
|
||||
}
|
||||
|
||||
void _vfs_sync(Vfs::Vfs_handle *vfs_handle)
|
||||
/**
|
||||
* Sync a handle and propagate errors
|
||||
*/
|
||||
int _vfs_sync(Vfs::Vfs_handle *vfs_handle)
|
||||
{
|
||||
typedef Vfs::File_io_service::Sync_result Result;
|
||||
Result result = Result::SYNC_QUEUED;
|
||||
|
||||
{
|
||||
struct Check : Libc::Suspend_functor
|
||||
{
|
||||
@ -112,29 +122,32 @@ class Libc::Vfs_plugin : public Libc::Plugin
|
||||
bool retry { false };
|
||||
|
||||
Vfs::Vfs_handle *vfs_handle;
|
||||
Result &result;
|
||||
|
||||
Check(Vfs::Vfs_handle *vfs_handle)
|
||||
: vfs_handle(vfs_handle) { }
|
||||
Check(Vfs::Vfs_handle *vfs_handle, Result &result)
|
||||
: vfs_handle(vfs_handle), result(result) { }
|
||||
|
||||
bool suspend() override
|
||||
{
|
||||
retry = (vfs_handle->fs().complete_sync(vfs_handle) ==
|
||||
Vfs::File_io_service::SYNC_QUEUED);
|
||||
result = vfs_handle->fs().complete_sync(vfs_handle);
|
||||
retry = result == Vfs::File_io_service::SYNC_QUEUED;
|
||||
return retry;
|
||||
}
|
||||
} check(vfs_handle);
|
||||
} check(vfs_handle, result);
|
||||
|
||||
/*
|
||||
* Cannot call Libc::suspend() immediately, because the Libc kernel
|
||||
* might not be running yet.
|
||||
*/
|
||||
if (vfs_handle->fs().complete_sync(vfs_handle) ==
|
||||
Vfs::File_io_service::SYNC_QUEUED) {
|
||||
result = vfs_handle->fs().complete_sync(vfs_handle);
|
||||
if (result == Result::SYNC_QUEUED) {
|
||||
do {
|
||||
Libc::suspend(check);
|
||||
} while (check.retry);
|
||||
}
|
||||
}
|
||||
|
||||
return result == Result::SYNC_OK ? 0 : Libc::Errno(EIO);
|
||||
}
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user