#include #include #include #include #include #include #include #include #include #include #define BACKLIGHT_DIR "/sys/class/backlight" void die(const char *msg) { puts(msg); exit(1); } void err(const char *msg) { perror(msg); exit(1); } void* ecalloc(size_t nmemb, size_t size) { void *ret = calloc(nmemb, size); if (!ret) err("ecalloc"); return ret; } char* appendStr(size_t len, const char *a, const char *b) { char *buf = ecalloc(len, sizeof(char)); int ret = snprintf(buf, len, "%s%s", a, b); if (ret == -1 || ret > len) err("snprintf"); return buf; } /* returns errno */ int maxBrightness(const char *prefix, long *max) { int e; char *buf = appendStr(256, prefix, "/max_brightness"); int fd = open(buf, O_RDONLY); if (fd == -1) { e = errno; free(buf); return e; } memset(buf, '\0', 256); int b = read(fd, buf, 256); if (b==-1) { e = errno; free(buf); close(fd); return e; } for (int i=0; i<256 ; i++) { if (buf[i] == '\n') { buf[i] = '\0'; break; } } long n = strtol(buf, NULL, 10); if (n == LONG_MIN || n == LONG_MAX || n == 0) err("strtol"); free(buf); buf = NULL; close(fd); *max = n; return 0; } int setBacklight(const char *prefix, int percent) { char *fn = appendStr(256, prefix, "/brightness"); int fd = open(fn, O_WRONLY); if (fd == -1) { free(fn); return -1; } int n = dprintf(fd, "%d\n", percent); if (n == -1) { close(fd); free(fn); return -1; } close(fd); free(fn); fn = NULL; } int main(int argc, char **argv) { uid_t euid = geteuid(); char **a = argv+1; if (euid != 0) die("Program must be run as root/setuid"); if (!*a) die("Brightness percentage must be supplied"); long percent = strtol(*a, NULL, 10); if (percent <= LONG_MIN || percent >= LONG_MAX) err("invalid percent"); if (percent < 0 || percent > 100) die("percent must be between 0 and 100"); DIR *d = opendir(BACKLIGHT_DIR); if (!d) err("opendir"); errno = 0; for (;;) { struct dirent *dent = readdir(d); if(!dent&&errno!=0) err("readdir"); if (!dent) break; if (strcmp("..", dent->d_name)==0 || strcmp(".", dent->d_name)==0) continue; char *prefix = appendStr(1024, BACKLIGHT_DIR"/", dent->d_name); printf("found backlight: %s\n", prefix); int ret; long max = 0; ret = maxBrightness(prefix, &max); if (ret != 0) { const char *msg = strerror(ret); printf("Error getting max brightness for: %s : %s\n", prefix, msg); continue; } float p = (double)max*((double)percent/100.0); ret = setBacklight(prefix, (int)p); if (ret != 0) { perror("setBacklight"); } free(prefix); prefix = NULL; } }