Im building a terminal-based file viewer project with ncurses.h and C. Its only a side project as a hobby, and has a few lines of code. I get some segmentation errors and I don’t even have a clue where they are, if someone can check the code, I will appreciate a lot.
#include "window.h"
#include <dirent.h>
#include <menu.h>
#include <ncurses.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static DIR *get_dir(const char *path)
{
DIR *dir;
if (strcmp(path, "current") == 0)
dir = opendir(".");
else
dir = opendir(path);
if (dir == NULL)
{
perror("Error opening dir");
exit(-1);
}
return dir;
}
WINDOW *init_window(int start_y, int start_x, int y, int x)
{
WINDOW *win;
initscr();
getmaxyx(stdscr, y, x);
cbreak();
noecho();
if (x < WDIM_X || y < WDIM_Y)
{
start_x = (x - WDIM_X_MIN);
start_y = (y - WDIM_Y_MIN);
win = newwin(WDIM_Y_MIN, WDIM_X_MIN, 1, 2);
}
else {
start_x = (x - WDIM_X) / 2;
start_y = (y - WDIM_Y) / 2;
win = newwin(WDIM_Y, WDIM_X, start_y, start_x);
}
box(win, 0, 0);
start_color();
curs_set(0);
keypad(win, true);
init_pair(1, COLOR_BLACK, COLOR_BLUE);
wbkgd(win, COLOR_PAIR(1));
wrefresh(win);
return win;
}
void delete_window(WINDOW *win)
{
delwin(win);
endwin();
}
char *get_current_dir()
{
/*
char *dirs = malloc(MAX_LENGTH * sizeof(char));
if (getcwd(dirs, sizeof(char) * MAX_LENGTH) != NULL)
return dirs;
return "Error";
*/
char *cwd = getcwd(NULL, 0);
return cwd;
}
char **dir_items(DIR *dir)
{
char **current_dirs = (char **)malloc(MAX_LENGTH * sizeof(char *));
struct dirent *entry;
int i = 0;
while ((entry = readdir(dir)) != NULL)
{
char *name = entry->d_name;
int j=i;
while (j > 0 && strcmp(name, current_dirs[j-1]) < 0)
{
current_dirs[j] = current_dirs[j-1];
j--;
}
current_dirs[j] = name;
i++;
}
return current_dirs;
}
void cd(const char *path)
{
if (chdir(path) == -1)
{
perror("Error");
}
}
void ls(const char *path)
{
DIR *dir = get_dir(path);
struct dirent *entry;
while ((entry = readdir(dir)) != NULL)
printf("%s | %s\n", path, entry->d_name);
closedir(dir);
}
static int n_elements(char **items)
{
int i = 0;
while (items[i] != NULL)
{
i++;
}
return i;
}
/* static void moveMenu(MENU *menu, WINDOW *win)
{
char c;
WINDOW *w;
while ((c = wgetch(win)) != '1')
{
switch (c)
{
case 'j':
menu_driver(menu, REQ_DOWN_ITEM);
wrefresh(win);
break;
case 'k':
menu_driver(menu, REQ_UP_ITEM);
wrefresh(win);
break;
case 'q':
delete_window(win);
exit(-1);
break;
case '\n':
delete_window(win);
win = init_window(WDIM_Y, WDIM_X, 5, 5);
cd("/");
sleep(3);
render_dir(win);
break;
}
}
} */
void render_dir(WINDOW *win)
{
char **items_chars, *titulo, c;
int i=0, x, y;
int n;
DIR *dir;
ITEM **items;
MENU *menu;
char *path = get_current_dir();
path = strcat(path, "/");
dir = get_dir(path);
items_chars = dir_items(dir);
wclear(win);
titulo = malloc(MAX_LENGTH * sizeof(char));
strcpy(titulo, get_current_dir(path));
mvwprintw(win, 0, 1, titulo);
wrefresh(win);
n = n_elements(items_chars);
items = (ITEM **)calloc(n + 1, sizeof(ITEM *));
for (int j = 0; j < n; j++)
{
items[j] = new_item(items_chars[j], "");
}
// final have to be NULL
items[n] = (ITEM *)NULL;
menu = new_menu(items);
set_menu_win(menu, win);
set_menu_sub(menu, derwin(win, 25, 40, 2, 1));
// set_menu_fore(menu, A_NORMAL);
set_menu_format(menu, 25, 1);
set_menu_back(menu, COLOR_PAIR(1));
post_menu(menu);
wrefresh(win);
while ((c = wgetch(win)) != '1')
{
switch (c)
{
case 'j':
menu_driver(menu, REQ_DOWN_ITEM);
if (i > n)
i = n;
else
i++;
//i++;
wrefresh(win);
break;
case 'k':
menu_driver(menu, REQ_UP_ITEM);
if (i < 0)
i = 0;
else
i--;
//i--;
wrefresh(win);
break;
break;
case 'q':
delete_window(win);
exit(-1);
break;
case '\n':
for (int j = 0; j < n; j++)
{
free_item(items[j]);
}
free_menu(menu);
path = strcat(path, items_chars[i]);
free(items_chars);
free(titulo);
closedir(dir);
wclear(win);
delwin(win);
getmaxyx(stdscr, y, x);
if (x < WDIM_X || y < WDIM_Y)
win = init_window(WDIM_Y_MIN, WDIM_X_MIN, 5, 5);
else
win = init_window(WDIM_Y, WDIM_X, 5, 5);
cd(path);
free(path);
mvwprintw(win, 20, 1, "s");
render_dir(win);
break;
}
}
wrefresh(win);
}
Here is main
#include "window.h"
int main(int argc, char **argv)
{
WINDOW *win;
win = init_window(WDIM_Y, WDIM_X, 5, 5);
render_dir(win);
delete_window(win);
return 0;
}
I have tried to free all the memory in all ways but it still has segmentation faults and memory leaks.