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;
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);
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");
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) {
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:
*/