2 * Copyright © 2014 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 #include <sys/types.h>
32 #include <linux/input.h>
34 #include <libevdev/libevdev.h>
35 #include <libevdev/libevdev-uinput.h>
36 #include "test-common.h"
38 START_TEST(test_revoke)
40 struct uinput_device* uidev;
41 struct libevdev *dev, *dev2;
43 struct input_event ev1, ev2;
46 test_create_device(&uidev, &dev,
56 fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
57 ck_assert_int_gt(fd, -1);
58 rc = libevdev_new_from_fd(fd, &dev2);
59 ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
61 uinput_device_event(uidev, EV_REL, REL_X, 1);
62 uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
64 rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
65 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
67 rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
68 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
70 ck_assert_int_eq(ev1.type, ev2.type);
71 ck_assert_int_eq(ev1.code, ev2.code);
72 ck_assert_int_eq(ev1.value, ev2.value);
74 /* revoke first device, expect it closed, second device still open */
75 dev_fd = libevdev_get_fd(dev);
76 ck_assert_int_ge(dev_fd, 0);
77 rc = ioctl(dev_fd, EVIOCREVOKE, NULL);
78 if (rc == -1 && errno == -EINVAL) {
79 fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
82 ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
84 rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
85 ck_assert_int_eq(rc, -ENODEV);
87 rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
88 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
91 uinput_device_free(uidev);
98 START_TEST(test_revoke_invalid)
100 struct uinput_device* uidev;
101 struct libevdev *dev;
105 test_create_device(&uidev, &dev,
115 dev_fd = libevdev_get_fd(dev);
116 ck_assert_int_ge(dev_fd, 0);
117 /* ioctl requires 0 as value */
118 rc = ioctl(dev_fd, EVIOCREVOKE, 1);
119 ck_assert_int_eq(rc, -1);
120 ck_assert_int_eq(errno, EINVAL);
122 uinput_device_free(uidev);
127 START_TEST(test_revoke_fail_after)
129 struct uinput_device* uidev;
130 struct libevdev *dev, *dev2 = NULL;
133 test_create_device(&uidev, &dev,
143 fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
144 ck_assert_int_gt(fd, -1);
146 rc = ioctl(fd, EVIOCREVOKE, NULL);
147 if (rc == -1 && errno == -EINVAL) {
148 fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
151 ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
153 rc = libevdev_new_from_fd(fd, &dev2);
154 ck_assert_int_eq(rc, -ENODEV);
157 uinput_device_free(uidev);
163 int main(int argc, char **argv)
170 s = suite_create("kernel tests");
172 tc = tcase_create("EVIOCREVOKE");
173 tcase_add_test(tc, test_revoke);
174 tcase_add_test(tc, test_revoke_invalid);
175 tcase_add_test(tc, test_revoke_fail_after);
176 suite_add_tcase(s, tc);
178 sr = srunner_create(s);
179 srunner_run_all(sr, CK_NORMAL);
181 failed = srunner_ntests_failed(sr);