gpio: Added port inquiry.
authorFredrik Tolf <fredrik@dolda2000.com>
Fri, 14 Sep 2018 21:46:00 +0000 (23:46 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Fri, 14 Sep 2018 21:46:00 +0000 (23:46 +0200)
gpio.c

diff --git a/gpio.c b/gpio.c
index 0179c18..4b82229 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -33,7 +33,7 @@ static void export(int p)
     int rp;
     
     if((rp = mappin(p)) < 0)
-       errx(1, "%i: no such port\n", p);
+       errx(1, "%i: no such port", p);
     sprintf(path, "/sys/class/gpio/gpio%i", rp);
     if(!access(path, R_OK | X_OK))
        return;
@@ -51,29 +51,42 @@ static void export(int p)
        errx(1, "gpio%i: still not available after export", rp);
 }
 
-static void setport(int p, int v)
+static void checkdir(int rp, char *dir)
 {
     char path[256], line[256];
     FILE *fp;
-    int rv, rp;
+    int rv;
+    size_t ln;
     
-    if((rp = mappin(p)) < 0)
-       errx(1, "%i: no such port\n", p);
     sprintf(path, "/sys/class/gpio/gpio%i/direction", rp);
     if((fp = fopen(path, "r")) == NULL)
        err(1, "%s", path);
     rv = !!fgets(line, sizeof(line), fp);
     fclose(fp);
-    if(!rv || strcmp(line, "out\n")) {
+    if(!rv || ((ln = strlen(line)) < 1) || (line[ln - 1] != '\n'))
+       errx(1, "gpio%i: could not read direction", rp);
+    line[ln - 1] = 0;
+    if(strcmp(line, dir)) {
        if(preserve)
-           errx(2, "gpio%i: not set to output", rp);
+           errx(2, "gpio%i: direction not set to %s", rp, dir);
        if((fp = fopen(path, "w")) == NULL)
            err(1, "%s", path);
-       fprintf(fp, "out\n"); fflush(fp);
+       fprintf(fp, "%s\n", dir); fflush(fp);
        if(ferror(fp))
-           errx(1, "gpio%i: could not set to output", rp);
+           errx(1, "gpio%i: could not set to direction to %s", rp, dir);
        fclose(fp);
     }
+}
+
+static void setport(int p, int v)
+{
+    char path[256];
+    FILE *fp;
+    int rp;
+    
+    if((rp = mappin(p)) < 0)
+       errx(1, "%i: no such port", p);
+    checkdir(rp, "out");
     sprintf(path, "/sys/class/gpio/gpio%i/value", rp);
     if((fp = fopen(path, "w")) == NULL)
        err(1, "%s", path);
@@ -83,6 +96,30 @@ static void setport(int p, int v)
     fclose(fp);
 }
 
+static int getport(int p)
+{
+    char path[256], line[256], *ep;
+    FILE *fp;
+    int rv, rp;
+    size_t ln;
+    
+    if((rp = mappin(p)) < 0)
+       errx(1, "%i: no such port", p);
+    checkdir(rp, "in");
+    sprintf(path, "/sys/class/gpio/gpio%i/value", rp);
+    if((fp = fopen(path, "r")) == NULL)
+       err(1, "%s", path);
+    rv = !!fgets(line, sizeof(line), fp);
+    fclose(fp);
+    if(!rv || ((ln = strlen(line)) < 1) || (line[ln - 1] != '\n'))
+       errx(1, "gpio%i: could not read direction", rp);
+    line[ln - 1] = 0;
+    rv = (int)strtol(line, &ep, 10);
+    if(*ep)
+       errx(1, "gpio%i: unexpected contents: %s", rp, line);
+    return(rv);
+}
+
 static void usage(FILE *out)
 {
     fprintf(out, "usage: gpio [-hip] PORT=VAL...\n");
@@ -91,7 +128,7 @@ static void usage(FILE *out)
 int main(int argc, char **argv)
 {
     int c, i, port, val;
-    char *p, *e;
+    char *e;
     
     while((c = getopt(argc, argv, "hip")) >= 0) {
        switch(c) {
@@ -115,28 +152,31 @@ int main(int argc, char **argv)
        return(1);
     }
     for(i = optind; i < argc; i++) {
-       if((p = strchr(argv[i], '=')) == NULL) {
-           fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]);
-           exit(1);
-       }
        port = strtol(argv[i], &e, 10);
-       if(e != p) {
-           fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]);
-           exit(1);
-       }
-       val = strtol(p + 1, &e, 10);
-       if(*e) {
-           fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]);
-           exit(1);
+       if((e > argv[i]) && (e[0] == '=') && (e[1] == '=')) {
+           val = strtol(e + 2, &e, 10);
+           if(*e)
+               errx(1, "gpio: %s: not of the form PORT==VAL", argv[i]);
+           export(port);
+           return(getport(port) != val);
+       } else if((e > argv[i]) && (e[0] == '=')) {
+           val = strtol(e + 1, &e, 10);
+           if(*e)
+               errx(1, "gpio: %s: not of the form PORT=VAL", argv[i]);
+           export(port);
+           setport(port, val);
+       } else if((e > argv[i]) && (e[0] == '?') && !e[1]) {
+           export(port);
+           printf("%i\n", getport(port));
+       } else {
+           errx(1, "gpio: %s: not a valid argument", argv[i]);
        }
-       export(port);
-       setport(port, val);
     }
     return(0);
 }
 
 /*
  * Local Variables:
- * compile-command: "gcc -Wall -g -O2 -march=native -o gpio gpio.c"
+ * compile-command: "gcc -Wall -g -O2 -march=native -c -o gpio.o gpio.c && gcc -o gpio gpio.o"
  * End:
  */