Discussion:
RFC - Add internal server error message
r***@ubuntu.com
2018-02-20 07:07:25 UTC
Permalink
Because C++ exceptions escaping into C FFI invokes undefined behaviour
our Wayland implementation wraps all the interface vtable callbacks
with try {} catch (...) { log_error }.

This has the nice property of not crashing the server, but does result
in the client and server having different ideas about the current state.

In the interests of debugability it would be nice to tell clients that
their request failed due to server error rather than silently continue
into unknown territory.

These patches introduce a WL_DISPLAY_ERROR_INTERNAL error the compositor
can send in such cases.
r***@ubuntu.com
2018-02-20 07:07:27 UTC
Permalink
From: Christopher James Halse Rogers <***@canonical.com>

Many languages such as C++ or Rust have an unwinding error-reporting
mechanism. Code in these languages can (and must!) wrap request handling
callbacks in unwind guards to avoid undefined behaviour.

As a consequence such code will detect internal server errors, but have
no way to communicate such failures to the client.

This adds a WL_DISPLAY_ERROR_INTERNAL error to wl_display so that
such code can notify (and disconnect) client which hit internal bugs.

Signed-off-by: Christopher James Halse Rogers <***@canonical.com>
---
protocol/wayland.xml | 2 ++
src/wayland-client.c | 3 +++
src/wayland-server-core.h | 4 ++++
src/wayland-server.c | 23 +++++++++++++++++++++++
tests/display-test.c | 40 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 72 insertions(+)

diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index b5662e0..1db31a6 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -94,6 +94,8 @@
summary="method doesn't exist on the specified interface"/>
<entry name="no_memory" value="2"
summary="server is out of memory"/>
+ <entry name="internal" value="3"
+ summary="internal server error"/>
</enum>

<event name="delete_id">
diff --git a/src/wayland-client.c b/src/wayland-client.c
index c1369b8..7c442b1 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -192,6 +192,9 @@ display_protocol_error(struct wl_display *display, uint32_t code,
case WL_DISPLAY_ERROR_NO_MEMORY:
err = ENOMEM;
break;
+ case WL_DISPLAY_ERROR_INTERNAL:
+ err = EPROTO;
+ break;
default:
err = EFAULT;
}
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index 2e725d9..7137da6 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -324,6 +324,10 @@ wl_client_get_object(struct wl_client *client, uint32_t id);
void
wl_client_post_no_memory(struct wl_client *client);

+void
+wl_client_post_internal_error(struct wl_client *client,
+ const char* msg, ...) WL_PRINTF(2,3);
+
void
wl_client_add_resource_created_listener(struct wl_client *client,
struct wl_listener *listener);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 00c93f7..6317f8f 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -650,6 +650,29 @@ wl_client_post_no_memory(struct wl_client *client)
WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
}

+/** Report an internal server error
+ *
+ * \param client The client object
+ * \param msg A printf-style format string
+ * \param ... Format string arguments
+ *
+ * Report an unspecified internal error and disconnect the client.
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_post_internal_error(struct wl_client *client,
+ char const *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(client->display_resource,
+ WL_DISPLAY_ERROR_INTERNAL,
+ msg, ap);
+ va_end(ap);
+}
+
WL_EXPORT void
wl_resource_post_no_memory(struct wl_resource *resource)
{
diff --git a/tests/display-test.c b/tests/display-test.c
index 9b49a0e..63f8b5a 100644
--- a/tests/display-test.c
+++ b/tests/display-test.c
@@ -419,6 +419,46 @@ TEST(post_nomem_tst)
display_destroy(d);
}

+static void
+post_internal_error_main(void)
+{
+ struct client *c = client_connect();
+ struct wl_seat *seat = client_get_seat(c);
+ uint32_t object_id, protocol_error;
+ const struct wl_interface *interface;
+
+ assert(stop_display(c, 1) == -1);
+ int err = wl_display_get_error(c->wl_display);
+ fprintf(stderr, "Err is %i\n", err);
+ assert(err == EPROTO);
+ protocol_error = wl_display_get_protocol_error(c->wl_display,
+ &interface,
+ &object_id);
+ assert(protocol_error == WL_DISPLAY_ERROR_INTERNAL);
+ assert(interface == &wl_display_interface);
+
+ wl_proxy_destroy((struct wl_proxy *) seat);
+ client_disconnect_nocheck(c);
+}
+
+TEST(post_internal_error_tst)
+{
+ struct display *d = display_create();
+ struct client_info *cl;
+
+ wl_global_create(d->wl_display, &wl_seat_interface,
+ 1, d, bind_seat);
+
+ cl = client_create_noarg(d, post_internal_error_main);
+ display_run(d);
+
+ wl_client_post_internal_error(cl->wl_client, "Error %i", 20);
+
+ display_resume(d);
+
+ display_destroy(d);
+}
+
static void
register_reading(struct wl_display *display)
{
--
2.15.1
Pekka Paalanen
2018-02-21 08:15:55 UTC
Permalink
On Tue, 20 Feb 2018 18:07:27 +1100
Post by r***@ubuntu.com
Many languages such as C++ or Rust have an unwinding error-reporting
mechanism. Code in these languages can (and must!) wrap request handling
callbacks in unwind guards to avoid undefined behaviour.
As a consequence such code will detect internal server errors, but have
no way to communicate such failures to the client.
This adds a WL_DISPLAY_ERROR_INTERNAL error to wl_display so that
such code can notify (and disconnect) client which hit internal bugs.
---
protocol/wayland.xml | 2 ++
src/wayland-client.c | 3 +++
src/wayland-server-core.h | 4 ++++
src/wayland-server.c | 23 +++++++++++++++++++++++
tests/display-test.c | 40 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 72 insertions(+)
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index b5662e0..1db31a6 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -94,6 +94,8 @@
summary="method doesn't exist on the specified interface"/>
<entry name="no_memory" value="2"
summary="server is out of memory"/>
+ <entry name="internal" value="3"
+ summary="internal server error"/>
</enum>
<event name="delete_id">
diff --git a/src/wayland-client.c b/src/wayland-client.c
index c1369b8..7c442b1 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -192,6 +192,9 @@ display_protocol_error(struct wl_display *display, uint32_t code,
err = ENOMEM;
break;
+ err = EPROTO;
+ break;
err = EFAULT;
}
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index 2e725d9..7137da6 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -324,6 +324,10 @@ wl_client_get_object(struct wl_client *client, uint32_t id);
void
wl_client_post_no_memory(struct wl_client *client);
+void
+wl_client_post_internal_error(struct wl_client *client,
+ const char* msg, ...) WL_PRINTF(2,3);
+
void
wl_client_add_resource_created_listener(struct wl_client *client,
struct wl_listener *listener);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 00c93f7..6317f8f 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -650,6 +650,29 @@ wl_client_post_no_memory(struct wl_client *client)
WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
}
+/** Report an internal server error
+ *
+ * \param client The client object
+ * \param msg A printf-style format string
+ * \param ... Format string arguments
+ *
+ * Report an unspecified internal error and disconnect the client.
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_post_internal_error(struct wl_client *client,
+ char const *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(client->display_resource,
+ WL_DISPLAY_ERROR_INTERNAL,
+ msg, ap);
+ va_end(ap);
+}
+
Hi,

the explanation here is more explicit than what we discussed in IRC,
and both together give a nice justifiction for adding this. I'm for it,
and I am very happy to see the tests extended as well.

What we discussed in IRC was around why add a new error code instead of
abusing the existing wl_display error codes (it is possible to send
wl_display errors explicitly with custom server code). The outcome of
that was that it would be useful for applications to tell the
difference between their fault and server's fault, to guide automated
bug reporting. This would be nice to add to the commit message.

The one thing I'm wondering is, is "internal" obvious enough to say
it's a server internal error and not a (lib)Wayland internal error?

I've seen Wayland blamed so wildly for things it has nothing to do with
that I might prefer something more explicit, like "implementation"
mentioned by Daniel in IRC. OTOH, what user would see is probably only
the numerical value of the error with the message, so maybe it's
unlikely to be confused.

Acked-by: Pekka Paalanen <***@collabora.co.uk>


Thanks,
pq
Christopher James Halse Rogers
2018-02-22 03:23:10 UTC
Permalink
Post by Pekka Paalanen
On Tue, 20 Feb 2018 18:07:27 +1100
Post by r***@ubuntu.com
From: Christopher James Halse Rogers
Many languages such as C++ or Rust have an unwinding error-reporting
mechanism. Code in these languages can (and must!) wrap request handling
callbacks in unwind guards to avoid undefined behaviour.
As a consequence such code will detect internal server errors, but have
no way to communicate such failures to the client.
This adds a WL_DISPLAY_ERROR_INTERNAL error to wl_display so that
such code can notify (and disconnect) client which hit internal bugs.
Signed-off-by: Christopher James Halse Rogers
---
protocol/wayland.xml | 2 ++
src/wayland-client.c | 3 +++
src/wayland-server-core.h | 4 ++++
src/wayland-server.c | 23 +++++++++++++++++++++++
tests/display-test.c | 40
++++++++++++++++++++++++++++++++++++++++
5 files changed, 72 insertions(+)
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index b5662e0..1db31a6 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -94,6 +94,8 @@
summary="method doesn't exist on the specified interface"/>
<entry name="no_memory" value="2"
summary="server is out of memory"/>
+ <entry name="internal" value="3"
+ summary="internal server error"/>
</enum>
<event name="delete_id">
diff --git a/src/wayland-client.c b/src/wayland-client.c
index c1369b8..7c442b1 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -192,6 +192,9 @@ display_protocol_error(struct wl_display
*display, uint32_t code,
err = ENOMEM;
break;
+ err = EPROTO;
+ break;
err = EFAULT;
}
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index 2e725d9..7137da6 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -324,6 +324,10 @@ wl_client_get_object(struct wl_client *client, uint32_t id);
void
wl_client_post_no_memory(struct wl_client *client);
+void
+wl_client_post_internal_error(struct wl_client *client,
+ const char* msg, ...) WL_PRINTF(2,3);
+
void
wl_client_add_resource_created_listener(struct wl_client *client,
struct wl_listener
*listener);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 00c93f7..6317f8f 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -650,6 +650,29 @@ wl_client_post_no_memory(struct wl_client *client)
WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
}
+/** Report an internal server error
+ *
+ * \param client The client object
+ * \param msg A printf-style format string
+ * \param ... Format string arguments
+ *
+ * Report an unspecified internal error and disconnect the client.
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_post_internal_error(struct wl_client *client,
+ char const *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(client->display_resource,
+ WL_DISPLAY_ERROR_INTERNAL,
+ msg, ap);
+ va_end(ap);
+}
+
Hi,
the explanation here is more explicit than what we discussed in IRC,
and both together give a nice justifiction for adding this. I'm for it,
and I am very happy to see the tests extended as well.
What we discussed in IRC was around why add a new error code instead of
abusing the existing wl_display error codes (it is possible to send
wl_display errors explicitly with custom server code). The outcome of
that was that it would be useful for applications to tell the
difference between their fault and server's fault, to guide automated
bug reporting. This would be nice to add to the commit message.
The one thing I'm wondering is, is "internal" obvious enough to say
it's a server internal error and not a (lib)Wayland internal error?
I've seen Wayland blamed so wildly for things it has nothing to do with
that I might prefer something more explicit, like "implementation"
mentioned by Daniel in IRC. OTOH, what user would see is probably only
the numerical value of the error with the message, so maybe it's
unlikely to be confused.
I'm happy to respin this as wl_client_post_implementation_error; as
Daniel pointed out, there's a nice consonance with the
BadImplementation error from X11.

Does anyone want this particular bikeshed painted a different colour?
Christopher James Halse Rogers
2018-11-20 07:02:48 UTC
Permalink
Resurrecting this from the depths of my email. I think almost 12 months
is long enough to assume no-one else is going to try and paint this
particular bikeshed!
Christopher James Halse Rogers
2018-11-20 07:02:50 UTC
Permalink
Many languages such as C++ or Rust have an unwinding error-reporting
mechanism. Code in these languages can (and must!) wrap request handling
callbacks in unwind guards to avoid undefined behaviour.

As a consequence such code will detect internal server errors, but have
no way to communicate such failures to the client.

This adds a WL_DISPLAY_ERROR_IMPLEMENTATION error to wl_display so that
such code can notify (and disconnect) clients which hit internal bugs.
While servers can currently abuse other wl_display errors for the same
effect, adding an explicit error code allows clients to tell the
difference between errors which are their fault and errors which are the
server's fault. This is particularly interesting for automated bug
reporting.

v2: Rename error from "internal" to "implementation", in sympathy with
X11's BadImplementation error.
Add more justification in the commit message.

Signed-off-by: Christopher James Halse Rogers <***@canonical.com>
Acked-by: Pekka Paalanen <***@collabora.co.uk>
---
protocol/wayland.xml | 2 ++
src/wayland-client.c | 3 +++
src/wayland-server-core.h | 4 ++++
src/wayland-server.c | 24 +++++++++++++++++++++++
tests/display-test.c | 40 +++++++++++++++++++++++++++++++++++++++
5 files changed, 73 insertions(+)

diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 141038b..754b789 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -94,6 +94,8 @@
summary="method doesn't exist on the specified interface"/>
<entry name="no_memory" value="2"
summary="server is out of memory"/>
+ <entry name="implementation" value="3"
+ summary="implementation error in compositor"/>
</enum>

<event name="delete_id">
diff --git a/src/wayland-client.c b/src/wayland-client.c
index 0ccfc66..b0805f1 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -185,6 +185,9 @@ display_protocol_error(struct wl_display *display, uint32_t code,
case WL_DISPLAY_ERROR_NO_MEMORY:
err = ENOMEM;
break;
+ case WL_DISPLAY_ERROR_IMPLEMENTATION:
+ err = EPROTO;
+ break;
default:
err = EFAULT;
}
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index 2e725d9..3e0272b 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -324,6 +324,10 @@ wl_client_get_object(struct wl_client *client, uint32_t id);
void
wl_client_post_no_memory(struct wl_client *client);

+void
+wl_client_post_implementation_error(struct wl_client *client,
+ const char* msg, ...) WL_PRINTF(2,3);
+
void
wl_client_add_resource_created_listener(struct wl_client *client,
struct wl_listener *listener);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index c0ad229..19f6a76 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -650,6 +650,30 @@ wl_client_post_no_memory(struct wl_client *client)
WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
}

+/** Report an internal server error
+ *
+ * \param client The client object
+ * \param msg A printf-style format string
+ * \param ... Format string arguments
+ *
+ * Report an unspecified internal implementation error and disconnect
+ * the client.
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_post_implementation_error(struct wl_client *client,
+ char const *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(client->display_resource,
+ WL_DISPLAY_ERROR_IMPLEMENTATION,
+ msg, ap);
+ va_end(ap);
+}
+
WL_EXPORT void
wl_resource_post_no_memory(struct wl_resource *resource)
{
diff --git a/tests/display-test.c b/tests/display-test.c
index 9b49a0e..6d98cc7 100644
--- a/tests/display-test.c
+++ b/tests/display-test.c
@@ -419,6 +419,46 @@ TEST(post_nomem_tst)
display_destroy(d);
}

+static void
+post_implementation_error_main(void)
+{
+ struct client *c = client_connect();
+ struct wl_seat *seat = client_get_seat(c);
+ uint32_t object_id, protocol_error;
+ const struct wl_interface *interface;
+
+ assert(stop_display(c, 1) == -1);
+ int err = wl_display_get_error(c->wl_display);
+ fprintf(stderr, "Err is %i\n", err);
+ assert(err == EPROTO);
+ protocol_error = wl_display_get_protocol_error(c->wl_display,
+ &interface,
+ &object_id);
+ assert(protocol_error == WL_DISPLAY_ERROR_IMPLEMENTATION);
+ assert(interface == &wl_display_interface);
+
+ wl_proxy_destroy((struct wl_proxy *) seat);
+ client_disconnect_nocheck(c);
+}
+
+TEST(post_internal_error_tst)
+{
+ struct display *d = display_create();
+ struct client_info *cl;
+
+ wl_global_create(d->wl_display, &wl_seat_interface,
+ 1, d, bind_seat);
+
+ cl = client_create_noarg(d, post_implementation_error_main);
+ display_run(d);
+
+ wl_client_post_implementation_error(cl->wl_client, "Error %i", 20);
+
+ display_resume(d);
+
+ display_destroy(d);
+}
+
static void
register_reading(struct wl_display *display)
{
--
2.19.1
Christopher James Halse Rogers
2018-11-20 07:02:49 UTC
Permalink
This will allow other wrappers around wl_resource_post_error to accept
variable argument lists.

Signed-off-by: Christopher James Halse Rogers <***@canonical.com>
Acked-by: Pekka Paalanen <***@collabora.co.uk>
---
src/wayland-server.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index eae8d2e..c0ad229 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -273,17 +273,14 @@ wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
wl_resource_queue_event_array(resource, opcode, args);
}

-WL_EXPORT void
-wl_resource_post_error(struct wl_resource *resource,
- uint32_t code, const char *msg, ...)
+static void
+wl_resource_post_error_vargs(struct wl_resource *resource,
+ uint32_t code, const char *msg, va_list argp)
{
struct wl_client *client = resource->client;
char buffer[128];
- va_list ap;

- va_start(ap, msg);
- vsnprintf(buffer, sizeof buffer, msg, ap);
- va_end(ap);
+ vsnprintf(buffer, sizeof buffer, msg, argp);

/*
* When a client aborts, its resources are destroyed in id order,
@@ -298,6 +295,18 @@ wl_resource_post_error(struct wl_resource *resource,
wl_resource_post_event(client->display_resource,
WL_DISPLAY_ERROR, resource, code, buffer);
client->error = 1;
+
+}
+
+WL_EXPORT void
+wl_resource_post_error(struct wl_resource *resource,
+ uint32_t code, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(resource, code, msg, ap);
+ va_end(ap);
}

static void
--
2.19.1
r***@ubuntu.com
2018-02-20 07:07:26 UTC
Permalink
From: Christopher James Halse Rogers <***@canonical.com>

This will allow other wrappers around wl_resource_post_error to accept
variable argument lists.

Signed-off-by: Christopher James Halse Rogers <***@canonical.com>
---
src/wayland-server.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index eb1e500..00c93f7 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -273,17 +273,14 @@ wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
wl_resource_queue_event_array(resource, opcode, args);
}

-WL_EXPORT void
-wl_resource_post_error(struct wl_resource *resource,
- uint32_t code, const char *msg, ...)
+static void
+wl_resource_post_error_vargs(struct wl_resource *resource,
+ uint32_t code, const char *msg, va_list argp)
{
struct wl_client *client = resource->client;
char buffer[128];
- va_list ap;

- va_start(ap, msg);
- vsnprintf(buffer, sizeof buffer, msg, ap);
- va_end(ap);
+ vsnprintf(buffer, sizeof buffer, msg, argp);

/*
* When a client aborts, its resources are destroyed in id order,
@@ -298,6 +295,18 @@ wl_resource_post_error(struct wl_resource *resource,
wl_resource_post_event(client->display_resource,
WL_DISPLAY_ERROR, resource, code, buffer);
client->error = 1;
+
+}
+
+WL_EXPORT void
+wl_resource_post_error(struct wl_resource *resource,
+ uint32_t code, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(resource, code, msg, ap);
+ va_end(ap);
}

static void
--
2.15.1
Pekka Paalanen
2018-02-21 08:00:52 UTC
Permalink
On Tue, 20 Feb 2018 18:07:26 +1100
Post by r***@ubuntu.com
This will allow other wrappers around wl_resource_post_error to accept
variable argument lists.
---
src/wayland-server.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/wayland-server.c b/src/wayland-server.c
index eb1e500..00c93f7 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -273,17 +273,14 @@ wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
wl_resource_queue_event_array(resource, opcode, args);
}
-WL_EXPORT void
-wl_resource_post_error(struct wl_resource *resource,
- uint32_t code, const char *msg, ...)
+static void
+wl_resource_post_error_vargs(struct wl_resource *resource,
+ uint32_t code, const char *msg, va_list argp)
{
struct wl_client *client = resource->client;
char buffer[128];
- va_list ap;
- va_start(ap, msg);
- vsnprintf(buffer, sizeof buffer, msg, ap);
- va_end(ap);
+ vsnprintf(buffer, sizeof buffer, msg, argp);
/*
* When a client aborts, its resources are destroyed in id order,
@@ -298,6 +295,18 @@ wl_resource_post_error(struct wl_resource *resource,
wl_resource_post_event(client->display_resource,
WL_DISPLAY_ERROR, resource, code, buffer);
client->error = 1;
+
+}
+
+WL_EXPORT void
+wl_resource_post_error(struct wl_resource *resource,
+ uint32_t code, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ wl_resource_post_error_vargs(resource, code, msg, ap);
+ va_end(ap);
}
static void
Acked-by: Pekka Paalanen <***@collabora.co.uk>


Thanks,
pq
Loading...