From f65451be6b6ce06de4dfc9ae99a14b89163669a5 Mon Sep 17 00:00:00 2001 From: Kenny Date: Thu, 2 Nov 2023 13:29:57 +0000 Subject: [PATCH] Fix permissions error for /sys/class/gpio/export --- gpio/__init__.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gpio/__init__.py b/gpio/__init__.py index 6382f72..7e5067f 100644 --- a/gpio/__init__.py +++ b/gpio/__init__.py @@ -17,7 +17,9 @@ GPIO_ROOT = "/sys/class/gpio" GPIO_EXPORT = os.path.join(GPIO_ROOT, "export") GPIO_UNEXPORT = os.path.join(GPIO_ROOT, "unexport") -FMODE = "w+" # w+ overwrites and truncates existing files +FMODE_SYS_WO = "w" # /sys/class/gpio/export is not readable, even by root +FMODE_SYS_RW = "w+" # w+ overwrites and truncates existing files +FMODE_BIN_RW = "wb+" # Using unbuffered binary IO is ~ 3x faster than text IN, OUT = "in", "out" LOW, HIGH = 0, 1 @@ -48,12 +50,12 @@ def __init__(self, pin, direction=None, initial=LOW, active_low=None): if not os.path.exists(self.root): with _export_lock: - with open(GPIO_EXPORT, FMODE) as f: + with open(GPIO_EXPORT, FMODE_SYS_WO) as f: f.write(str(self.pin)) f.flush() # Using unbuffered binary IO is ~ 3x faster than text - self.value = open(os.path.join(self.root, "value"), "wb+", buffering=0) + self.value = open(os.path.join(self.root, "value"), FMODE_BIN_RW, buffering=0) # I hate manually calling .setup()! self.setup(direction, initial, active_low) @@ -102,7 +104,7 @@ def get_direction(self): Returns: str: "in" or "out" """ - with open(os.path.join(self.root, "direction"), FMODE) as f: + with open(os.path.join(self.root, "direction"), FMODE_SYS_RW) as f: return f.read().strip() def set_direction(self, mode): @@ -114,7 +116,7 @@ def set_direction(self, mode): if mode not in (IN, OUT, LOW, HIGH): raise ValueError("Unsupported pin mode {}".format(mode)) - with open(os.path.join(self.root, "direction"), FMODE) as f: + with open(os.path.join(self.root, "direction"), FMODE_SYS_RW) as f: f.write(str(mode)) f.flush() @@ -127,7 +129,7 @@ def set_active_low(self, active_low): if not isinstance(active_low, bool): raise ValueError("active_low must be True or False") - with open(os.path.join(self.root, "active_low"), FMODE) as f: + with open(os.path.join(self.root, "active_low"), FMODE_SYS_RW) as f: f.write("1" if active_low else "0") f.flush() @@ -170,7 +172,7 @@ def cleanup(self): if os.path.exists(self.root): with _export_lock: - with open(GPIO_UNEXPORT, FMODE) as f: + with open(GPIO_UNEXPORT, FMODE_SYS_WO) as f: f.write(str(self.pin)) f.flush()