mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
LxIP: propagate write errors using SYNC_ERR_INVALID
The libc sockets implementation already syncs socket control files after writes, so sync errors will induce failures for operations such as "connect". Fix #2920
This commit is contained in:
parent
08b774e318
commit
a7e5d4ef03
@ -195,6 +195,9 @@ struct Vfs::File : Vfs::Node
|
||||
Genode::error(name(), " not readable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual File_io_service::Sync_result sync() {
|
||||
return File_io_service::Sync_result::SYNC_OK; }
|
||||
};
|
||||
|
||||
|
||||
@ -256,6 +259,7 @@ struct Vfs::Lxip_vfs_handle : Vfs::Vfs_handle
|
||||
{
|
||||
typedef File_io_service:: Read_result Read_result;
|
||||
typedef File_io_service::Write_result Write_result;
|
||||
typedef File_io_service::Sync_result Sync_result;
|
||||
|
||||
Lxip_vfs_handle(Vfs::File_system &fs, Allocator &alloc, int status_flags)
|
||||
: Vfs::Vfs_handle(fs, fs, alloc, status_flags) { }
|
||||
@ -267,6 +271,8 @@ struct Vfs::Lxip_vfs_handle : Vfs::Vfs_handle
|
||||
virtual Write_result write(char const *src,
|
||||
file_size count, file_size &out_count) = 0;
|
||||
|
||||
virtual Sync_result sync() {
|
||||
return Sync_result::SYNC_OK; }
|
||||
};
|
||||
|
||||
|
||||
@ -327,6 +333,9 @@ struct Vfs::Lxip_vfs_file_handle final : Vfs::Lxip_vfs_handle
|
||||
content_buffer[len+1] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Sync_result sync() override {
|
||||
return (file) ? file->sync() : Sync_result::SYNC_ERR_INVALID; }
|
||||
};
|
||||
|
||||
|
||||
@ -386,6 +395,8 @@ class Vfs::Lxip_file : public Vfs::File
|
||||
Lxip::Socket_dir &_parent;
|
||||
Linux::socket &_sock;
|
||||
|
||||
int _write_err = 0;
|
||||
|
||||
bool _sock_valid() { return _sock.sk != nullptr; }
|
||||
|
||||
public:
|
||||
@ -409,6 +420,13 @@ class Vfs::Lxip_file : public Vfs::File
|
||||
le = handles.first();
|
||||
}
|
||||
}
|
||||
|
||||
File_io_service::Sync_result sync() override
|
||||
{
|
||||
return (_write_err)
|
||||
? File_io_service::Sync_result::SYNC_ERR_INVALID
|
||||
: File_io_service::Sync_result::SYNC_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -451,7 +469,8 @@ class Vfs::Lxip_data_file : public Vfs::Lxip_file
|
||||
msghdr msg = create_msghdr(&_parent.remote_addr(),
|
||||
sizeof(sockaddr_in), len, &iov);
|
||||
|
||||
return _sock.ops->sendmsg(&_sock, &msg, len);
|
||||
_write_err = _sock.ops->sendmsg(&_sock, &msg, len);
|
||||
return _write_err;
|
||||
}
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &,
|
||||
@ -519,8 +538,8 @@ class Vfs::Lxip_bind_file : public Vfs::Lxip_file
|
||||
addr->sin_addr.s_addr = get_addr(handle.content_buffer);
|
||||
addr->sin_family = AF_INET;
|
||||
|
||||
int res = _sock.ops->bind(&_sock, (sockaddr*)addr, sizeof(addr_storage));
|
||||
if (res != 0) return -1;
|
||||
_write_err = _sock.ops->bind(&_sock, (sockaddr*)addr, sizeof(addr_storage));
|
||||
if (_write_err != 0) return -1;
|
||||
|
||||
_port = port;
|
||||
|
||||
@ -572,15 +591,13 @@ class Vfs::Lxip_listen_file : public Vfs::Lxip_file
|
||||
|
||||
if (!handle.write_content_line(src, len)) return -1;
|
||||
|
||||
Lxip::ssize_t res;
|
||||
|
||||
Genode::ascii_to_unsigned(
|
||||
handle.content_buffer, _backlog, sizeof(handle.content_buffer));
|
||||
|
||||
if (_backlog == ~0UL) return -1;
|
||||
|
||||
res = _sock.ops->listen(&_sock, _backlog);
|
||||
if (res != 0) {
|
||||
_write_err = _sock.ops->listen(&_sock, _backlog);
|
||||
if (_write_err != 0) {
|
||||
handle.write_content_line("", 0);
|
||||
return -1;
|
||||
}
|
||||
@ -637,9 +654,9 @@ class Vfs::Lxip_connect_file : public Vfs::Lxip_file
|
||||
addr->sin_addr.s_addr = get_addr(handle.content_buffer);
|
||||
addr->sin_family = AF_INET;
|
||||
|
||||
int res = _sock.ops->connect(&_sock, (sockaddr *)addr, sizeof(addr_storage), 0);
|
||||
_write_err = _sock.ops->connect(&_sock, (sockaddr *)addr, sizeof(addr_storage), 0);
|
||||
|
||||
switch (res) {
|
||||
switch (_write_err) {
|
||||
case Lxip::Io_result::LINUX_EINPROGRESS:
|
||||
_connecting = true;
|
||||
return -1;
|
||||
@ -658,7 +675,7 @@ class Vfs::Lxip_connect_file : public Vfs::Lxip_file
|
||||
break;
|
||||
|
||||
default:
|
||||
if (res != 0) return -1;
|
||||
if (_write_err != 0) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1883,6 +1900,13 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
|
||||
*static_cast<Lxip_vfs_handle *>(vfs_handle);
|
||||
return handle.read_ready();
|
||||
}
|
||||
|
||||
Sync_result complete_sync(Vfs_handle *vfs_handle)
|
||||
{
|
||||
Vfs::Lxip_vfs_handle *handle =
|
||||
static_cast<Vfs::Lxip_vfs_handle*>(vfs_handle);
|
||||
return handle->sync();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user