From d6e5d180db865f27f6a76f0f134ef04ba045ae11 Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:09:28 -0500 Subject: [PATCH 1/7] Set `run_dir` to the correct path *beofre* it is used - Fixes #120 --- brightnessctl.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index 1917212..9b186fa 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -266,6 +266,9 @@ int process_device(struct device *dev) { } free(file_path); } + char *sys_run_dir = getenv("XDG_RUNTIME_DIR"); + if (sys_run_dir) + run_dir = dir_child(sys_run_dir, "brightnessctl"); if (p.save) if (!save_device_data(dev)) fprintf(stderr, "Could not save data for device '%s'.\n", dev->id); @@ -636,13 +639,6 @@ bool ensure_dir(char *dir) { } static bool ensure_run_dir() { - static bool set; - if (!set) { - char *sys_run_dir = getenv("XDG_RUNTIME_DIR"); - if (sys_run_dir) - run_dir = dir_child(sys_run_dir, "brightnessctl"); - set = true; - } return ensure_dir(run_dir); } From af938fbbc16a745e118c7252fe4ef7c4a4a00d23 Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:56:03 -0500 Subject: [PATCH 2/7] Removed `ensure_dev_dir` and `ensure_run_dir` functions --- brightnessctl.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index 9b186fa..9283088 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -61,7 +61,6 @@ static bool find_devices(struct device **, char *); static bool save_device_data(struct device *); static bool restore_device_data(struct device *); static bool ensure_dir(char *); -static bool ensure_dev_dir(struct device *); #ifdef ENABLE_LOGIND static bool logind_set_brightness(struct device *); @@ -562,7 +561,8 @@ int read_devices(struct device **devs) { bool save_device_data(struct device *dev) { char c[16]; size_t s = sprintf(c, "%u", dev->curr_brightness); - char *d_path = cat_with('/', run_dir, dev->class, dev->id); + char *c_path = dir_child(run_dir, dev->class); + char *d_path = dir_child(c_path, dev->id); FILE *fp; mode_t old = 0; int error = 0; @@ -572,7 +572,7 @@ bool save_device_data(struct device *dev) { error++; goto fail; } - if (!ensure_dev_dir(dev)) + if (!ensure_dir(c_path)) goto fail; old = umask(0); fp = fopen(d_path, "w"); @@ -585,6 +585,7 @@ bool save_device_data(struct device *dev) { } fclose(fp); fail: + free(c_path); free(d_path); if (errno) { perror("Error saving device data"); @@ -618,7 +619,6 @@ bool restore_device_data(struct device *dev) { return true; } - bool ensure_dir(char *dir) { struct stat sb; if (stat(dir, &sb)) { @@ -638,21 +638,6 @@ bool ensure_dir(char *dir) { return true; } -static bool ensure_run_dir() { - return ensure_dir(run_dir); -} - -bool ensure_dev_dir(struct device *dev) { - char *cpath; - bool ret; - if (!ensure_run_dir()) - return false; - cpath = dir_child(run_dir, dev->class); - ret = ensure_dir(cpath); - free(cpath); - return ret; -} - char *_cat_with(char c, ...) { size_t size = 32; size_t length = 0; From 09d9e49ca87d695bc11879d7297c9c3edc3eca8d Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:09:19 -0500 Subject: [PATCH 3/7] Replaced `ensure_dir` with `mkdir_parent` --- brightnessctl.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index 9283088..b9c0cdc 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -60,7 +60,7 @@ static unsigned long percent_to_val(float, struct device *); static bool find_devices(struct device **, char *); static bool save_device_data(struct device *); static bool restore_device_data(struct device *); -static bool ensure_dir(char *); +static bool mkdir_parent(const char *); #ifdef ENABLE_LOGIND static bool logind_set_brightness(struct device *); @@ -572,7 +572,7 @@ bool save_device_data(struct device *dev) { error++; goto fail; } - if (!ensure_dir(c_path)) + if (!mkdir_parent(c_path)) goto fail; old = umask(0); fp = fopen(d_path, "w"); @@ -619,23 +619,27 @@ bool restore_device_data(struct device *dev) { return true; } -bool ensure_dir(char *dir) { - struct stat sb; - if (stat(dir, &sb)) { - if (errno != ENOENT) - return false; - errno = 0; - if (mkdir(dir, 0777)) { - return false; - } - if (stat(dir, &sb)) - return false; - } - if (!S_ISDIR(sb.st_mode)) { - errno = ENOTDIR; +bool mkdir_parent(const char *path) { + if (!path) + return false; + bool ret = true; + size_t size = strlen(path) + 1; + char *tmp = calloc(1, size); + if (!tmp) return false; + for (const char *p = path; (p - path) < (long)size; p++) { + if ((*p == '/' || *p == '\0') && (p != path && *(p - 1) != '/')) { + memcpy(tmp, path, p - path); + tmp[p - path] = 0; + if (mkdir(tmp, 0777) && errno != EEXIST) { + ret = false; + perror(tmp); + break; + } + } } - return true; + free(tmp); + return ret; } char *_cat_with(char c, ...) { From 6fee015a1c5311c4501c7d56c637725054952cbc Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:26:26 -0500 Subject: [PATCH 4/7] Refactored `save_device_data` --- brightnessctl.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index b9c0cdc..6a13018 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -563,34 +563,30 @@ bool save_device_data(struct device *dev) { size_t s = sprintf(c, "%u", dev->curr_brightness); char *c_path = dir_child(run_dir, dev->class); char *d_path = dir_child(c_path, dev->id); - FILE *fp; - mode_t old = 0; int error = 0; - errno = 0; - if (s <= 0) { - fprintf(stderr, "Error converting device data."); - error++; - goto fail; - } - if (!mkdir_parent(c_path)) - goto fail; - old = umask(0); - fp = fopen(d_path, "w"); - umask(old); - if (!fp) - goto fail; - if (fwrite(c, 1, s, fp) < s) { - fprintf(stderr, "Error writing to '%s'.\n", d_path); + if (s > 0) { + if (mkdir_parent(c_path)) { + mode_t old = umask(0); + FILE *fp = fopen(d_path, "w"); + umask(old); + if (fp) { + fwrite(c, 1, s, fp); + if (ferror(fp)) { + error++; + fprintf(stderr, "Error writing to '%s'.\n", d_path); + } + fclose(fp); + } else { + error++; + fprintf(stderr, "Error opening '%s': %s\n", d_path, strerror(errno)); + } + } + } else { error++; + fprintf(stderr, "Error converting device data."); } - fclose(fp); -fail: free(c_path); free(d_path); - if (errno) { - perror("Error saving device data"); - error++; - } return !error; } From 3b7b63b5a6dc2b7541bc5a17781ad065f4c280a9 Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:53:55 -0500 Subject: [PATCH 5/7] Read and write binary files instead of text --- brightnessctl.c | 72 +++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index 6a13018..061eebe 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -559,60 +559,50 @@ int read_devices(struct device **devs) { } bool save_device_data(struct device *dev) { - char c[16]; - size_t s = sprintf(c, "%u", dev->curr_brightness); char *c_path = dir_child(run_dir, dev->class); char *d_path = dir_child(c_path, dev->id); - int error = 0; - if (s > 0) { - if (mkdir_parent(c_path)) { - mode_t old = umask(0); - FILE *fp = fopen(d_path, "w"); - umask(old); - if (fp) { - fwrite(c, 1, s, fp); - if (ferror(fp)) { - error++; - fprintf(stderr, "Error writing to '%s'.\n", d_path); - } - fclose(fp); - } else { - error++; - fprintf(stderr, "Error opening '%s': %s\n", d_path, strerror(errno)); + bool ret = true; + if (mkdir_parent(c_path)) { + mode_t old = umask(0); + FILE *fp = fopen(d_path, "wb"); + umask(old); + if (fp) { + fwrite(&dev->curr_brightness, sizeof(dev->curr_brightness), 1, fp); + if (ferror(fp)) { + ret = false; + fprintf(stderr, "Error writing to '%s'.\n", d_path); } + fclose(fp); + } else { + ret = false; + fprintf(stderr, "Error opening '%s': %s\n", d_path, strerror(errno)); } - } else { - error++; - fprintf(stderr, "Error converting device data."); } free(c_path); free(d_path); - return !error; + return ret; } bool restore_device_data(struct device *dev) { - char buf[16]; char *filename = cat_with('/', run_dir, dev->class, dev->id); - char *end; - FILE *fp; - memset(buf, 0, 16); - errno = 0; - if (!(fp = fopen(filename, "r"))) - goto fail; - if (!fread(buf, 1, 15, fp)) - goto rfail; - dev->curr_brightness = strtol(buf, &end, 10); - if (end == buf) - errno = EINVAL; -rfail: - fclose(fp); -fail: - free(filename); - if (errno) { + bool ret = true; + FILE *fp = fopen(filename, "rb"); + if (fp) { + unsigned int val; + fread(&val, sizeof(val), 1, fp); + if (!ferror(fp)) { + dev->curr_brightness = val; + } else { + ret = false; + fprintf(stderr, "Error reading file '%s'\n", filename); + } + fclose(fp); + } else { + ret = false; perror("Error restoring device data"); - return false; } - return true; + free(filename); + return ret; } bool mkdir_parent(const char *path) { From 412c991e6738fa09951ef10d2043c6ebd4bebb2d Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:50:33 -0500 Subject: [PATCH 6/7] Set umask for files in `XDG_RUNTIME_DIR` --- brightnessctl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index 061eebe..e3bbe2a 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -265,12 +265,16 @@ int process_device(struct device *dev) { } free(file_path); } + mode_t old = umask(0); char *sys_run_dir = getenv("XDG_RUNTIME_DIR"); - if (sys_run_dir) + if (sys_run_dir) { + umask(0077); run_dir = dir_child(sys_run_dir, "brightnessctl"); + } if (p.save) if (!save_device_data(dev)) fprintf(stderr, "Could not save data for device '%s'.\n", dev->id); + umask(old); if (p.restore) { if (restore_device_data(dev)) p.operation = RESTORE; @@ -563,9 +567,7 @@ bool save_device_data(struct device *dev) { char *d_path = dir_child(c_path, dev->id); bool ret = true; if (mkdir_parent(c_path)) { - mode_t old = umask(0); FILE *fp = fopen(d_path, "wb"); - umask(old); if (fp) { fwrite(&dev->curr_brightness, sizeof(dev->curr_brightness), 1, fp); if (ferror(fp)) { From 8eea9f51a03e38cfe87d4b203f1b01c03bd4e83d Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Tue, 26 Nov 2024 01:33:50 -0500 Subject: [PATCH 7/7] Check if the directory exists and the user has write permission --- brightnessctl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/brightnessctl.c b/brightnessctl.c index e3bbe2a..4493552 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -61,6 +61,7 @@ static bool find_devices(struct device **, char *); static bool save_device_data(struct device *); static bool restore_device_data(struct device *); static bool mkdir_parent(const char *); +static bool ensure_dir(const char *); #ifdef ENABLE_LOGIND static bool logind_set_brightness(struct device *); @@ -566,7 +567,7 @@ bool save_device_data(struct device *dev) { char *c_path = dir_child(run_dir, dev->class); char *d_path = dir_child(c_path, dev->id); bool ret = true; - if (mkdir_parent(c_path)) { + if (ensure_dir(c_path)) { FILE *fp = fopen(d_path, "wb"); if (fp) { fwrite(&dev->curr_brightness, sizeof(dev->curr_brightness), 1, fp); @@ -579,6 +580,8 @@ bool save_device_data(struct device *dev) { ret = false; fprintf(stderr, "Error opening '%s': %s\n", d_path, strerror(errno)); } + } else { + fprintf(stderr, "Failed to access or create '%s': %s\n", path, strerror(errno)); } free(c_path); free(d_path); @@ -630,6 +633,12 @@ bool mkdir_parent(const char *path) { return ret; } +static bool ensure_dir(const char * path) { + if (!access(path, W_OK)) + return true; + return errno == ENOENT ? mkdir_parent(path) : false; +} + char *_cat_with(char c, ...) { size_t size = 32; size_t length = 0;