#include #include #include #include #include #include #include #include #define GPIO_IFACE_MISSING = -1 #define GPIO_PIN_EXP_FAIL = -2 #define GPIO_DIR_CONT_FAIL = -3 #define GPIO_SWITCH_FAIL = -4 #define GPIO_PIN_UNX_NF = -5 #define GPIO_PIN_UNX_FAIL = -6 #define GPIO_PREFIX "/sys/class/gpio/" #define GPIO_EXPORT "export" #define GPIO_UNEXPORT "unexport" #define MAX_PATHLEN 512 #define PRINTERRANDRET(mesg, varfmt, var) \ { \ fprintf(stderr, "%s \"%" varfmt "\". %s (%i)\n", mesg, var, strerror(errno), errno); \ return 1; \ } ssize_t exportPin(signed int pinno); ssize_t setPinDirection(signed int pinno, char* value); ssize_t setPinValue(signed int pinno, int value); int main(int argc, char* argv[]) { int pinno = (argc > 1) ? atoi(argv[1]) : 0; bool value = (argc > 2) ? atoi(argv[2]) : 0; if (pinno != exportPin(pinno)) return -1; if (pinno != setPinDirection(pinno, "out")) return -1; if (pinno != setPinValue(pinno, value)) return -1; return 0; } ssize_t exportPin(signed int pinno) { if (chdir(GPIO_PREFIX) != 0) PRINTERRANDRET("Failed to change directory to", "s", GPIO_PREFIX); char buffer[MAX_PATHLEN]; int fd; ssize_t nbytes; if ((fd = open(GPIO_EXPORT, O_WRONLY)) < 0) PRINTERRANDRET("Failed to open export", "s", GPIO_EXPORT); if ((nbytes = snprintf(buffer, MAX_PATHLEN, "%i", pinno)) <= 0) PRINTERRANDRET("Couldn't format pin number as string", "i", pinno); if (write(fd, buffer, nbytes) != nbytes && errno != EBUSY) PRINTERRANDRET("Couldn't write pin number to the exporter", "i", pinno); if (close(fd) != 0) PRINTERRANDRET("Couldn't close exporter", "i", pinno); return pinno; } ssize_t setPinDirection(signed int pinno, char* value) { if (chdir(GPIO_PREFIX) != 0) PRINTERRANDRET("Failed to change directory to", "s", GPIO_PREFIX); char buffer[MAX_PATHLEN]; int fd; ssize_t nbytes; if ((nbytes = snprintf(buffer, MAX_PATHLEN, "gpio%i/direction", pinno)) <= 0) PRINTERRANDRET("Couldn't format pin path as string", "i", pinno); if ((fd = open(buffer, O_WRONLY)) < 0) PRINTERRANDRET("Failed to open pin path.", "s", GPIO_EXPORT); if (write(fd, value, strlen(value)) != nbytes && errno != EBUSY) PRINTERRANDRET("Couldn't write pin direction", "i", pinno); if (close(fd) != 0) PRINTERRANDRET("Couldn't close pin direction file", "i", pinno); return pinno; } ssize_t setPinValue(signed int pinno, int value) { if (chdir(GPIO_PREFIX) != 0) PRINTERRANDRET("Failed to change directory to", "s", GPIO_PREFIX); char buffer[MAX_PATHLEN]; int fd; ssize_t nbytes; if ((nbytes = snprintf(buffer, MAX_PATHLEN, "gpio%i/value", pinno)) <= 0) PRINTERRANDRET("Couldn't format pin path as string", "i", pinno); if ((fd = open(buffer, O_WRONLY)) < 0) PRINTERRANDRET("Failed to open pin path.", "s", GPIO_EXPORT); if ((nbytes = snprintf(buffer, MAX_PATHLEN, "%i", value)) <= 0) PRINTERRANDRET("Couldn't format pin value as string", "i", value); if (write(fd, buffer, nbytes) != nbytes && errno != EBUSY) PRINTERRANDRET("Couldn't write pin value", "i", pinno); if (close(fd) != 0) PRINTERRANDRET("Couldn't close pin value file", "i", pinno); return pinno; }