diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..f653445 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,36 @@ +Checks: > + clang-analyzer-*, + bugprone-*, + cert-*, + modernize-*, + performance-*, + portability-*, + readability-*, + -readability-braces-around-statements, + +WarningsAsErrors: '' +HeaderFilterRegex: '.*' +FormatStyle: file + +CheckOptions: + - key: readability-magic-numbers.IgnoredIntegerValues + value: '0;1;2;3;10;255' + # - key: readability-magic-numbers.IgnoredValues + # value: '0;1;2;3;10;255' + - key: readability-identifier-naming.VariableCase + value: lower_case + - key: readability-identifier-naming.ConstantParameterCase + value: UPPER_CASE + + - key: readability-identifier-length.VariableThreshold + value: '2' + - key: readability-identifier-length.ParameterThreshold + value: '2' + - key: readability-identifier-length.LocalConstantThreshold + value: '2' + - key: readability-identifier-length.MemberThreshold + value: '2' + - key: readability-identifier-length.MinimumParameterNameLength + value: '2' + - key: readability-identifier-length.MinimumVariableNameLength + value: '2' diff --git a/include/auth.h b/include/auth.h index c3ef186..0d15557 100644 --- a/include/auth.h +++ b/include/auth.h @@ -1,5 +1,5 @@ -#ifndef _AUTHH_ -#define _AUTHH_ +#ifndef AUTHH_ +#define AUTHH_ #include diff --git a/include/chvt.h b/include/chvt.h index a39af33..8883ada 100644 --- a/include/chvt.h +++ b/include/chvt.h @@ -1,5 +1,5 @@ -#ifndef _CHVTH_ -#define _CHVTH_ +#ifndef CHVTH_ +#define CHVTH_ #include #include diff --git a/include/config.h b/include/config.h index 5ad3fd0..1b49cf6 100644 --- a/include/config.h +++ b/include/config.h @@ -1,5 +1,5 @@ -#ifndef _CONFIGH_ -#define _CONFIGH_ +#ifndef CONFIGH_ +#define CONFIGH_ #include #include @@ -73,11 +73,6 @@ struct config { struct behavior behavior; }; -bool line_parser( - FILE* fd, - ssize_t* blksize, - u_char (*cb)(char* key, - char* value)); // might use this for parsing .desktop files too struct config* parse_config(char* path); #endif diff --git a/include/efield.h b/include/efield.h index ed03c32..8295275 100644 --- a/include/efield.h +++ b/include/efield.h @@ -1,5 +1,5 @@ -#ifndef _EFIELDH_ -#define _EFIELDH_ +#ifndef EFIELDH_ +#define EFIELDH_ #include #include @@ -10,9 +10,9 @@ struct editable_field { char content[255]; }; -struct editable_field field_new(char*); -void field_trim(struct editable_field*, u_char); -void field_update(struct editable_field*, char*); -bool field_seek(struct editable_field*, char); +struct editable_field field_new(char* content); +void field_trim(struct editable_field* self, u_char pos); +void field_update(struct editable_field* self, char* update); +bool field_seek(struct editable_field* self, char seek); #endif diff --git a/include/keys.h b/include/keys.h index 51aaacc..57d6b0f 100644 --- a/include/keys.h +++ b/include/keys.h @@ -1,5 +1,5 @@ -#ifndef _KEYSH_ -#define _KEYSH_ +#ifndef KEYSH_ +#define KEYSH_ #include diff --git a/include/sessions.h b/include/sessions.h index 108c0bc..f0cc1bf 100644 --- a/include/sessions.h +++ b/include/sessions.h @@ -1,5 +1,5 @@ -#ifndef _SESSIONSH_ -#define _SESSIONSH_ +#ifndef SESSIONSH_ +#define SESSIONSH_ #include diff --git a/include/ui.h b/include/ui.h index a7f7bec..bbdb1cc 100644 --- a/include/ui.h +++ b/include/ui.h @@ -1,5 +1,5 @@ -#ifndef _UIH_ -#define _UIH_ +#ifndef UIH_ +#define UIH_ #include "config.h" #include "util.h" diff --git a/include/users.h b/include/users.h index 0a2eda0..7e818fb 100644 --- a/include/users.h +++ b/include/users.h @@ -1,5 +1,5 @@ -#ifndef _USERSH_ -#define _USERSH_ +#ifndef USERSH_ +#define USERSH_ #include diff --git a/include/util.h b/include/util.h index 5965a31..5daf13b 100644 --- a/include/util.h +++ b/include/util.h @@ -1,5 +1,5 @@ -#ifndef _UTILH_ -#define _UTILH_ +#ifndef UTILH_ +#define UTILH_ #include #include diff --git a/src/auth.c b/src/auth.c index 01bdaa2..ba29bf2 100644 --- a/src/auth.c +++ b/src/auth.c @@ -45,6 +45,7 @@ void clear_screen() { printf("\x1b[H\x1b[J"); } +// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) pam_handle_t* get_pamh(char* user, char* passwd) { pam_handle_t* pamh = NULL; struct pam_conv pamc = {pam_conversation, (void*)passwd}; @@ -91,7 +92,7 @@ void sourceFileTry(char* file) { } if (line) free(line); - fclose(file2source); + (void)fclose(file2source); } void moarEnv(char* user, @@ -109,7 +110,7 @@ void moarEnv(char* user, // PATH? - char* xdg_session_type; + char* xdg_session_type = "unknown"; if (session.type == SHELL) xdg_session_type = "tty"; if (session.type == XORG) xdg_session_type = "x11"; if (session.type == WAYLAND) xdg_session_type = "wayland"; @@ -126,12 +127,12 @@ void moarEnv(char* user, uint home_len = strlen(pw->pw_dir); for (size_t i = 0; i < behavior->user_source.length; i++) { char* file2sourcepath = (char*)vec_get(&behavior->user_source, i); - char* newbuf = - malloc(home_len + strlen(file2sourcepath) + 2); // nullbyte and slash - if (newbuf == NULL) continue; // can't bother - strcpy(newbuf, pw->pw_dir); + size_t newbuf_len = home_len + strlen(file2sourcepath) + 2; + char* newbuf = malloc(newbuf_len); // nullbyte and slash + if (newbuf == NULL) continue; // can't bother + strlcpy(newbuf, pw->pw_dir, newbuf_len); newbuf[home_len] = '/'; // assume pw_dir doesn't start with '/' :P - strcpy(&newbuf[home_len + 1], file2sourcepath); + strlcpy(&newbuf[home_len + 1], file2sourcepath, newbuf_len - home_len - 1); /* printf("DEBUG(user_source)!!!! %d %s\n", i, newbuf); */ sourceFileTry(newbuf); @@ -150,6 +151,7 @@ void moarEnv(char* user, /*setenv("XDG_SEAT", "seat0", true);*/ } +// NOLINTBEGIN(readability-function-cognitive-complexity) bool launch(char* user, char* passwd, struct session session, @@ -176,9 +178,9 @@ bool launch(char* user, uint pid = fork(); if (pid == 0) { // child - char* TERM = NULL; - char* _GETTERM = getenv("TERM"); - if (_GETTERM != NULL) strcln(&TERM, _GETTERM); + char* term = NULL; + char* getterm = getenv("TERM"); + if (getterm != NULL) strcln(&term, getterm); if (clearenv() != 0) { print_errno("clearenv"); _exit(EXIT_FAILURE); @@ -194,12 +196,12 @@ bool launch(char* user, } // FIXME: path hotfix putenv("PATH=/bin:/usr/bin"); - if (TERM != NULL) { - setenv("TERM", TERM, true); - free(TERM); + if (term != NULL) { + setenv("TERM", term, true); + free(term); } - free(envlist); + free((void*)envlist); moarEnv(user, session, pw, behavior); // TODO: chown stdin to user @@ -228,29 +230,31 @@ bool launch(char* user, // TODO: these will be different due to TryExec // and, Exec/TryExec might contain spaces as args printf("\x1b[0m"); + // NOLINTNEXTLINE(bugprone-branch-clone) if (session.type == SHELL) { clear_screen(); - fflush(stdout); + (void)fflush(stdout); execlp(session.exec, session.exec, NULL); } else if (session.type == XORG || session.type == WAYLAND) { clear_screen(); - fflush(stdout); + (void)fflush(stdout); execlp(session.exec, session.exec, NULL); } perror("execl error"); - fprintf(stderr, "failure calling session\n"); + (void)fputs("failure calling session\n", stderr); } else { - waitpid(pid, NULL, 0); + __pid_t child_pid = (__pid_t)pid; + waitpid(child_pid, NULL, 0); pam_setcred(pamh, PAM_DELETE_CRED); pam_close_session(pamh, 0); pam_end(pamh, PAM_SUCCESS); - if (*reach_session == false) { + if (*reach_session == false) return false; - } else - exit(0); + exit(0); } return true; } +// NOLINTEND(readability-function-cognitive-complexity) diff --git a/src/chvt.c b/src/chvt.c index a0c11bb..5d61460 100644 --- a/src/chvt.c +++ b/src/chvt.c @@ -11,6 +11,7 @@ static char* vterms[] = {"/dev/tty", "/dev/tty0", "/dev/vc/0", "/dev/systty", int chvt_str(char* str) { char* err; errno = 0; + // NOLINTNEXTLINE(readability-identifier-length) long i = strtol(str, &err, 10); if (errno) { perror("strol"); @@ -23,13 +24,16 @@ int chvt_str(char* str) { } int chvt(int n) { - fprintf(stderr, "activating vt %d\n", n); + // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + (void)fprintf(stderr, "activating vt %d\n", n); + // NOLINTNEXTLINE(readability-identifier-length) char c = 0; for (size_t i = 0; i < sizeof(vterms) / sizeof(vterms[0]); i++) { int fd = open(vterms[i], O_RDWR); if (fd >= 0 && isatty(fd) && ioctl(fd, KDGKBTYPE, &c) == 0 && c < 3) { if (ioctl(fd, VT_ACTIVATE, n) < 0 || ioctl(fd, VT_WAITACTIVE, n) < 0) { - fprintf(stderr, "Couldn't activate vt %d\n", n); + // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + (void)fprintf(stderr, "Couldn't activate vt %d\n", n); return -1; } return 0; @@ -37,6 +41,6 @@ int chvt(int n) { close(fd); } - fprintf(stderr, "Couldn't get a file descriptor referring to the console.\n"); + (void)fputs("Couldn't get a file descriptor referring to the console.\n", stderr); return -1; } diff --git a/src/config.c b/src/config.c index d4857b3..0f93a37 100644 --- a/src/config.c +++ b/src/config.c @@ -1,3 +1,6 @@ +#include +#include +#include #include #include @@ -13,154 +16,164 @@ // // This would return true if everything goes fine, false otherwise (malloc // error, broke parsing, etc) -bool line_parser(FILE* fd, - ssize_t* blksize, - u_char (*cb)(char* key, char* value)) { - size_t opt_size = 4096; - if (blksize != NULL) opt_size = *blksize; +// NOLINTBEGIN(modernize-macro-to-enum) +#define LN_BREAK_OK 0b0001 +#define LN_FREE_VALUE 0b0010 +#define LN_FREE_KEY 0b0100 +#define LN_FREE_KV (LN_FREE_KEY | LN_FREE_VALUE) +#define LN_BREAK_ERR 0b1000 +// NOLINTEND(modernize-macro-to-enum) +bool line_parser(FILE* fd, u_char (*cb)(char* key, char* value)) { + bool ok = false; - while (true) { - size_t alloc_size = opt_size; - char* buf = malloc(alloc_size); - if (buf == NULL) return false; - ssize_t read_size = getline(&buf, &alloc_size, fd); - if (read_size == -1) { - free(buf); - break; - } - - uint read; + char* buf = NULL; + size_t alloc_size = 0; + size_t read_size; + while ((read_size = getline(&buf, &alloc_size, fd)) != -1) { + ok = true; char* key = malloc(read_size); if (key == NULL) { - free(buf); - return false; + ok = false; + break; } char* value = malloc(read_size); if (value == NULL) { - free(buf); - return false; + free(key); + ok = false; + break; } - if ((read = sscanf(buf, "%[^ ] = %[^\n]\n", key, value)) != 0) { + // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + if (sscanf(buf, "%[^ ] = %[^\n]\n", key, value) == 2) { u_char ret = cb(key, value); - if (ret & 0b0100) free(key); - if (ret & 0b0010) free(value); - if (ret & 0b1000) { - free(buf); - return false; - } - if (ret & 0b0001) { - free(buf); + if (ret & LN_FREE_KEY) free(key); + if (ret & LN_FREE_VALUE) free(value); + if (ret & LN_BREAK_ERR) { + ok = false; break; } + if (ret & LN_BREAK_OK) { + break; + } + } else { + free(key); + free(value); } - free(buf); } - return true; + if (buf != NULL) free(buf); + return ok; } -struct config* __config; +struct config* g_config; // Yanderedev code (wanna fix this with a table or smth) +// NOLINTNEXTLINE(readability-identifier-length,readability-function-cognitive-complexity) u_char config_line_handler(char* k, char* v) { + // NOLINTNEXTLINE(readability-function-cognitive-complexity) if (strcmp(k, "colors.bg") == 0) - __config->theme.colors.bg = v; + g_config->theme.colors.bg = v; else if (strcmp(k, "colors.fg") == 0) - __config->theme.colors.fg = v; + g_config->theme.colors.fg = v; else if (strcmp(k, "colors.err") == 0) - __config->theme.colors.err = v; + g_config->theme.colors.err = v; else if (strcmp(k, "colors.s_wayland") == 0) - __config->theme.colors.s_wayland = v; + g_config->theme.colors.s_wayland = v; else if (strcmp(k, "colors.s_xorg") == 0) - __config->theme.colors.s_xorg = v; + g_config->theme.colors.s_xorg = v; else if (strcmp(k, "colors.s_shell") == 0) - __config->theme.colors.s_shell = v; + g_config->theme.colors.s_shell = v; else if (strcmp(k, "colors.e_hostname") == 0) - __config->theme.colors.e_hostname = v; + g_config->theme.colors.e_hostname = v; else if (strcmp(k, "colors.e_date") == 0) - __config->theme.colors.e_date = v; + g_config->theme.colors.e_date = v; else if (strcmp(k, "colors.e_box") == 0) - __config->theme.colors.e_box = v; + g_config->theme.colors.e_box = v; else if (strcmp(k, "colors.e_header") == 0) - __config->theme.colors.e_header = v; + g_config->theme.colors.e_header = v; else if (strcmp(k, "colors.e_user") == 0) - __config->theme.colors.e_user = v; + g_config->theme.colors.e_user = v; else if (strcmp(k, "colors.e_passwd") == 0) - __config->theme.colors.e_passwd = v; + g_config->theme.colors.e_passwd = v; else if (strcmp(k, "colors.e_badpasswd") == 0) - __config->theme.colors.e_badpasswd = v; + g_config->theme.colors.e_badpasswd = v; else if (strcmp(k, "colors.e_key") == 0) - __config->theme.colors.e_key = v; + g_config->theme.colors.e_key = v; else if (strcmp(k, "chars.hb") == 0) - __config->theme.chars.hb = v; + g_config->theme.chars.hb = v; else if (strcmp(k, "chars.vb") == 0) - __config->theme.chars.vb = v; + g_config->theme.chars.vb = v; else if (strcmp(k, "chars.ctl") == 0) - __config->theme.chars.ctl = v; + g_config->theme.chars.ctl = v; else if (strcmp(k, "chars.ctr") == 0) - __config->theme.chars.ctr = v; + g_config->theme.chars.ctr = v; else if (strcmp(k, "chars.cbl") == 0) - __config->theme.chars.cbl = v; + g_config->theme.chars.cbl = v; else if (strcmp(k, "chars.cbr") == 0) - __config->theme.chars.cbr = v; + g_config->theme.chars.cbr = v; else if (strcmp(k, "functions.poweroff") == 0) { - __config->functions.poweroff = find_keyname(v); - return 0b0110; + g_config->functions.poweroff = find_keyname(v); + return LN_FREE_KV; } else if (strcmp(k, "functions.reboot") == 0) { - __config->functions.reboot = find_keyname(v); - return 0b0110; + g_config->functions.reboot = find_keyname(v); + return LN_FREE_KV; } else if (strcmp(k, "functions.refresh") == 0) { - __config->functions.refresh = find_keyname(v); - return 0b0110; + g_config->functions.refresh = find_keyname(v); + return LN_FREE_KV; } else if (strcmp(k, "strings.f_poweroff") == 0) - __config->strings.f_poweroff = v; + g_config->strings.f_poweroff = v; else if (strcmp(k, "strings.f_reboot") == 0) - __config->strings.f_reboot = v; + g_config->strings.f_reboot = v; else if (strcmp(k, "strings.f_refresh") == 0) - __config->strings.f_refresh = v; + g_config->strings.f_refresh = v; else if (strcmp(k, "strings.e_user") == 0) - __config->strings.e_user = v; + g_config->strings.e_user = v; else if (strcmp(k, "strings.e_passwd") == 0) - __config->strings.e_passwd = v; + g_config->strings.e_passwd = v; else if (strcmp(k, "strings.s_wayland") == 0) - __config->strings.s_wayland = v; + g_config->strings.s_wayland = v; else if (strcmp(k, "strings.s_xorg") == 0) - __config->strings.s_xorg = v; + g_config->strings.s_xorg = v; else if (strcmp(k, "strings.s_shell") == 0) - __config->strings.s_shell = v; + g_config->strings.s_shell = v; else if (strcmp(k, "behavior.include_defshell") == 0) { - __config->behavior.include_defshell = strcmp(v, "true") == 0; - return 0b0110; + g_config->behavior.include_defshell = strcmp(v, "true") == 0; + return LN_FREE_KV; } else if (strcmp(k, "behavior.source") == 0) - vec_push(&__config->behavior.source, v); + vec_push(&g_config->behavior.source, v); else if (strcmp(k, "behavior.user_source") == 0) - vec_push(&__config->behavior.user_source, v); + vec_push(&g_config->behavior.user_source, v); else - return 0b1111; + return LN_BREAK_ERR | LN_FREE_KV; - return 0b0100; + return LN_FREE_KEY; } struct config* parse_config(char* path) { - struct stat sb; + // struct stat sb; + errno = 0; FILE* fd = fopen(path, "r"); - if (fd == NULL || (stat(path, &sb) == -1)) { + if (fd == NULL) { perror("fopen"); - fprintf(stderr, - "Please place a config file at /etc/lidm.ini or set the LIDM_CONF " - "env variable"); + (void)fputs( + "Please place a config file at /etc/lidm.ini or set the LIDM_CONF " + "env variable", + stderr); return NULL; } + // if(stat(path, &sb) != 0) { + // perror("stat"); + // } - __config = malloc(sizeof(struct config)); - __config->behavior.source = vec_new(); - __config->behavior.user_source = vec_new(); + g_config = malloc(sizeof(struct config)); + g_config->behavior.source = vec_new(); + g_config->behavior.user_source = vec_new(); - if (__config == NULL) return NULL; - bool ret = line_parser(fd, (ssize_t*)&sb.st_blksize, config_line_handler); + if (g_config == NULL) return NULL; + bool ret = line_parser(fd, config_line_handler); + (void)fclose(fd); if (!ret) { - free(__config); + free(g_config); return NULL; } - return __config; + return g_config; } diff --git a/src/efield.c b/src/efield.c index d04eaac..fb6ef9f 100644 --- a/src/efield.c +++ b/src/efield.c @@ -3,71 +3,77 @@ #include "efield.h" #include "ui.h" +// NOLINTBEGIN(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + struct editable_field field_new(char* content) { - struct editable_field __efield; + struct editable_field efield; if (content != NULL) { - __efield.length = __efield.pos = strlen(content); - memcpy(__efield.content, content, __efield.length); + efield.length = efield.pos = strlen(content); + memcpy(efield.content, content, efield.length); } else { - field_trim(&__efield, 0); + field_trim(&efield, 0); } - __efield.content[__efield.length] = '\0'; - return __efield; + efield.content[efield.length] = '\0'; + return efield; } -void field_trim(struct editable_field* field, u_char pos) { - field->length = field->pos = pos; - field->content[field->length] = '\0'; +void field_trim(struct editable_field* self, u_char pos) { + self->length = self->pos = pos; + self->content[self->length] = '\0'; } -void field_update(struct editable_field* field, char* update) { +// NOLINTNEXTLINE(modernize-macro-to-enum) +#define BACKSPACE_CODE 127 +void field_update(struct editable_field* self, char* update) { u_char insert_len = strlen(update); if (insert_len == 0) return; - if (field->pos > field->length) field->pos = field->length; // WTF + if (self->pos > self->length) self->pos = self->length; // WTF if (insert_len == 1) { // backspace - if (*update == 127) { - if (field->pos == 0) return; - if (field->pos < field->length) { - memmove(&field->content[field->pos - 1], &field->content[field->pos], - field->length - field->pos); + if (*update == BACKSPACE_CODE) { + if (self->pos == 0) return; + if (self->pos < self->length) { + memmove(&self->content[self->pos - 1], &self->content[self->pos], + self->length - self->pos); } - (field->pos)--; - (field->length)--; - field->content[field->length] = '\0'; + (self->pos)--; + (self->length)--; + self->content[self->length] = '\0'; return; } } // append - if (field->length + field->pos >= 255) { + if (self->length + self->pos >= 255) { print_err("field too long"); } - if (field->pos < field->length) { + if (self->pos < self->length) { // move with immediate buffer - memmove(&field->content[field->pos + insert_len], - &field->content[field->pos], field->length - field->pos); + memmove(&self->content[self->pos + insert_len], + &self->content[self->pos], self->length - self->pos); } - memcpy(&field->content[field->pos], update, insert_len); + memcpy(&self->content[self->pos], update, insert_len); - field->pos += insert_len; - field->length += insert_len; - field->content[field->length] = '\0'; + self->pos += insert_len; + self->length += insert_len; + self->content[self->length] = '\0'; } // returns bool depending if it was able to "use" the seek -bool field_seek(struct editable_field* field, char seek) { - if (field->length == 0) return false; +bool field_seek(struct editable_field* self, char seek) { + if (self->length == 0) return false; - if (seek < 0 && -seek > field->pos) - field->pos = 0; - else if (seek > 0 && 255 - field->pos < seek) - field->pos = 255; + if (seek < 0 && -seek > self->pos) + self->pos = 0; + else if (seek > 0 && 255 - self->pos < seek) + self->pos = 255; else - field->pos += seek; + self->pos += seek; - if (field->pos > field->length) field->pos = field->length; + if (self->pos > self->length) self->pos = self->length; return true; } + +// NOLINTEND(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) diff --git a/src/main.c b/src/main.c index 2096782..f1a87b1 100644 --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,8 @@ int main(int argc, char* argv[]) { struct config* config = parse_config(conf_override == NULL ? "/etc/lidm.ini" : conf_override); if (config == NULL) { - fprintf(stderr, "error parsing config\n"); + // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + (void)fputs("error parsing config\n", stderr); return 1; } setup(*config); diff --git a/src/sessions.c b/src/sessions.c index f4e6a12..ab3aa51 100644 --- a/src/sessions.c +++ b/src/sessions.c @@ -19,37 +19,42 @@ static const struct source_dir sources[] = { {WAYLAND, "/usr/share/wayland-sessions"}, }; -static struct session __new_session(enum session_type type, +static struct session new_session(enum session_type type, char* name, const char* exec, const char* tryexec) { - struct session __session; - __session.type = type; - strcln(&__session.name, name); - strcln(&__session.exec, exec); - strcln(&__session.tryexec, tryexec); + struct session session; + session.type = type; + strcln(&session.name, name); + strcln(&session.exec, exec); + strcln(&session.tryexec, tryexec); - return __session; + return session; } static struct Vector* cb_sessions = NULL; // NOTE: commented printf's here would be nice to have debug logs if I ever // implement it +#define LN_NAME 0b0001 +#define LN_EXEC 0b0010 +#define LN_TEXEC 0b0100 +#define LN_ALL (LN_NAME | LN_EXEC | LN_TEXEC) static enum session_type session_type; +// NOLINTNEXTLINE(readability-function-cognitive-complexity) static int fn(const char* fpath, const struct stat* sb, int typeflag) { - if (sb == NULL || !S_ISREG(sb->st_mode)) return 0; + if (!S_ISREG(sb->st_mode)) return 0; - /*printf("gonna open %s\n", fpath);*/ + // printf("gonna open %s\n", fpath); FILE* fd = fopen(fpath, "r"); if (fd == NULL) { perror("fopen"); - fprintf(stderr, "error opening file (r) '%s'\n", fpath); + // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + (void)fprintf(stderr, "error opening file (r) '%s'\n", fpath); return 0; } u_char found = 0; - size_t alloc_size = sb->st_blksize; char* name_buf = NULL; char* exec_buf = NULL; @@ -57,38 +62,35 @@ static int fn(const char* fpath, const struct stat* sb, int typeflag) { // This should be made a specific function // Emm, if anything goes wrong just free the inner loop and `break;` fd and // the rest is handled after - while (true) { - char* buf = malloc(sb->st_blksize); - ssize_t read_size = getline(&buf, &alloc_size, fd); - if (read_size == -1) { - free(buf); - break; - } - - uint read; + char* buf = NULL; + size_t alloc_size = 0; + size_t read_size; + while ((read_size = getline(&buf, &alloc_size, fd)) != -1) { char* key = malloc(read_size + sizeof(char)); if (key == NULL) { free(buf); - // TODO: more sophisticated error handling?? break; } char* value = malloc(read_size + sizeof(char)); if (value == NULL) { free(buf); free(key); - // TODO: more sophisticated error handling?? break; } value[0] = '\0'; // I'm not sure if sscanf would null this string out - if ((read = sscanf(buf, "%[^=]=%[^\n]\n", key, value)) != 0) { + // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + if (sscanf(buf, "%[^=]=%[^\n]\n", key, value) == 2) { if (strcmp(key, "Name") == 0) { - found &= 0b001; + found &= LN_EXEC; + if(name_buf != NULL) free(name_buf); name_buf = realloc(value, strlen(value) + sizeof(char)); } else if (strcmp(key, "Exec") == 0) { - found &= 0b010; + found &= LN_EXEC; + if(exec_buf != NULL) free(exec_buf); exec_buf = realloc(value, strlen(value) + sizeof(char)); } else if (strcmp(key, "TryExec") == 0) { - found &= 0b100; + found &= LN_TEXEC; + if(tryexec_buf != NULL) free(tryexec_buf); tryexec_buf = realloc(value, strlen(value) + sizeof(char)); } else { free(value); @@ -97,19 +99,17 @@ static int fn(const char* fpath, const struct stat* sb, int typeflag) { free(value); } free(key); - free(buf); - if (found == 0b111) break; + // if (found == LN_ALL) break; } - /*printf("\nend parsing...\n");*/ - // Generic handling of exit - - fclose(fd); + if(buf != NULL) free(buf); + (void)fclose(fd); + // printf("\nend parsing...\n"); // just add this to the list if (name_buf != NULL && exec_buf != NULL) { struct session* session_i = malloc(sizeof(struct session)); - *session_i = __new_session(session_type, name_buf, exec_buf, + *session_i = new_session(session_type, name_buf, exec_buf, tryexec_buf == NULL ? "" : tryexec_buf); vec_push(cb_sessions, session_i); } @@ -122,9 +122,10 @@ static int fn(const char* fpath, const struct stat* sb, int typeflag) { } // This code is designed to be run purely single threaded +#define LIKELY_BOUND_SESSIONS 8 struct Vector get_avaliable_sessions() { struct Vector sessions = vec_new(); - vec_reserve(&sessions, 8); + vec_reserve(&sessions, LIKELY_BOUND_SESSIONS); cb_sessions = &sessions; for (size_t i = 0; i < (sizeof(sources) / sizeof(sources[0])); i++) {