From d108954f39537254edbb9b3922d8eead9b5a6ee9 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 12 Jul 2017 19:46:50 +0200 Subject: [PATCH] core: accept NULL consumer strings If the user passes a NULL pointer as the consumer name to any of the line request functions, pass an empty string to the kernel instead of segfaulting. The kernel code will then set the consumer string to "?". Signed-off-by: Bartosz Golaszewski --- src/lib/core.c | 12 ++++++++---- tests/tests-line.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/lib/core.c b/src/lib/core.c index 8b00b18..3fba33d 100644 --- a/src/lib/core.c +++ b/src/lib/core.c @@ -316,8 +316,9 @@ static int line_request_values(struct gpiod_line_bulk *bulk, req->default_values[i] = !!default_vals[i]; } - strncpy(req->consumer_label, config->consumer, - sizeof(req->consumer_label) - 1); + if (config->consumer) + strncpy(req->consumer_label, config->consumer, + sizeof(req->consumer_label) - 1); fd = bulk->lines[0]->chip->fd; @@ -345,8 +346,11 @@ static int line_request_event_single(struct gpiod_line *line, req = &line->event; memset(req, 0, sizeof(*req)); - strncpy(req->consumer_label, config->consumer, - sizeof(req->consumer_label) - 1); + + if (config->consumer) + strncpy(req->consumer_label, config->consumer, + sizeof(req->consumer_label) - 1); + req->lineoffset = gpiod_line_offset(line); req->handleflags |= GPIOHANDLE_REQUEST_INPUT; diff --git a/tests/tests-line.c b/tests/tests-line.c index b0a07bf..fab2998 100644 --- a/tests/tests-line.c +++ b/tests/tests-line.c @@ -396,3 +396,41 @@ static void line_misc_flags(void) TEST_DEFINE(line_misc_flags, "gpiod_line - misc flags", 0, { 8 }); + +static void line_null_consumer(void) +{ + TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL; + struct gpiod_line_request_config config; + struct gpiod_line *line; + int rv; + + chip = gpiod_chip_open(test_chip_path(0)); + TEST_ASSERT_NOT_NULL(chip); + + line = gpiod_chip_get_line(chip, 2); + TEST_ASSERT_NOT_NULL(line); + + config.request_type = GPIOD_REQUEST_DIRECTION_INPUT; + config.consumer = NULL; + config.active_state = GPIOD_REQUEST_ACTIVE_HIGH; + config.flags = 0; + + rv = gpiod_line_request(line, &config, 0); + TEST_ASSERT_RET_OK(rv); + TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?"); + + gpiod_line_release(line); + + /* + * Internally we use different structures for event requests, so we + * need to test that explicitly too. + */ + config.request_type = GPIOD_REQUEST_EVENT_BOTH_EDGES; + + rv = gpiod_line_request(line, &config, 0); + TEST_ASSERT_RET_OK(rv); + TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?"); +} +TEST_DEFINE(line_null_consumer, + "line request - NULL consumer string", + 0, { 8 }); -- 2.30.2