[PATCH 2/2] server: add log message when client connection is destroyed due to an error

mathias_fiedler at mentor.com mathias_fiedler at mentor.com
Thu Jun 8 07:39:07 UTC 2017


From: Mathias Fiedler <mathias_fiedler at mentor.com>

The client connection is destroyed by the server in several
circumstances. This patch adds log messages in case the connection is
destroyed due to an error other than normal hangup.

Signed-off-by: Mathias Fiedler <mathias_fiedler at mentor.com>
---
 src/wayland-server.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 3fa4338..38b3de1 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -300,6 +300,19 @@ wl_resource_post_error(struct wl_resource *resource,
 	client->error = 1;
 }
 
+static void
+destroy_client_with_error(struct wl_client *client, const char *reason, int err)
+{
+	if (err < 0) {
+		wl_log("%s (pid %u): %s\n",
+		       reason, client->ucred.pid, strerror(-err));
+	} else {
+		wl_log("%s (pid %u): protocol error\n",
+		       reason, client->ucred.pid);
+	}
+	wl_client_destroy(client);
+}
+
 static int
 wl_client_connection_data(int fd, uint32_t mask, void *data)
 {
@@ -313,16 +326,30 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
 	uint32_t resource_flags;
 	int opcode, size, since;
 	int len;
+	int err;
+	socklen_t errlen;
 
-	if (mask & (WL_EVENT_ERROR | WL_EVENT_HANGUP)) {
+	if (mask & WL_EVENT_HANGUP) {
 		wl_client_destroy(client);
 		return 1;
 	}
 
+	if (mask & WL_EVENT_ERROR) {
+		// query socket error
+		errlen = sizeof(err);
+		if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen)) {
+			// when getsockopt fails use its error instead
+			err = errno;
+		}
+		destroy_client_with_error(client, "socket error", err);
+		return 1;
+	}
+
 	if (mask & WL_EVENT_WRITABLE) {
 		len = wl_connection_flush(connection);
 		if (len < 0 && errno != EAGAIN) {
-			wl_client_destroy(client);
+			destroy_client_with_error(
+			    client, "failed to flush client connection", errno);
 			return 1;
 		} else if (len >= 0) {
 			wl_event_source_fd_update(client->source,
@@ -334,7 +361,8 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
 	if (mask & WL_EVENT_READABLE) {
 		len = wl_connection_read(connection);
 		if (len == 0 || (len < 0 && errno != EAGAIN)) {
-			wl_client_destroy(client);
+			destroy_client_with_error(
+			    client, "failed to read client connection", errno);
 			return 1;
 		}
 	}
@@ -418,8 +446,10 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
 		len = wl_connection_pending_input(connection);
 	}
 
-	if (client->error)
-		wl_client_destroy(client);
+	if (client->error) {
+		destroy_client_with_error(
+		    client, "error in client communication", client->error);
+	}
 
 	return 1;
 }
-- 
1.9.1



More information about the wayland-devel mailing list