Skip to content

Commit

Permalink
Fix permissions error for /sys/class/gpio/export
Browse files Browse the repository at this point in the history
  • Loading branch information
aSmig authored and Gadgetoid committed Nov 2, 2023
1 parent 99d91a6 commit 70879d9
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions gpio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand All @@ -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()

Expand All @@ -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()

Expand Down Expand Up @@ -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()

Expand Down

0 comments on commit 70879d9

Please sign in to comment.