The C extension methods request_set_values() and request_get_values()
iterate over a caller-supplied sequence and write offsets/values into
pre-allocated buffers self->offsets and self->values, without checking
the write index.
If the user tries to read values for more lines than they previously
requested, we overflow the buffers.
Add appropriate bounds checks and implement test cases for this issue.
Fixes: b7ba732e6a ("treewide: libgpiod v2 implementation")
Reported-by: 4fqr <4fqr@proton.me>
Tested-by: Vincent Fazio <vfazio@xes-inc.com>
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://patch.msgid.link/20260407-treewide-fixes-v1-1-66c9744a56a3@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Previously, lines requested by name could also be referred to by offset
when calling LineRequest.reconfigure_lines. However, lines requested by
offset could not be reconfigured by name if they had one.
Now, the name map is populated if the line has a name regardless of if
it's requested by name or offset.
To make behavior as consistent with earlier versions as possible, a line
requested by name always returns the first line on the chip with that
name. If there are duplicate line names and lines are requested by
offset, the first line in the request is mapped to the name. A line
requested by name always overrides a name mapped via an offset request.
If lines 0-3 all have the same name and a config object looks like:
{("foo", 1, 2): None}
or
{(1, "foo", 2): None}
Then lines 0-2 are requested and line 0 can be reconfigured by name.
If the config object looks like:
{(1, 2): None}
Then lines 1 and 2 are requested and line 1 can be reconfigured by name.
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
Link: https://lore.kernel.org/r/20251009130516.3729433-9-vfazio@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Previously, calling `reconfigure_lines` with line identifiers that were
not included in the original request produced different behaviors
depending on the identifier type.
If the identifier was an integer, it would be silently ignored.
If the identifier was a string, it would raise a `ValueError`.
To be consistent, invalid line names are now silently ignored.
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
Link: https://lore.kernel.org/r/20251009130516.3729433-7-vfazio@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
When `chip.request_lines` was modified to allow `Iterable`s instead of
only `tuple`s, the code that checked for duplicate line entries in the
`config` argument was not updated to account for the expanded types.
If the `config` argument had a key that was not a `tuple`, `str`, or
`int`, a `TypeError` would be raised when resolving the line offset.
Refactor the code the resolves IDs to offsets into a separate function
to make the logic a bit clearer and to account for the widened types.
Fixes: 8f62e6c453 ("bindings: python: loosen type requirements in public API")
Closes: https://github.com/brgl/libgpiod/issues/148
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
Link: https://lore.kernel.org/r/20250902123905.6491-1-vfazio@gmail.com
[Bartosz: don't pass the only argument by name in the call to
_resolve_config_keys_to_offsets()]
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Linux kernel commit 8bd76b3d3f3a ("gpio: sim: lock up configfs that an
instantiated device depends on") uncovered an issue in Python bindings
tests where the GPIO simulator device is not disabled before removing its
configfs entries. Reorder the operations in chip_finalize() in order to
disable the device first (if needed) before releasing any other
resources.
Link: https://lore.kernel.org/r/20250203-fix-gpiosim-in-bindings-v1-2-d2c9e0f3a29d@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Certain polling APIs in the standard library - most notably: the
select() function and the poll class - allow to poll any object that
implements the fileno() method returning the underlying file descriptor
number.
Implement fileno() for Chip and LineRequest which allows users to do:
rd, _, _ = select([chip/request], [], [], 1)
where rd will contain the actual object passed to select which makes for
easier reading of events afterwards.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241211-python-fileno-v2-1-84c642572485@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
We claim that libgpiod python bindings have no dependencies other than
the python standard library but this is not true - the tests do depend
on deprecated distutils for kernel version parsing.
As distutils is deprecated, the recommended improvement is to use the
Version class from packaging.version but this would too entail pulling
in an external module.
Let's instead implement the kernel version check in C using uname() and
put it into the tests.system extension. This allows us to entirely drop
the distutils import.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241120-drop-distutils-v1-3-7498e8b3babe@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Since their inclusion in Python 3.6, f-strings have become the preferred
way to format strings with variable values as they are generally more
readable as the value substitution is in place and doesn't have to be
parsed from the list or arguments to `.format()`.
Where it does not impact readability (when the line is <120 characters),
swap usage of `.format()` to an f-string.
For lines that are not converted, inform the linter to ignore attempts
to upgrade those instances to f-strings [0]
[0]: https://docs.astral.sh/ruff/rules/f-string/
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-23-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Some of the unit tests intentionally call methods or assign properties
with invalid values to ensure they fail in an expected way.
Type checkers complain for these instances so inform them via directive
that these lines should be ignore for specific errors.
Additionally, some lines that access properties without assigning the
value look like they perform no action to linters.
To appease the linter, read the value into a throw-away variable.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-22-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Add type hints for internal members of the test cases so type checkers
can ensure the code properly constrains to these types and accounts for
scenarios where the values are `None`.
In most cases, the type checker is allowed to assume the inferred type
upon assignment.
An example is any test case that creates a `Chip` as part of its `setUp`
method. Many of these tests subsequently set the reference to `None` in
`tearDown` to free up resources to be collected by the GC.
If the member was "properly" typed to be `Optional`, all references in
the unit tests would need to be guarded by an assert or a cast or
ignored by the type checker. This is noisy and doesn't add value since
for the life of the test it should always be a valid reference.
Instead, allow `tearDown` to violate the inferred type and inform the
type checker to ignore the assignment via directive.
If the tests are ever changed to set the member to something other than
the inferred type outside of `tearDown`, explicit type hints and proper
checks should be added.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-21-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Previously, both tests_edge_event and tests_info_event had a public
module level EventType member.
The __main__ module for unittests does a star import from both modules
which led to an import conflict between the two.
It is not necessary to import EventType to run unit tests.
Now, EventType is private to avoid being imported via star syntax.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-18-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Previously, the `test_rising_edge_event` test was defined twice.
The second instance of the test actually tested the falling edge event
and was shadowing the first test which tested the rising edge event.
Now, the second instance is renamed to `test_falling_edge_event` to
reflect what it is testing and to avoid the naming conflict.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-16-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Use black to make the coding style of the line-request test cases
consistent with the rest of the codebase.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
We currently only have a test-case that checks if the event clock
property is correctly set in the LineSettings object but not whether it
is actually passed to the line request. Extend the existing test-case for
line requests to account for event clocks as well.
Link: https://lore.kernel.org/r/20240731104658.93117-2-brgl@bgdev.pl
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The kernel's handling of reconfigure with default values, as is the
case for providing a None value as the settings to the Python bindings'
reconfigure_lines(), resets any flags set to non-default values when the
line is requested to their default values. While the flags are cleared,
the kernel makes no corresponding change to the electrical settings -
though subsequent calls to get and set values will apply the updated
flags.
The tests for missing or None settings are extended to demonstrate the
issue for active_low and drive flags, though the issue applies to all
flags.
The tests fail unless the kernel is patched to ignore reconfiguration
of lines without direction set.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20240626053808.179457-4-warthog618@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Make the new test file for line definitions part of the entire test-suite
for python bindings.
Fixes: c8e3ae0499 ("bindings: python: tests: add test for casting line.Value to bool")
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The __repr__() function should - if possible - return a valid Python
expression that can be used to instantiate a new object when evaluated.
LineSettings.__repr__() is missing comas between arguments. Both Chip and
LineSettings also don't prefix the returned string with 'gpiod.'. Fix
both functions and add more test cases - including actually using the
strings returned by __repr__() to create new objects and compare their
contents.
Reported-by: Robert Thomas <rob.thomas@raspberrypi.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The presence of _distutils in setuptools is an implementation detail. If
we want anything from the distutils package, we should import it directly.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
There are no thread-safety guarantees in libgpiod. Let's not reuse the
chip object created in one thread to generate info events in another but
use a global request function instead.
Reported-by: Erik Schilling <erik.schilling@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Erik Schilling <erik.schilling@linaro.org>
Provide a wrapper around gpiod_line_request_get_chip_name() for Python
bindings and update the tests.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
It seems like every release there's some new problem with parsing the
version strings in tests. Let's reduce the strictness of the patterns
to avoid future test failures and accept the following version schemes:
X.Y
X.Y.Z
X.Y-devel
X.Y-rcZ
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The square bracket is in the wrong place which makes the regex not match
version strings of the form: x.y.z. Fix the pattern in core and bindings
tests.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Two-digit versions are not correctly parsed as the last "segment" is not
optional as it should.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
One of the test cases doesn't release the request object leading to the
following warning in the kernel log:
REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED
Fix it.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Add a new optional argument to Chip.request_lines() called output_values.
It accepts a dictionary of mappings between line names or offsets to the
output values the requested lines should be set to at request-time.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
When we run the test suite by calling the __main__ function of the module,
the name of the process as visible in the system becomes "python". Let's
set it to "python-gpiod" before running the tests. This way gpiosim will
name its configfs attributes appropriately.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Python bindings now have their own setup.py script and can be built
separately from the rest of the code-base. Let's decouple the python
package version from libgpiod API (but let's keep a module attribute
containing the API version) by introducing a version.py submodule that
can be executed by the setup.py script. This way we have a single
canonical place defining the version number.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The enum itself should just define direction settings, it's the functions
that use it that should refer to hogging.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
The read_edge_event() family of functions should actually be called
read_edge_events() as they universally allow to read more than one
event. We're converting wait_edge_event() too for consistency.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
We currently require the third-party packaging module to be installed in
order to run tests. Let's instead use the version parser that's already
available in setuptools.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is the result of a squash of all the commits created during
the development of libgpiod v2. This is done to preserve bisectability
of the git tree. It contains significant re-writes of the core C library
as well as C++ and python bindings. The tools have been adjusted to work
with the new API but have not undergone significant changes yet.
This commit contains the bulk of the work on libgpiod v2 but the
development continues with more changes planned.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
[Ben: fix format specifier for uint64_t]
Signed-off-by: Ben Hutchings <ben.hutchings@mind.be>
[Viresh: Fix ioctl number for gpiod_line_request_reconfigure_lines()]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
[Kent: bug fixes, improvements, better pointer contracts, type strictness]
Signed-off-by: Kent Gibson <warthog618@gmail.com>
This removes any trace of line updating from the API (C, C++ and Python).
The line objects will soon disappear entirely so in order to make the
gradual transition to the new data model easier, remove
gpiod_line_update().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This removes another two functions from the C API as well as their
bindings that don't make much sense (since the user should know if
they have requested the line or not).
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Together with the removal of line objects, we'll entirely drop the
line bulk concept. In order to avoid having to update tests that will
soon be unneeded when introducing further changes, let's remove line
bulk test cases already.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
We're preparing to entirely remove the line objects from the API and
split their functionality between two new objects: line_info and
line_request. The lookup functions must be limited in the process.
This reworks all the find_line methods to: a) always assume that names
looked for are unique within a single chip (because while it's
technically possible for GPIO line names to be non-unique, it doesn't
make sense to look for two lines named the same) and b) return the
hardware offset within the chip instead of the line object.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>