mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-13 22:23:45 +00:00
Libc: MSG_PEEK support
As discovered by Johannes Kliemann, peeking at buffered socket data using 'recv' and 'MSG_PEEK' is not supported. Read a "peek" control file from the socket directory to attempt to peek into buffers at the socket_fs. Support for every feature of POSIX sockets cannot be expected, but this one is trivial to implement. Fix #2875
This commit is contained in:
parent
7f928a6573
commit
adb48b5c9e
@ -131,7 +131,7 @@ struct Libc::Socket_fs::Context : Plugin_context
|
||||
private:
|
||||
|
||||
enum Fd : unsigned {
|
||||
DATA, CONNECT, BIND, LISTEN, ACCEPT, LOCAL, REMOTE, MAX
|
||||
DATA, PEEK, CONNECT, BIND, LISTEN, ACCEPT, LOCAL, REMOTE, MAX
|
||||
};
|
||||
|
||||
struct
|
||||
@ -140,7 +140,7 @@ struct Libc::Socket_fs::Context : Plugin_context
|
||||
int num;
|
||||
File_descriptor *file;
|
||||
} _fd[Fd::MAX] = {
|
||||
{ "data", -1, nullptr },
|
||||
{ "data", -1, nullptr }, { "peek", -1, nullptr },
|
||||
{ "connect", -1, nullptr }, { "bind", -1, nullptr },
|
||||
{ "listen", -1, nullptr }, { "accept", -1, nullptr },
|
||||
{ "local", -1, nullptr }, { "remote", -1, nullptr }
|
||||
@ -205,6 +205,7 @@ struct Libc::Socket_fs::Context : Plugin_context
|
||||
}
|
||||
|
||||
int data_fd() { return _fd_for_type(Fd::DATA, O_RDWR); }
|
||||
int peek_fd() { return _fd_for_type(Fd::PEEK, O_RDONLY); }
|
||||
int connect_fd() { return _fd_for_type(Fd::CONNECT, O_RDWR); }
|
||||
int bind_fd() { return _fd_for_type(Fd::BIND, O_WRONLY); }
|
||||
int listen_fd() { return _fd_for_type(Fd::LISTEN, O_WRONLY); }
|
||||
@ -751,9 +752,11 @@ static ssize_t do_recvfrom(File_descriptor *fd,
|
||||
/* TODO ENOTCONN */
|
||||
/* TODO ECONNREFUSED */
|
||||
|
||||
int data_fd = flags & MSG_PEEK ? context->peek_fd() : context->data_fd();
|
||||
|
||||
try {
|
||||
lseek(context->data_fd(), 0, 0);
|
||||
ssize_t out_len = read(context->data_fd(), buf, len);
|
||||
lseek(data_fd, 0, 0);
|
||||
ssize_t out_len = read(data_fd, buf, len);
|
||||
return out_len;
|
||||
} catch (Socket_fs::Context::Inaccessible) {
|
||||
return Errno(EINVAL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user