parent
8dda68a1bd
commit
88757a674a
|
@ -82,6 +82,8 @@ namespace Socket_fs {
|
||||||
struct Local_functor;
|
struct Local_functor;
|
||||||
|
|
||||||
Plugin & plugin();
|
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 EOPNOTSUPP - no SOCK_STREAM */
|
||||||
/* TODO ECONNABORTED */
|
/* TODO ECONNABORTED */
|
||||||
|
|
||||||
char accept_socket[10];
|
char accept_socket[MAX_CONTROL_PATH_LEN];
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
/* XXX currently reading accept may return without new connection */
|
/* 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 len = strlen(addr_string.base());
|
||||||
int const n = write(context->bind_fd(), addr_string.base(), len);
|
int const n = write(context->bind_fd(), addr_string.base(), len);
|
||||||
if (n != len) return Errno(EACCES);
|
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) {
|
} catch (Socket_fs::Context::Inaccessible) {
|
||||||
return Errno(EINVAL);
|
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);
|
int const n = write(context->connect_fd(), addr_string.base(), len);
|
||||||
if (n != len) return Errno(ECONNREFUSED);
|
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);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
if (!context) return Errno(ENOTSOCK);
|
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 len = snprintf(buf, sizeof(buf), "%d", backlog);
|
||||||
int const n = write(context->listen_fd(), buf, len);
|
int const n = write(context->listen_fd(), buf, len);
|
||||||
if (n != len) return Errno(EOPNOTSUPP);
|
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());
|
Absolute_path new_socket("new_socket", path.base());
|
||||||
|
|
||||||
int const fd = open(new_socket.base(), O_RDONLY);
|
int const fd = open(new_socket.base(), O_RDONLY);
|
||||||
if (fd == -1) {
|
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();
|
throw New_socket_failed();
|
||||||
}
|
}
|
||||||
char buf[10];
|
char buf[MAX_CONTROL_PATH_LEN];
|
||||||
int const n = read(fd, buf, sizeof(buf));
|
int const n = read(fd, buf, sizeof(buf));
|
||||||
close(fd);
|
close(fd);
|
||||||
if (n == -1 || !n || n >= (int)sizeof(buf) - 1)
|
if (n == -1 || !n || n >= (int)sizeof(buf) - 1)
|
||||||
throw New_socket_failed();
|
throw New_socket_failed();
|
||||||
buf[n] = 0;
|
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;
|
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("/");
|
||||||
path.append(socket_path.string());
|
path.append(socket_path.string());
|
||||||
} catch (New_socket_failed) { return Errno(EACCES); }
|
} 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)
|
int Libc::Vfs_plugin::fsync(Libc::File_descriptor *fd)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
_vfs_sync(handle);
|
return _vfs_sync(handle);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <libc/component.h>
|
#include <libc/component.h>
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -28,6 +27,11 @@
|
||||||
#include <libc-plugin/plugin.h>
|
#include <libc-plugin/plugin.h>
|
||||||
#include <libc-plugin/fd_alloc.h>
|
#include <libc-plugin/fd_alloc.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include "task.h"
|
||||||
|
#include "libc_errno.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Libc { class Vfs_plugin; }
|
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
|
struct Check : Libc::Suspend_functor
|
||||||
{
|
{
|
||||||
|
@ -112,29 +122,32 @@ class Libc::Vfs_plugin : public Libc::Plugin
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
Vfs::Vfs_handle *vfs_handle;
|
Vfs::Vfs_handle *vfs_handle;
|
||||||
|
Result &result;
|
||||||
|
|
||||||
Check(Vfs::Vfs_handle *vfs_handle)
|
Check(Vfs::Vfs_handle *vfs_handle, Result &result)
|
||||||
: vfs_handle(vfs_handle) { }
|
: vfs_handle(vfs_handle), result(result) { }
|
||||||
|
|
||||||
bool suspend() override
|
bool suspend() override
|
||||||
{
|
{
|
||||||
retry = (vfs_handle->fs().complete_sync(vfs_handle) ==
|
result = vfs_handle->fs().complete_sync(vfs_handle);
|
||||||
Vfs::File_io_service::SYNC_QUEUED);
|
retry = result == Vfs::File_io_service::SYNC_QUEUED;
|
||||||
return retry;
|
return retry;
|
||||||
}
|
}
|
||||||
} check(vfs_handle);
|
} check(vfs_handle, result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cannot call Libc::suspend() immediately, because the Libc kernel
|
* Cannot call Libc::suspend() immediately, because the Libc kernel
|
||||||
* might not be running yet.
|
* might not be running yet.
|
||||||
*/
|
*/
|
||||||
if (vfs_handle->fs().complete_sync(vfs_handle) ==
|
result = vfs_handle->fs().complete_sync(vfs_handle);
|
||||||
Vfs::File_io_service::SYNC_QUEUED) {
|
if (result == Result::SYNC_QUEUED) {
|
||||||
do {
|
do {
|
||||||
Libc::suspend(check);
|
Libc::suspend(check);
|
||||||
} while (check.retry);
|
} while (check.retry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result == Result::SYNC_OK ? 0 : Libc::Errno(EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user