xkb: Don't call exit on failure in weston_compositor_xkb_init()

This will exit without cleaning vt modes and leave the system stuck.

https://bugs.freedesktop.org/show_bug.cgi?id=60817
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 37e8253..57fcf13 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1934,7 +1934,7 @@
 
 static const char default_seat[] = "seat0";
 
-static void
+static int
 device_added(struct udev_device *udev_device, struct drm_seat *master)
 {
 	struct weston_compositor *c;
@@ -1949,7 +1949,7 @@
 		device_seat = default_seat;
 
 	if (strcmp(device_seat, master->seat_id))
-		return;
+		return 0;
 
 	c = master->base.compositor;
 	devnode = udev_device_get_devnode(udev_device);
@@ -1960,14 +1960,18 @@
 	fd = weston_launcher_open(c, devnode, O_RDWR | O_NONBLOCK);
 	if (fd < 0) {
 		weston_log("opening input device '%s' failed.\n", devnode);
-		return;
+		return -1;
 	}
 
 	device = evdev_device_create(&master->base, devnode, fd);
-	if (!device) {
+	if (device == EVDEV_UNHANDLED_DEVICE) {
 		close(fd);
 		weston_log("not using input device '%s'.\n", devnode);
-		return;
+		return 0;
+	} else if (device == NULL) {
+		close(fd);
+		weston_log("failed to create input device '%s'.\n", devnode);
+		return -1;
 	}
 
 	calibration_values =
@@ -1993,9 +1997,11 @@
 	}
 
 	wl_list_insert(master->devices_list.prev, &device->link);
+
+	return 0;
 }
 
-static void
+static int
 evdev_add_devices(struct udev *udev, struct weston_seat *seat_base)
 {
 	struct drm_seat *seat = (struct drm_seat *) seat_base;
@@ -2017,7 +2023,11 @@
 			continue;
 		}
 
-		device_added(device, seat);
+		if (device_added(device, seat) < 0) {
+			udev_device_unref(device);
+			udev_enumerate_unref(e);
+			return -1;
+		}
 
 		udev_device_unref(device);
 	}
@@ -2034,6 +2044,8 @@
 			"(Weston backend option 'seat', "
 			"udev device property ID_SEAT)\n");
 	}
+
+	return 0;
 }
 
 static int
@@ -2136,7 +2148,7 @@
 		evdev_led_update(device, leds);
 }
 
-static void
+static struct drm_seat *
 evdev_input_create(struct weston_compositor *c, struct udev *udev,
 		   const char *seat_id)
 {
@@ -2144,7 +2156,7 @@
 
 	seat = malloc(sizeof *seat);
 	if (seat == NULL)
-		return;
+		return NULL;
 
 	memset(seat, 0, sizeof *seat);
 	weston_seat_init(&seat->base, c);
@@ -2152,13 +2164,17 @@
 
 	wl_list_init(&seat->devices_list);
 	seat->seat_id = strdup(seat_id);
-	if (!evdev_enable_udev_monitor(udev, &seat->base)) {
-		free(seat->seat_id);
-		free(seat);
-		return;
-	}
+	if (!evdev_enable_udev_monitor(udev, &seat->base))
+		goto err;
+	if (evdev_add_devices(udev, &seat->base) < 0)
+		goto err;
 
-	evdev_add_devices(udev, &seat->base);
+	return seat;
+
+ err:
+	free(seat->seat_id);
+	free(seat);
+	return NULL;
 }
 
 static void
@@ -2486,7 +2502,10 @@
 
 	path = NULL;
 
-	evdev_input_create(&ec->base, ec->udev, seat);
+	if (evdev_input_create(&ec->base, ec->udev, seat) == NULL) {
+		weston_log("failed to create input devices\n");
+		goto err_sprite;
+	}
 
 	loop = wl_display_get_event_loop(ec->base.wl_display);
 	ec->drm_source =
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index e39c482..7a9998c 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -303,7 +303,8 @@
 	weston_seat_init_pointer(&c->core_seat);
 
 	keymap = x11_compositor_get_keymap(c);
-	weston_seat_init_keyboard(&c->core_seat, keymap);
+	if (weston_seat_init_keyboard(&c->core_seat, keymap) < 0)
+		return -1;
 	if (keymap)
 		xkb_map_unref(keymap);
 
diff --git a/src/compositor.c b/src/compositor.c
index 3b16220..6ee3a79 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2363,14 +2363,15 @@
 	weston_seat_update_drag_surface(seat, 0, 0);
 }
 
-static void weston_compositor_xkb_init(struct weston_compositor *ec,
-				       struct xkb_rule_names *names)
+static int
+weston_compositor_xkb_init(struct weston_compositor *ec,
+			   struct xkb_rule_names *names)
 {
 	if (ec->xkb_context == NULL) {
 		ec->xkb_context = xkb_context_new(0);
 		if (ec->xkb_context == NULL) {
 			weston_log("failed to create XKB context\n");
-			exit(1);
+			return -1;
 		}
 	}
 
@@ -2382,6 +2383,8 @@
 		ec->xkb_names.model = strdup("pc105");
 	if (!ec->xkb_names.layout)
 		ec->xkb_names.layout = strdup("us");
+
+	return 0;
 }
 
 static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
@@ -2407,7 +2410,7 @@
 	xkb_context_unref(ec->xkb_context);
 }
 
-static void
+static int
 weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
 {
 	char *keymap_str;
@@ -2436,7 +2439,7 @@
 	keymap_str = xkb_map_get_as_string(xkb_info->keymap);
 	if (keymap_str == NULL) {
 		weston_log("failed to get string version of keymap\n");
-		exit(EXIT_FAILURE);
+		return -1;
 	}
 	xkb_info->keymap_size = strlen(keymap_str) + 1;
 
@@ -2458,21 +2461,21 @@
 	strcpy(xkb_info->keymap_area, keymap_str);
 	free(keymap_str);
 
-	return;
+	return 0;
 
 err_dev_zero:
 	close(xkb_info->keymap_fd);
 	xkb_info->keymap_fd = -1;
 err_keymap_str:
 	free(keymap_str);
-	exit(EXIT_FAILURE);
+	return -1;
 }
 
-static void
+static int
 weston_compositor_build_global_keymap(struct weston_compositor *ec)
 {
 	if (ec->xkb_info.keymap != NULL)
-		return;
+		return 0;
 
 	ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
 						     &ec->xkb_names,
@@ -2480,28 +2483,32 @@
 	if (ec->xkb_info.keymap == NULL) {
 		weston_log("failed to compile global XKB keymap\n");
 		weston_log("  tried rules %s, model %s, layout %s, variant %s, "
-			"options %s",
+			"options %s\n",
 			ec->xkb_names.rules, ec->xkb_names.model,
 			ec->xkb_names.layout, ec->xkb_names.variant,
 			ec->xkb_names.options);
-		exit(1);
+		return -1;
 	}
 
-	weston_xkb_info_new_keymap(&ec->xkb_info);
+	if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
+		return -1;
+
+	return 0;
 }
 
-WL_EXPORT void
+WL_EXPORT int
 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
 {
 	if (seat->has_keyboard)
-		return;
+		return 0;
 
 	if (keymap != NULL) {
 		seat->xkb_info.keymap = xkb_map_ref(keymap);
-		weston_xkb_info_new_keymap(&seat->xkb_info);
-	}
-	else {
-		weston_compositor_build_global_keymap(seat->compositor);
+		if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
+			return -1;
+	} else {
+		if (weston_compositor_build_global_keymap(seat->compositor) < 0)
+			return -1;
 		seat->xkb_info = seat->compositor->xkb_info;
 		seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
 	}
@@ -2509,7 +2516,7 @@
 	seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
 	if (seat->xkb_state.state == NULL) {
 		weston_log("failed to initialise XKB state\n");
-		exit(1);
+		return -1;
 	}
 
 	seat->xkb_state.leds = 0;
@@ -2518,6 +2525,8 @@
 	wl_seat_set_keyboard(&seat->seat, &seat->keyboard.keyboard);
 
 	seat->has_keyboard = 1;
+
+	return 0;
 }
 
 WL_EXPORT void
@@ -2991,7 +3000,8 @@
 
 	weston_plane_init(&ec->primary_plane, 0, 0);
 
-	weston_compositor_xkb_init(ec, &xkb_names);
+	if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
+		return -1;
 
 	ec->ping_handler = NULL;
 
diff --git a/src/compositor.h b/src/compositor.h
index c39abe3..fdde762 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -738,7 +738,7 @@
 weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec);
 void
 weston_seat_init_pointer(struct weston_seat *seat);
-void
+int
 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap);
 void
 weston_seat_init_touch(struct weston_seat *seat);
diff --git a/src/evdev.c b/src/evdev.c
index 0b99c43..286543a 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -397,7 +397,7 @@
 }
 
 static int
-evdev_configure_device(struct evdev_device *device)
+evdev_handle_device(struct evdev_device *device)
 {
 	struct input_absinfo absinfo;
 	unsigned long ev_bits[NBITS(EV_MAX)];
@@ -483,9 +483,15 @@
 		weston_log("input device %s, %s "
 			   "ignored: unsupported device type\n",
 			   device->devname, device->devnode);
-		return -1;
+		return 0;
 	}
 
+	return 1;
+}
+
+static int
+evdev_configure_device(struct evdev_device *device)
+{
 	if ((device->caps &
 	     (EVDEV_MOTION_ABS | EVDEV_MOTION_REL | EVDEV_BUTTON))) {
 		weston_seat_init_pointer(device->seat);
@@ -496,7 +502,8 @@
 			   device->caps & EVDEV_BUTTON ? " button" : "");
 	}
 	if ((device->caps & EVDEV_KEYBOARD)) {
-		weston_seat_init_keyboard(device->seat, NULL);
+		if (weston_seat_init_keyboard(device->seat, NULL) < 0)
+			return -1;
 		weston_log("input device %s, %s is a keyboard\n",
 			   device->devname, device->devnode);
 	}
@@ -538,6 +545,13 @@
 	ioctl(device->fd, EVIOCGNAME(sizeof(devname)), devname);
 	device->devname = strdup(devname);
 
+	if (!evdev_handle_device(device)) {
+		free(device->devnode);
+		free(device->devname);
+		free(device);
+		return EVDEV_UNHANDLED_DEVICE;
+	}
+
 	if (evdev_configure_device(device) == -1)
 		goto err1;
 
diff --git a/src/evdev.h b/src/evdev.h
index a90f90c..ccbb222 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -88,6 +88,8 @@
 #define TEST_BIT(array, bit)    ((array[LONG(bit)] >> OFF(bit)) & 1)
 /* end copied */
 
+#define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
+
 struct evdev_dispatch;
 
 struct evdev_dispatch_interface {