core: don't allow OPEN_DRAIN & OPEN_SOURCE flags for input
authorBartosz Golaszewski <bartekgola@gmail.com>
Mon, 16 Oct 2017 15:45:27 +0000 (17:45 +0200)
committerBartosz Golaszewski <bartekgola@gmail.com>
Mon, 16 Oct 2017 15:54:31 +0000 (17:54 +0200)
OPEN_DRAIN and OPEN_SOURCE flags only affect the way we drive a GPIO
line, so they only make sense for output mode.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
src/lib/core.c
tests/tests-line.c

index ecf000a835b9f3727c4dab5d36f4cb8b571e46fb..7a73137d5356c922615829adfb7257a61786d1cc 100644 (file)
@@ -441,6 +441,13 @@ static int line_request_values(struct gpiod_line_bulk *bulk,
        unsigned int i;
        int rv, fd;
 
+       if ((config->request_type != GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) &&
+           (config->flags & (GPIOD_LINE_REQUEST_OPEN_DRAIN |
+                             GPIOD_LINE_REQUEST_OPEN_SOURCE))) {
+               errno = EINVAL;
+               return -1;
+       }
+
        handle = malloc(sizeof(*handle));
        if (!handle)
                return -1;
index 0aaeb98f4ea5274ec9abd28ef5d2504b37b7378e..c3b54881ed8cbb700a44b920c477a881e2ade8b2 100644 (file)
@@ -428,6 +428,32 @@ TEST_DEFINE(line_misc_flags,
            "gpiod_line - misc flags",
            0, { 8 });
 
+static void line_open_source_open_drain_input_invalid(void)
+{
+       TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL;
+       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);
+
+       rv = gpiod_line_request_input_flags(line, TEST_CONSUMER,
+                                           GPIOD_LINE_REQUEST_OPEN_DRAIN);
+       TEST_ASSERT_EQ(rv, -1);
+       TEST_ASSERT_ERRNO_IS(EINVAL);
+
+       rv = gpiod_line_request_input_flags(line, TEST_CONSUMER,
+                                           GPIOD_LINE_REQUEST_OPEN_SOURCE);
+       TEST_ASSERT_EQ(rv, -1);
+       TEST_ASSERT_ERRNO_IS(EINVAL);
+}
+TEST_DEFINE(line_open_source_open_drain_input_invalid,
+           "gpiod_line - open-source & open-drain for input mode (invalid)",
+           0, { 8 });
+
 static void line_null_consumer(void)
 {
        TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL;