diff --git a/src/libratbag-hidraw.c b/src/libratbag-hidraw.c index 462dcbf5..fd475be4 100644 --- a/src/libratbag-hidraw.c +++ b/src/libratbag-hidraw.c @@ -40,11 +40,13 @@ ratbag_open_hidraw(struct ratbag *ratbag) { struct hidraw_devinfo info; int fd, res; + const char *devnode; if (!ratbag->udev_hidraw) return -EINVAL; - fd = open(udev_device_get_devnode(ratbag->udev_hidraw), O_RDWR); + devnode = udev_device_get_devnode(ratbag->udev_hidraw); + fd = ratbag_open_path(ratbag, devnode, O_RDWR); if (fd < 0) goto err; @@ -67,7 +69,7 @@ ratbag_open_hidraw(struct ratbag *ratbag) err: if (fd >= 0) - close(fd); + ratbag_close_fd(ratbag, fd); return -errno; } diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 9c859643..ec03690e 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -39,6 +39,18 @@ struct ratbag_driver; +struct libratbag { + const struct libratbag_interface *interface; + void *userdata; + + struct udev *udev; + struct list drivers; + + int refcount; + libratbag_log_handler log_handler; + enum libratbag_log_priority log_priority; +}; + struct ratbag { char *name; struct udev_device *udev_device; @@ -102,6 +114,22 @@ struct ratbag_button { enum ratbag_button_action_type action_type; }; +static inline int +ratbag_open_path(struct ratbag *ratbag, const char *path, int flags) +{ + struct libratbag *libratbag = ratbag->libratbag; + + return libratbag->interface->open_restricted(path, flags, libratbag->userdata); +} + +static inline void +ratbag_close_fd(struct ratbag *ratbag, int fd) +{ + struct libratbag *libratbag = ratbag->libratbag; + + return libratbag->interface->close_restricted(fd, libratbag->userdata); +} + static inline void ratbag_set_drv_data(struct ratbag *ratbag, void *drv_data) { @@ -126,6 +154,7 @@ ratbag_profile_get_drv_data(struct ratbag_profile *profile) return profile->drv_data; } + void log_msg_va(struct libratbag *libratbag, enum libratbag_log_priority priority, diff --git a/src/libratbag.c b/src/libratbag.c index 4805a37a..f3d6dc84 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -24,7 +24,6 @@ #include "config.h" #include #include -#include #include #include #include @@ -35,15 +34,6 @@ #include "libratbag-private.h" #include "libratbag-util.h" -struct libratbag { - struct udev *udev; - struct list drivers; - - int refcount; - libratbag_log_handler log_handler; - enum libratbag_log_priority log_priority; -}; - static void libratbag_default_log_func(struct libratbag *libratbag, enum libratbag_log_priority priority, @@ -362,15 +352,23 @@ ratbag_register_driver(struct libratbag *libratbag, struct ratbag_driver *driver } LIBRATBAG_EXPORT struct libratbag * -libratbag_create_context(void) +libratbag_create_context(const struct libratbag_interface *interface, + void *userdata) { struct libratbag *libratbag; + if (interface == NULL || + interface->open_restricted == NULL || + interface->close_restricted == NULL) + return NULL; + libratbag = zalloc(sizeof(*libratbag)); if (!libratbag) return NULL; libratbag->refcount = 1; + libratbag->interface = interface; + libratbag->userdata = userdata; list_init(&libratbag->drivers); libratbag->udev = udev_new(); diff --git a/src/libratbag.h b/src/libratbag.h index e7215a30..e60c296a 100644 --- a/src/libratbag.h +++ b/src/libratbag.h @@ -132,6 +132,39 @@ struct ratbag_profile; */ struct ratbag_button; +/** + * @ingroup base + * @struct libratbag_interface + * + * libratbag does not open file descriptors to devices directly, instead + * open_restricted() and close_restricted() are called for each path that + * must be opened. + * + * @see libratbag_create_context + */ +struct libratbag_interface { + /** + * Open the device at the given path with the flags provided and + * return the fd. + * + * @param path The device path to open + * @param flags Flags as defined by open(2) + * @param user_data The user_data provided in + * libratbag_create_context() + * + * @return The file descriptor, or a negative errno on failure. + */ + int (*open_restricted)(const char *path, int flags, void *user_data); + /** + * Close the file descriptor. + * + * @param fd The file descriptor to close + * @param user_data The user_data provided in + * libratbag_create_context() + */ + void (*close_restricted)(int fd, void *user_data); +}; + /** * @ingroup base * @@ -140,7 +173,8 @@ struct ratbag_button; * @return An initialized libratbag context or NULL on error */ struct libratbag * -libratbag_create_context(void); +libratbag_create_context(const struct libratbag_interface *interface, + void *userdata); /** * @ingroup base diff --git a/tools/ratbag-command.c b/tools/ratbag-command.c index 39c12352..dfda3780 100644 --- a/tools/ratbag-command.c +++ b/tools/ratbag-command.c @@ -89,6 +89,29 @@ parse_args(int argc, char **argv, const char **path, int *verbose) return 0; } +static int +open_restricted(const char *path, int flags, void *user_data) +{ + int fd = open(path, flags); + + if (fd < 0) + fprintf(stderr, "Failed to open %s (%s)\n", + path, strerror(errno)); + + return fd < 0 ? -errno : fd; +} + +static void +close_restricted(int fd, void *user_data) +{ + close(fd); +} + +const struct libratbag_interface interface = { + .open_restricted = open_restricted, + .close_restricted = close_restricted, +}; + int main(int argc, char **argv) { @@ -113,7 +136,7 @@ main(int argc, char **argv) return 1; } - libratbag = libratbag_create_context(); + libratbag = libratbag_create_context(&interface, NULL); if (!libratbag) { fprintf(stderr, "Can't initilize libratbag\n"); return 1;