xkb: Don't call exit on failure in weston_compositor_xkb_init()
authorKristian Høgsberg <krh@bitplanet.net>
Sat, 16 Feb 2013 19:29:24 +0000 (14:29 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Mon, 18 Feb 2013 22:39:40 +0000 (17:39 -0500)
This will exit without cleaning vt modes and leave the system stuck.

https://bugs.freedesktop.org/show_bug.cgi?id=60817

src/compositor-drm.c
src/compositor-x11.c
src/compositor.c
src/compositor.h
src/evdev.c
src/evdev.h

index 48b2685..5afbb2a 100644 (file)
@@ -1797,7 +1797,7 @@ drm_restore(struct weston_compositor *ec)
 
 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;
@@ -1811,7 +1811,7 @@ device_added(struct udev_device *udev_device, struct drm_seat *master)
                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);
@@ -1822,20 +1822,26 @@ device_added(struct udev_device *udev_device, struct drm_seat *master)
        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;
        }
 
        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;
@@ -1857,7 +1863,11 @@ evdev_add_devices(struct udev *udev, struct weston_seat *seat_base)
                        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);
        }
@@ -1874,6 +1884,8 @@ evdev_add_devices(struct udev *udev, struct weston_seat *seat_base)
                        "(Weston backend option 'seat', "
                        "udev device property ID_SEAT)\n");
        }
+
+       return 0;
 }
 
 static int
@@ -1976,7 +1988,7 @@ drm_led_update(struct weston_seat *seat_base, enum weston_led leds)
                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)
 {
@@ -1984,7 +1996,7 @@ evdev_input_create(struct weston_compositor *c, struct udev *udev,
 
        seat = malloc(sizeof *seat);
        if (seat == NULL)
-               return;
+               return NULL;
 
        memset(seat, 0, sizeof *seat);
        weston_seat_init(&seat->base, c);
@@ -1992,13 +2004,17 @@ evdev_input_create(struct weston_compositor *c, struct udev *udev,
 
        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
@@ -2307,7 +2323,10 @@ drm_compositor_create(struct wl_display *display,
 
        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 =
index d1b6ec7..9bd7a43 100644 (file)
@@ -293,7 +293,8 @@ x11_input_create(struct x11_compositor *c, int no_input)
        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);
 
index bb129d6..26fd41a 100644 (file)
@@ -2202,14 +2202,15 @@ device_handle_new_drag_icon(struct wl_listener *listener, void *data)
        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;
                }
        }
 
@@ -2221,6 +2222,8 @@ static void weston_compositor_xkb_init(struct weston_compositor *ec,
                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)
@@ -2246,7 +2249,7 @@ static void weston_compositor_xkb_destroy(struct weston_compositor *ec)
        xkb_context_unref(ec->xkb_context);
 }
 
-static void
+static int
 weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
 {
        char *keymap_str;
@@ -2275,7 +2278,7 @@ weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
        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;
 
@@ -2297,21 +2300,21 @@ weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
        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,
@@ -2319,28 +2322,32 @@ weston_compositor_build_global_keymap(struct weston_compositor *ec)
        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);
        }
@@ -2348,7 +2355,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
        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;
@@ -2357,6 +2364,8 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
        wl_seat_set_keyboard(&seat->seat, &seat->keyboard);
 
        seat->has_keyboard = 1;
+
+       return 0;
 }
 
 WL_EXPORT void
@@ -2837,7 +2846,8 @@ weston_compositor_init(struct weston_compositor *ec,
 
        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;
 
index 121f6bf..c7c583e 100644 (file)
@@ -722,7 +722,7 @@ void
 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);
index 1c65b7b..321992e 100644 (file)
@@ -381,7 +381,7 @@ evdev_device_data(int fd, uint32_t mask, void *data)
 }
 
 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)];
@@ -467,9 +467,15 @@ evdev_configure_device(struct evdev_device *device)
                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);
@@ -477,7 +483,8 @@ evdev_configure_device(struct evdev_device *device)
                           device->devname, device->devnode);
        }
        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);
        }
@@ -519,6 +526,13 @@ evdev_device_create(struct weston_seat *seat, const char *path, int device_fd)
        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;
 
index 85c4739..7222de3 100644 (file)
@@ -85,6 +85,8 @@ struct evdev_device {
 #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 {