diff --git a/Makefile b/Makefile index 1cc552f..2837c3a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ all: - gcc ./main.c -std=c89 -o th -lncurses -ltinfo -Wall + gcc ./main.c -std=c89 -o th -lncurses -ltinfo -Wall -O2 d: - gcc -g -std=c89 ./main.c -o th -lncurses -ltinfo -Wall && gdb --tui ./th + gcc -g -std=c89 ./main.c -o th -lncurses -ltinfo -Wall -O2 && gdb --tui ./th v: - gcc -g -std=c89 ./main.c -o th -lncurses -ltinfo && valgrind --leak-check=full --log-fd=9 9>>valgrind.log ./th + gcc -g -std=c89 ./main.c -o th -lncurses -ltinfo -O3 && valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all --log-fd=9 9>>valgrind.log ./th rel: gcc ./main.c -std=c89 -o th -lncurses -ltinfo -Wall -O2 -flto diff --git a/backend.c b/backend.c index 2e0de49..efec9d9 100644 --- a/backend.c +++ b/backend.c @@ -27,6 +27,7 @@ char* concat(const char *s1, const char *s2){ return result; } + unsigned long get_dir_size(char *path){ DIR *dir = opendir(path); unsigned long entry_count = 0; @@ -54,7 +55,6 @@ void get_dir_content(char *path, unsigned long *dir_file_count, file *dir_conten } else { scandir(path, &entry, skip_hidden_files, alphasort); } - unsigned long i = 0; @@ -155,8 +155,8 @@ void print_dir(WINDOW *win, unsigned long *line_width, unsigned long *dir_file_c unsigned long i = 0; unsigned long j = 0; float file_size = 0; - float printed_size; - char size_char; + float printed_size = 0; + char size_char = ' '; char is_selected = 0; static const char sizes[6] = { 'B', 'K', 'M', 'G', 'T', 'P' }; diff --git a/colors.c b/colors.c index d55eba1..042d275 100644 --- a/colors.c +++ b/colors.c @@ -97,7 +97,9 @@ void colors_init() { rewind(dircolors); + /*is it a leak when its intentional?*/ colors = malloc(sizeof(color) * color_count); + unsigned int i = 0; /* proper pass, reads all defined extensions within /etc/DIR_COLORS */ while (getline(&line, &size, dircolors) != -1) { diff --git a/config.h b/config.h index c698b79..7016725 100644 --- a/config.h +++ b/config.h @@ -29,10 +29,10 @@ static const binding key_binding[] = { { "e", update, NULL, "rerun all backend" }, /* executes the entire backend and redrawing of the screen */ { "/", not_implemented, NULL, "search" }, - { "h", move_right, NULL, "move right" }, /* moves one dir up */ + { "h", move_left, NULL, "move left" }, /* moves one dir up */ { "t", move_down, NULL, "move down" }, { "n", move_up, NULL, "move up" }, - { "s", move_left, NULL, "move left" }, /* if a dir is hovered, cd into it, if a file is selected, see mimetype_default_cmd */ + { "s", move_right, NULL, "move right" }, /* if a dir is hovered, cd into it, if a file is selected, see mimetype_default_cmd */ { "\n", open_with, NULL, "open \"open with\" dialog" }, /* opens the hovered file with an arbitrary command */ { "r", rename_hovered, NULL, "rename hovered file" }, /* renames currently hovered file/directory */ diff --git a/file_previews.c b/file_previews.c index 0884f51..428ee1e 100644 --- a/file_previews.c +++ b/file_previews.c @@ -22,9 +22,13 @@ char* get_mimetype(char *path){ FILE *cmd_open = popen(cmd, "r"); char *line; size_t size = 0; - getline(&line, &size, cmd_open); - pclose(cmd_open); - return line; + if (getline(&line, &size, cmd_open) != -1){ + pclose(cmd_open); + return line; + } else { + pclose(cmd_open); + return "unknown"; + } } char* preview_file(file *file_current){ /* this calls "file" on path */ @@ -47,10 +51,12 @@ char* text(char *path, unsigned long *file_size){ char *file_buffer = malloc(*file_size + 1); FILE *fp = fopen(path, "r"); - fread(file_buffer, *file_size, 1, fp); - file_buffer[*file_size] = '\0'; - - return file_buffer; + if (fread(file_buffer, *file_size, 1, fp) != 0) { + file_buffer[*file_size] = '\0'; + return file_buffer; + } else { + return "failed reading file"; + } } char* generic(char *path){ char *cmd = concat("file ./\"", path); @@ -59,7 +65,11 @@ char* generic(char *path){ FILE *cmd_open = popen(cmd, "r"); char *line; size_t size = 0; - getline(&line, &size, cmd_open); - pclose(cmd_open); - return line; + if (getline(&line, &size, cmd_open) != -1) { + pclose(cmd_open); + return line; + } else { + pclose(cmd_open); + return "failed executing shell command \"file\""; + } } diff --git a/interactions.c b/interactions.c index 4b6e744..d1c771b 100644 --- a/interactions.c +++ b/interactions.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "defines.h" #include "config.h" @@ -47,6 +48,14 @@ extern int (*order_func)(); +void FAIL(char *function, char *str){ + noraw(); + endwin(); + curs_set(1); + echo(); + printf("ERROR in function %s: %s", function, str); + kill(getpid(),9); +} void user_interactions() { @@ -208,19 +217,24 @@ void move_up(int passes){ status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK); pthread_mutex_unlock(&mutex_selection); } -void move_right(int passes){ +void move_left(int passes){ if (passes == 0) { passes++; } int i; for (i = 0; i < passes; i++) { - chdir(".."); + if (chdir("..") != 0) { + /* TODO(2025-07-09T00:30:05) fix */ + FAIL("move_left", "unhandled error of chdir"); + } } status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY); } -void move_left(){ +void move_right(){ if (file_current->file_type == FILE_TYPE_DIR || file_current->file_type == FILE_TYPE_SYMLINK) { - chdir(file_current->file_name); + if (chdir(file_current->file_name) != 0) { + FAIL("move_right", "unhandled error of chdir"); + } } else { unsigned long i = 0; char *mime = get_mimetype(file_current->file_name); @@ -235,7 +249,9 @@ void move_left(){ strcpy(btm_buffer, cmd); - system(cmd); + if (system(cmd) == -1) { + /*do nothing*/ + } status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY | STATUS_UPDATE_SCREEN_RELOAD_FULL); break; @@ -287,7 +303,9 @@ void open_with(){ cmd = concat(cmd, file_current->file_name); cmd = concat(cmd, "\""); - system(cmd); + if (system(cmd) == -1) { + FAIL("open_with", "creating subcommand failed unhandled"); + } free(btm_buffer); btm_buffer = cmd; @@ -326,7 +344,9 @@ void rename_hovered(){ cmd = concat(cmd, str); cmd = concat(cmd, "\""); - system(cmd); + if (system(cmd) == -1) { + FAIL("rename_hovered", "mv or creating subcommand failed"); + }; btm_buffer = cmd; } @@ -374,15 +394,18 @@ void delete(){ char ch = wgetch(win_b); if (ch == 'y' || ch == 'Y') { - /* the second loop is used to add "./", wich is not being printed" */ - char *cmd; + char *cmd = malloc(sizeof(char)); /* TODO(2025-06-30T02:27:06) IMPORTANT: this really fucks up when the file has a quotation mark in its name */ if (hits) { + /* the second loop is used to add "./", wich is not being printed" */ for (i = 0; i < mid_file_count; i++) { if (mid_content[i].status & FILE_STATUS_SELECTED) { + free(cmd); cmd = concat("rm -rf ./\"", mid_content[i].file_name); cmd = concat(cmd, "\""); - system(cmd); + if (system(cmd) == -1) { + FAIL("delete", "rm -rf or creating subcommand failed"); + } } } free(btm_buffer); @@ -391,9 +414,12 @@ void delete(){ free(btm_buffer); btm_buffer = concat("deleted: \"", file_current->file_name); btm_buffer = concat(btm_buffer, "\""); + free(cmd); cmd = concat("rm -rf ./\"", file_current->file_name); cmd = concat(cmd, "\""); - system(cmd); + if (system(cmd) == -1) { + FAIL("delete", "rm -rf or creating subcommand failed"); + } } /*system(cmd);*/ @@ -469,11 +495,10 @@ void not_implemented(int passes, int index){ } void jump_to_dir(int passes, int index){ if ((char*)key_binding[index].black_magic) { - chdir(getenv((char*)key_binding[index].black_magic+1)); - } else { - chdir((char*)key_binding[index].black_magic); - } - + if (chdir(getenv((char*)key_binding[index].black_magic+1)) != 0) { + FAIL("jump_to_dir", "jumping to black_magic in config.h failed"); + } + } status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY); } void order_by(int passes, int index){ @@ -520,26 +545,31 @@ void cmd_on_selected(int passes, int index){ if (ch == 'y' || ch == 'Y') { /* the second loop is used to add "./", wich is not being printed" */ - char *cmd; + char *cmd = malloc(sizeof(char)); /* TODO(2025-07-06T07:23:05) IMPORTANT: this really fucks up when the file has a quotation mark in its name */ if (hits) { for (i = 0; i < mid_file_count; i++) { if (mid_content[i].status & FILE_STATUS_SELECTED) { + free(cmd); cmd = concat((char*)key_binding[index].black_magic, " \""); cmd = concat(cmd, mid_content[i].file_name); cmd = concat(cmd, "\""); - system(cmd); - free(cmd); + if (system(cmd) != 0) { + /*do nothing*/ + } } } free(btm_buffer); btm_buffer = concat("completed: ", key_binding[index].black_magic); } else { free(btm_buffer); + free(cmd); cmd = concat((char*)key_binding[index].black_magic, " \""); cmd = concat(cmd, file_current->file_name); cmd = concat(cmd, "\""); - system(cmd); + if (system(cmd) != 0) { + /*do nothing*/ + } mvaddstr(10,10, cmd); } diff --git a/interactions.h b/interactions.h index c93f0a4..43d8d97 100644 --- a/interactions.h +++ b/interactions.h @@ -9,10 +9,10 @@ void user_interactions(); void quit_program(); void toggle_selection(); -void move_right(int pssses); +void move_right(); void move_up(int passes); void move_down(int passes); -void move_left(); +void move_left(int passes); void jump_bottom(); void jump_top(); void toggle_hidden_files(); diff --git a/main.c b/main.c index d1255f9..80eab9f 100644 --- a/main.c +++ b/main.c @@ -129,11 +129,11 @@ void render_pass(){ /*TODO: check if deallocation of window and reallocation is faster than this or not */ - werase(win_t); - werase(win_b); - werase(win_l); - werase(win_m); - werase(win_r); + wclear(win_t); + wclear(win_b); + wclear(win_l); + wclear(win_m); + wclear(win_r); wresize(win_t, 1, terminal_width); wresize(win_l, terminal_height-2, terminal_width/8); @@ -172,7 +172,6 @@ void init() { initscr(); /* start ncurses */ noecho(); /* hide keyboard input */ timeout(0); /* blocking timeout of getch() */ - keypad(stdscr, TRUE); curs_set(0); /*file_modifiers = (FILE_MODIFIERS_HIDDEN_FILES | FILE_MODIFIERS_SORT_BITMASK);*/ @@ -180,13 +179,14 @@ void init() { memset(input, 0, 255); status = (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY); if (getuid() == 0) { - status += STATUS_USER_ROOT; + status |= STATUS_USER_ROOT; } threading_init(); /* found in threading.c */ colors_init(); ESCDELAY = 10; - - setenv("START_PATH", getcwd(NULL, 0), 0); + char *start_path = getcwd(NULL, 0); + setenv("START_PATH", start_path, 0); + free(start_path); } diff --git a/threading.c b/threading.c index f162e89..fd1d298 100644 --- a/threading.c +++ b/threading.c @@ -28,7 +28,7 @@ char *btm_buffer; file *file_current; -char *top_content; /* current path */ +char *top_buffer; /* current path */ unsigned long rgt_file_count; unsigned long mid_file_count; @@ -191,17 +191,20 @@ void *thread_rgt(void *data){ get_dir_content(path, &rgt_file_count, rgt_content); rgt_content[0].status &= ~FILE_STATUS_FILE_OPEN; free(path); + + free(rgt_buffer); + rgt_buffer = malloc(sizeof(char)); + memset(rgt_buffer, ' ', sizeof(char)); } else { rgt_file_count = 0; + free(rgt_buffer); if (rgt_content->status & FILE_STATUS_DIR_EMPTY) { - free(rgt_buffer); rgt_buffer = "empty dir"; } else { rgt_content->file_type = FILE_TYPE_OPEN_FILE; rgt_content->status = FILE_STATUS_HOVER; - free(rgt_buffer); rgt_buffer = preview_file(rgt_content); } } @@ -211,16 +214,16 @@ void *thread_rgt(void *data){ } void *thread_top(void *data){ pthread_mutex_lock(&mutex_top); - free(top_content); + free(top_buffer); char *path; if((path=getcwd(NULL, 0)) == NULL) { - top_content = malloc(sizeof("cannot open directory")); + top_buffer = malloc(sizeof("cannot open directory")); top_width = sizeof("cannot open directory"); - top_content = "cannot open directory"; + top_buffer = "cannot open directory"; } else { - top_content = getcwd(NULL, 0); - top_width = strlen(top_content); + top_buffer = getcwd(NULL, 0); + top_width = strlen(top_buffer); } free(path); @@ -228,12 +231,12 @@ void *thread_top(void *data){ pthread_exit(0); } void *thread_btm(void *data){ + pthread_mutex_lock(&mutex_btm); pthread_mutex_lock(&mutex_wait); wait_count++; pthread_cond_wait(&cond_wait, &mutex_wait); wait_count--; pthread_mutex_unlock(&mutex_wait); - pthread_mutex_lock(&mutex_btm); free(btm_buffer); int buffer_width = terminal_width; @@ -260,9 +263,12 @@ void threading_init(){ mid_content = malloc(sizeof(file)); lft_content = malloc(sizeof(file)); - top_content = malloc(sizeof(char)); + top_buffer = malloc(sizeof(char)); rgt_buffer = malloc(sizeof(char)); btm_buffer = malloc(sizeof(char)); + memset(top_buffer, ' ', sizeof(char)); + memset(rgt_buffer, ' ', sizeof(char)); + memset(btm_buffer, ' ', sizeof(char)); rgt_content[0].file_type = 0; @@ -291,7 +297,7 @@ void threading_free(){ free(rgt_content); free(mid_content); free(lft_content); - free(top_content); + free(top_buffer); pthread_mutex_destroy(&mutex_top); pthread_mutex_destroy(&mutex_mid); diff --git a/window.c b/window.c index 3d4cd6b..5108658 100644 --- a/window.c +++ b/window.c @@ -13,7 +13,7 @@ extern color *colors; extern file *mid_content; extern file *lft_content; extern file *rgt_content; -extern char *top_content; +extern char *top_buffer; extern char *rgt_buffer; extern char *btm_buffer; @@ -30,19 +30,18 @@ extern pthread_mutex_t mutex_mid; extern pthread_mutex_t mutex_rgt; void window_top(WINDOW *win){ - unsigned long i = 0; werase(win); - if (pthread_mutex_trylock(&mutex_top)) { - wprintw(win,"loading"); - status |= STATUS_UPDATE_SCREEN_0; - pthread_mutex_unlock(&mutex_rgt); - - } else { + if (pthread_mutex_trylock(&mutex_top) == 0) { wattron(win, COLOR_PAIR(COLOR_PATH)); - mvwprintw(win, i, 0, "%s", top_content); + if (*top_buffer != ' ') { /*printing ' ' (standard initialized value, see threading_init) makes valgrind throw a fuss*/ + mvwprintw(win, 0, 0, "%s", top_buffer); + } wattroff(win, COLOR_PAIR(COLOR_PATH)); pthread_mutex_unlock(&mutex_top); + } else { + wprintw(win,"loading"); + status |= STATUS_UPDATE_SCREEN_0; } } void window_btm(WINDOW *win){ @@ -50,17 +49,17 @@ void window_btm(WINDOW *win){ unsigned long local_width; unsigned long local_height; getmaxyx(win, local_height, local_width); - if (pthread_mutex_trylock(&mutex_btm)) { - mvwprintw(win, local_height/2, local_width/2, "LOADING"); - status |= STATUS_UPDATE_SCREEN_0; - pthread_mutex_unlock(&mutex_rgt); - } else { - mvwprintw(win, 0, 0, "%s", btm_buffer); + if (pthread_mutex_trylock(&mutex_btm) == 0) { + if (*top_buffer != ' ') { /*printing ' ' (standard initialized value, see threading_init) makes valgrind throw a fuss*/ + mvwprintw(win, 0, 0, "%s", btm_buffer); + } pthread_mutex_unlock(&mutex_btm); /*the printing of the input char is done in user_interactions*/ /*the printing of all possible inputs are done in user_interactions */ + } else { + mvwprintw(win, local_height/2, local_width/2, "LOADING"); + status |= STATUS_UPDATE_SCREEN_0; } - } void window_lft(WINDOW *win){ werase(win); @@ -69,14 +68,13 @@ void window_lft(WINDOW *win){ unsigned long local_width; unsigned long local_height; getmaxyx(win, local_height, local_width); - if (pthread_mutex_trylock(&mutex_lft)) { - mvwprintw(win, local_height/2, local_width/2, "LOADING"); - status |= STATUS_UPDATE_SCREEN_0; - pthread_mutex_unlock(&mutex_rgt); - - } else { + if (pthread_mutex_trylock(&mutex_lft) == 0) { print_dir(win, &local_width, &lft_file_count, lft_content); pthread_mutex_unlock(&mutex_lft); + + } else { + mvwprintw(win, local_height/2, local_width/2, "LOADING"); + status |= STATUS_UPDATE_SCREEN_0; } } void window_mid(WINDOW *win){ @@ -86,18 +84,16 @@ void window_mid(WINDOW *win){ unsigned long local_width; unsigned long local_height; getmaxyx(win, local_height, local_width); - if (pthread_mutex_trylock(&mutex_mid)) { - mvwprintw(win, local_height/2, local_width/2, "LOADING"); - status |= STATUS_UPDATE_SCREEN_0; - pthread_mutex_unlock(&mutex_rgt); - - } else { + if (pthread_mutex_trylock(&mutex_mid) == 0) { if (mid_file_count == 0) { mvwprintw(win, 0, 0, "empty"); } else { print_dir(win, &local_width, &mid_file_count, mid_content); } pthread_mutex_unlock(&mutex_mid); + } else { + mvwprintw(win, local_height/2, local_width/2, "LOADING"); + status |= STATUS_UPDATE_SCREEN_0; } } void window_rgt(WINDOW *win){ @@ -107,13 +103,7 @@ void window_rgt(WINDOW *win){ unsigned long local_width; unsigned long local_height; getmaxyx(win, local_height, local_width); - if (pthread_mutex_trylock(&mutex_rgt)) { - /* TODO(2025-06-13T00:49:26) fix race condition and use trylock */ - mvwprintw(win, local_height/2, local_width/2, "LOADING"); - status |= STATUS_UPDATE_SCREEN_0; - pthread_mutex_unlock(&mutex_rgt); - } else { - + if (pthread_mutex_trylock(&mutex_rgt) == 0) { if (rgt_file_count == 0) { if (rgt_content[0].file_type == FILE_TYPE_OPEN_FILE) { mvwprintw(win, 0, 0, "%s", rgt_buffer); @@ -126,5 +116,8 @@ void window_rgt(WINDOW *win){ print_dir(win, &local_width, &rgt_file_count, rgt_content); } pthread_mutex_unlock(&mutex_rgt); + } else { + mvwprintw(win, local_height/2, local_width/2, "LOADING"); + status |= STATUS_UPDATE_SCREEN_0; } }