I'm trying to use raspberry pi GPIOs through sysfs using the C language, but I keep getting fopen: Permission denied when trying to change the GPIO line direction.
The issue occurs when trying to open the file "/sys/class/gpio/gpio18/direction".
Notes:
- If I run the program for a second time it works fine.
- If I export the GPIO line manually and then execute it works fine.
- If I run the program as root it works fine.
- My current user is part of the gpio group and should have all permissions.
Normally I would need to put the pin that I want to use in "/sys/class/gpio/export".
And then I need to set its direction (output/input) by writing 1 or 0 to "/sys/class/gpio/gpio18/direction".
To achieve that programmatically I use the following code
#include "io.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char const* argv[]) {
// export line
FILE* p_gpio_line;
if ((p_gpio_line = fopen("/sys/class/gpio/export", "w")) == NULL) {
printf("Cannot open export file.\n");
perror("fopen");
exit(1);
}
rewind(p_gpio_line);
fwrite("18", sizeof(char), 2, p_gpio_line);
fclose(p_gpio_line);
// set direction
FILE* p_gpio_direction;
if ((p_gpio_direction = fopen("/sys/class/gpio/gpio18/direction", "r+")) == NULL) {
printf("Cannot open direction file.\n");
perror("fopen");
exit(1);
}
return 0;
}
The first time it executes I get
Cannot open direction file.
fopen: Permission denied
The second time it works fine because the GPIO line is exported before the program is executed (from the first execution)
It also works fine if I manually export the GPIO line from the terminal

My comment about
perror()remains in effect, but indeed in your examplefopen()returns EACCES ("Permission denied").Group
gpioand permissions for/sys/class/gpioare specific for Raspberry Pi distro. They are set by udev rule in/etc/udev/rules.d/99-com.rules:Udev rule is applied asynchronously after
directionfile appears. You are trying to open the file while permissions aren't yet set.I'd suggest to use character device GPIO interface with libgpiod instead of deprecated sysfs interface.
If you still want to use sysfs interface, straightforward solution is to retry
fopen()until it succeed (or fail with error other than EACCES, or timeout). For example: