gcc -fanalyze complains because it doesn't know the __stop section is
always greater than the __start section so it complains that we're
eventually reading past our __start section. Let's silence that with a
simple check.
The socket backend is useful for debugging and testing but not for real
user-cases where the fd negotiation should be handled by the caller
(e.g. passing it down through the portal). Let's demote the socket
backend in favour of the fd backend.
Related https://gitlab.freedesktop.org/libinput/libei/-/issues/63
A blocking call can be problematic when done from inside Xwayland
to the compositor as the compositor could be doing a blocking X call
at the same time. In this instance we found it's likely to happen
because this call will happen shortly after the user accepted the
This is not a problem for the other calls because the portal API
is async for these via request response signalling.
We know exactly the lengths of everything involved here so let's use
memcpy. This way we don't need the stringop-truncation warning (a pragma
clang doesn't support anyway).
Using MAP_PRIVATE means copy-on-write so our data written into the map
immediately disappears again. This leads to a empty string when sending
a keymap to a client.
As the portal documentation [1] says:
Bitmask of what device types to request remote controlling of. Default is all.
The default is only triggered if we do not submit the types at all, the
current behavior of sending a value of 0 means "none". Fix this by
skipping the "types" key if we try to select for all devices.
[1] https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.impl.portal.RemoteDesktop.html
Because of the asynchronous protocol, we may get this interaction
server sends A->destroyed()
client sends A->foo()
client receives A->destroyed()
server receives A->foo()
server sends invalid_object_id(A)
client receives invalid_object_id(A)
Previously we dropped the object after destroyed() and were thus
guaranteed to warn about the invalid object id for that same object
later.
Fix this by keeping a cache of defunct object IDs that we know about and
ignoring errors for recently dropped objects.
Every 20 ei_dispatch() calls we drop any defunct objects that were
unregistered more than 5 seconds ago.
Fixes#49
Build a separate libei-eierpecken.so that is identical to libei.so but
allows adding an offset to ei_now() for the eierpecken tests. That
offset is added to the return value of ei_now(), removing the real-time
dependency of the tests.
In other words, we can call peck_ei_add_time_offset(peck, s2us(5)) to
add 5 seconds to the time and continue the test as if that time has
elapsed.
This triggered an internal bug message in test_ei_seat_bind_unbind_immediately.
If a client unbinds all capabilities this triggers an EIS_SEAT_BIND with
zero caps. peck would call eis_seat_remove() which calls eis_seat_drop().
That queued another EIS_EVENT_SEAT_BIND with zero capabilities, leading
peck to call eis_seat_remove() again on an already removed seat.
This allows us to handle/manipulate argv and/or pass a userdata to the
tests. Same ELF section approach as we already have with the MUNIT_TEST
macro but this time it's for a global setup.
Note that for the generated __start and __stop section variables we have
to have at least one entry in that section which we do with one
hardcoded (and ignored) one.
SIGALRM *should* not really be an issue for us, most of our IO shouldn't
take long (posix_fallocate is the exception) so we can just retry it
instead of blocking someone's use of SIGALRM.
Doing it here mostly means that the rest of libei doesn't have to care
about EINTR, it'll just be handled transparently (just like before with
the SIGALRM blocks).
If we get disconnected there's no point sending anything anymore, the
server may have already closed the connection.
Otherwise this produces a confusing warning in the log:
18:37:31 | INFO | Disconnected by EIS
... | WARN | failed to send message: Broken pipe
See https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/262#note_2132619
Any error will cause ei_disconnect() which in turn unwinds our context.
Each object removed will cause an ei_send_message() to notify the server
but that will only cause error messages - our socket is already gone.
Fix this by removing the source and checking if the fd is still valid
before we write to it.
Fixes#47
posix_fallocate() may be interrupted (EINTR), e.g. by SIGALRM in the X
server's smart scheduler. On slow systems and for large allocations
this means we cannot ever succeed so let's block SIGALRM like everyone
else does.
See e.g.
4cfee39872
and the same code is in libwayland, libdecor, etc.
Not sure what platforms this isn't the case on and I'm even less sure we
need to care so let's fail the build where this is the case and work it
out if someone complains.
In case our outbound buffers are full we need we need to be able to have a
notification when we're able to write again.
There are two approaches to do this: one is to duplicate the source
(and dup() the fd) and use that for write notifications only. The other
approach is to toggle the source's EPOLLOUT flag on demand, thus
sharing the source dispatch. I picked the latter for simplicity.
With our strings being a 4-byte header followed by the string itself,
they're virtually guaranteed not to be 8-byte aligned. This causes an
issue on some architectures so we need to copy the string out before we
access it.
Since strings are the only protocol type with that extra buffer, let's
hack this in with the minimum effort approach - a null-terminated
char * pointer array that's filled with the strings as they appear in
on the wire. The brei_arg->s points to one of those strings as needed.
This means we can drop the brei_string struct, thanks to pointer alignment
issues this struct doesn't work on s390x, so let's drop it, it no longer
serves any meaningful value.
Fixes#41
We were leaking some of the utility functions, let's not do that.
This is technically an ABI break but if you're relying on libei to
export those functions...well, don't.
This allows a caller to match up a region with other data, e.g. in the
remote desktop case the same mapping_id can be assigned to the pipewire
stream that represents that output.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Wrong calculation resulted in memmoving only the first 32 bytes (i.e. 8
fds) instead of the first 32 fds, resulting in an infinite loop when
cleaning up an iobuf with more than 8 fds.