diff --git a/src/libinput-util.h b/src/libinput-util.h index 732f8130..910406cf 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include @@ -230,6 +232,38 @@ matrix_to_farray6(const struct matrix *m, float out[6]) out[5] = m->val[1][2]; } +/** + * Simple wrapper for asprintf that ensures the passed in-pointer is set + * to NULL upon error. + * The standard asprintf() call does not guarantee the passed in pointer + * will be NULL'ed upon failure, whereas this wrapper does. + * + * @param strp pointer to set to newly allocated string. + * This pointer should be passed to free() to release when done. + * @param fmt the format string to use for printing. + * @return The number of bytes printed (excluding the null byte terminator) + * upon success or -1 upon failure. In the case of failure the pointer is set + * to NULL. + */ +static inline int +xasprintf(char **strp, const char *fmt, ...) + LIBINPUT_ATTRIBUTE_PRINTF(2, 3); + +static inline int +xasprintf(char **strp, const char *fmt, ...) +{ + int rc = 0; + va_list args; + + va_start(args, fmt); + rc = vasprintf(strp, fmt, args); + va_end(args); + if ((rc == -1) && strp) + *strp = NULL; + + return rc; +} + enum ratelimit_state { RATELIMIT_EXCEEDED, RATELIMIT_THRESHOLD, diff --git a/test/litest.c b/test/litest.c index 349eca08..30d30566 100644 --- a/test/litest.c +++ b/test/litest.c @@ -876,7 +876,7 @@ litest_init_udev_rules(struct litest_test_device *dev) ck_abort_msg("Failed to create udev rules directory (%s)\n", strerror(errno)); - rc = asprintf(&path, + rc = xasprintf(&path, "%s/%s%s.rules", UDEV_RULES_D, UDEV_RULE_PREFIX, diff --git a/tools/libinput-list-devices.c b/tools/libinput-list-devices.c index 66251731..68ddb612 100644 --- a/tools/libinput-list-devices.c +++ b/tools/libinput-list-devices.c @@ -120,17 +120,17 @@ calibration_default(struct libinput_device *device) float calibration[6]; if (!libinput_device_config_calibration_has_matrix(device)) { - asprintf(&str, "n/a"); + xasprintf(&str, "n/a"); return str; } if (libinput_device_config_calibration_get_default_matrix(device, calibration) == 0) { - asprintf(&str, "identity matrix"); + xasprintf(&str, "identity matrix"); return str; } - asprintf(&str, + xasprintf(&str, "%.2f %.2f %.2f %.2f %.2f %.2f", calibration[0], calibration[1], @@ -150,13 +150,13 @@ scroll_defaults(struct libinput_device *device) scroll_methods = libinput_device_config_scroll_get_methods(device); if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL) { - asprintf(&str, "none"); + xasprintf(&str, "none"); return str; } method = libinput_device_config_scroll_get_default_method(device); - asprintf(&str, + xasprintf(&str, "%s%s%s%s%s%s", (method == LIBINPUT_CONFIG_SCROLL_2FG) ? "*" : "", (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG) ? "two-finger " : "", @@ -176,12 +176,12 @@ click_defaults(struct libinput_device *device) click_methods = libinput_device_config_click_get_methods(device); if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE) { - asprintf(&str, "none"); + xasprintf(&str, "none"); return str; } method = libinput_device_config_click_get_default_method(device); - asprintf(&str, + xasprintf(&str, "%s%s%s%s", (method == LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "*" : "", (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "button-areas " : "",