Lotsa improvements
This commit is contained in:
parent
9786f9a525
commit
ab46185843
191
bb.c
191
bb.c
@ -24,7 +24,7 @@
|
|||||||
#define MIN(a,b) ((a) > (b) ? (b) : (a))
|
#define MIN(a,b) ((a) > (b) ? (b) : (a))
|
||||||
#define MAX_PATH 4096
|
#define MAX_PATH 4096
|
||||||
#define writez(fd, str) write(fd, str, strlen(str))
|
#define writez(fd, str) write(fd, str, strlen(str))
|
||||||
#define IS_SELECTED(p) ((p)->next || (p)->prev)
|
#define IS_SELECTED(p) ((p)->atme)
|
||||||
|
|
||||||
static const int SCROLLOFF = 5;
|
static const int SCROLLOFF = 5;
|
||||||
|
|
||||||
@ -34,8 +34,9 @@ static int width, height;
|
|||||||
static int mouse_x, mouse_y;
|
static int mouse_x, mouse_y;
|
||||||
|
|
||||||
typedef struct entry_s {
|
typedef struct entry_s {
|
||||||
struct entry_s *next, *prev;
|
struct entry_s *next, **atme;
|
||||||
int visible : 1;
|
int visible : 1;
|
||||||
|
int d_isdir : 1;
|
||||||
ino_t d_ino;
|
ino_t d_ino;
|
||||||
__uint16_t d_reclen;
|
__uint16_t d_reclen;
|
||||||
__uint8_t d_type;
|
__uint8_t d_type;
|
||||||
@ -50,6 +51,7 @@ typedef struct {
|
|||||||
size_t nselected, nfiles;
|
size_t nselected, nfiles;
|
||||||
int scroll, cursor;
|
int scroll, cursor;
|
||||||
struct timespec lastclick;
|
struct timespec lastclick;
|
||||||
|
int showhidden : 1;
|
||||||
} bb_state_t;
|
} bb_state_t;
|
||||||
|
|
||||||
static void err(const char *msg, ...);
|
static void err(const char *msg, ...);
|
||||||
@ -163,6 +165,9 @@ static void render(bb_state_t *state)
|
|||||||
writez(termfd, "\e[2J\e[0;1m"); // Clear, reset color + bold
|
writez(termfd, "\e[2J\e[0;1m"); // Clear, reset color + bold
|
||||||
term_move(0,0);
|
term_move(0,0);
|
||||||
writez(termfd, state->path);
|
writez(termfd, state->path);
|
||||||
|
|
||||||
|
term_move(0,1);
|
||||||
|
writez(termfd, "\e[32m Size Date Bits Name");
|
||||||
writez(termfd, "\e[0m"); // Reset color
|
writez(termfd, "\e[0m"); // Reset color
|
||||||
|
|
||||||
char fullpath[MAX_PATH];
|
char fullpath[MAX_PATH];
|
||||||
@ -173,21 +178,23 @@ static void render(bb_state_t *state)
|
|||||||
entry_t *entry = files[i];
|
entry_t *entry = files[i];
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = i - state->scroll + 1;
|
int y = i - state->scroll + 2;
|
||||||
term_move(x, y);
|
term_move(x, y);
|
||||||
|
|
||||||
// Selection box:
|
// Selection box:
|
||||||
if (IS_SELECTED(entry))
|
if (IS_SELECTED(entry))
|
||||||
writez(termfd, "\e[43m \e[0m"); // Yellow BG
|
writez(termfd, "\e[43m \e[0m");
|
||||||
else
|
else
|
||||||
writez(termfd, " ");
|
writez(termfd, " ");
|
||||||
|
|
||||||
if (i != state->cursor && entry->d_type & DT_DIR) {
|
if (i == state->cursor)
|
||||||
writez(termfd, "\e[34m"); // Blue FG
|
writez(termfd, "\e[30;47m");
|
||||||
}
|
else if (entry->d_isdir && entry->d_type == DT_LNK)
|
||||||
if (i == state->cursor) {
|
writez(termfd, "\e[36m");
|
||||||
writez(termfd, "\e[7m"); // Reverse color
|
else if (entry->d_isdir)
|
||||||
}
|
writez(termfd, "\e[34m");
|
||||||
|
else if (entry->d_type == DT_LNK)
|
||||||
|
writez(termfd, "\e[33m");
|
||||||
|
|
||||||
struct stat info = {0};
|
struct stat info = {0};
|
||||||
fullpath[pathlen] = '/';
|
fullpath[pathlen] = '/';
|
||||||
@ -205,7 +212,7 @@ static void render(bb_state_t *state)
|
|||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
char buf[16] = {0};
|
char buf[16] = {0};
|
||||||
sprintf(buf, "%6.*f%c ", j > 0 ? 1 : 0, bytes, units[j]);
|
sprintf(buf, "%6.*f%c │", j > 0 ? 1 : 0, bytes, units[j]);
|
||||||
writez(termfd, buf);
|
writez(termfd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,24 +221,38 @@ static void render(bb_state_t *state)
|
|||||||
char buf[64];
|
char buf[64];
|
||||||
strftime(buf, sizeof(buf), "%l:%M%p %b %e %Y", localtime(&(info.st_mtime)));
|
strftime(buf, sizeof(buf), "%l:%M%p %b %e %Y", localtime(&(info.st_mtime)));
|
||||||
writez(termfd, buf);
|
writez(termfd, buf);
|
||||||
writez(termfd, " ");
|
//writez(termfd, " ");
|
||||||
|
writez(termfd, " │ ");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Permissions:
|
||||||
|
char buf[] = {
|
||||||
|
'0' + ((info.st_mode >> 6) & 7),
|
||||||
|
'0' + ((info.st_mode >> 3) & 7),
|
||||||
|
'0' + ((info.st_mode >> 0) & 7),
|
||||||
|
};
|
||||||
|
write(termfd, buf, 5);
|
||||||
|
writez(termfd, " │ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name:
|
// Name:
|
||||||
write(termfd, entry->d_name, entry->d_namlen);
|
write(termfd, entry->d_name, entry->d_namlen);
|
||||||
|
if (entry->d_isdir)
|
||||||
if (entry->d_type & DT_DIR) {
|
|
||||||
writez(termfd, "/");
|
writez(termfd, "/");
|
||||||
}
|
|
||||||
if (entry->d_type == DT_LNK) {
|
if (entry->d_type == DT_LNK) {
|
||||||
char linkpath[MAX_PATH] = {0};
|
char linkpath[MAX_PATH] = {0};
|
||||||
ssize_t pathlen;
|
ssize_t pathlen;
|
||||||
if ((pathlen = readlink(entry->d_name, linkpath, sizeof(linkpath))) < 0)
|
if ((pathlen = readlink(entry->d_name, linkpath, sizeof(linkpath))) < 0)
|
||||||
err("readlink() failed");
|
err("readlink() failed");
|
||||||
writez(termfd, "\e[36m -> "); // Cyan FG
|
//writez(termfd, "\e[36m -> "); // Cyan FG
|
||||||
|
writez(termfd, " -> ");
|
||||||
write(termfd, linkpath, pathlen);
|
write(termfd, linkpath, pathlen);
|
||||||
|
if (entry->d_isdir)
|
||||||
|
writez(termfd, "/");
|
||||||
}
|
}
|
||||||
writez(termfd, "\e[0m"); // Reset color and attributes
|
writez(termfd, " \e[0m"); // Reset color and attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
term_move(0, height - 1);
|
term_move(0, height - 1);
|
||||||
@ -244,7 +265,7 @@ static int compare_alpha(const void *v1, const void *v2)
|
|||||||
{
|
{
|
||||||
const entry_t *f1 = *((const entry_t**)v1), *f2 = *((const entry_t**)v2);
|
const entry_t *f1 = *((const entry_t**)v1), *f2 = *((const entry_t**)v2);
|
||||||
int diff;
|
int diff;
|
||||||
diff = (f1->d_type & DT_DIR) - (f2->d_type & DT_DIR);
|
diff = -(f1->d_isdir - f2->d_isdir);
|
||||||
if (diff) return -diff;
|
if (diff) return -diff;
|
||||||
const char *p1 = f1->d_name, *p2 = f2->d_name;
|
const char *p1 = f1->d_name, *p2 = f2->d_name;
|
||||||
while (*p1 && *p2) {
|
while (*p1 && *p2) {
|
||||||
@ -385,8 +406,10 @@ static void explore(char *path)
|
|||||||
while ((dp = readdir(dir)) != NULL) {
|
while ((dp = readdir(dir)) != NULL) {
|
||||||
if (dp->d_name[0] == '.' && dp->d_name[1] == '\0')
|
if (dp->d_name[0] == '.' && dp->d_name[1] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
if (!state.showhidden && dp->d_name[0] == '.' && !(dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
|
||||||
|
continue;
|
||||||
// Hashed lookup from selected:
|
// Hashed lookup from selected:
|
||||||
if (state.firstselected) {
|
if (state.nselected > 0) {
|
||||||
for (int probe = ((int)dp->d_ino) % hashsize; selecthash[probe]; probe = (probe + 1) % hashsize) {
|
for (int probe = ((int)dp->d_ino) % hashsize; selecthash[probe]; probe = (probe + 1) % hashsize) {
|
||||||
if (selecthash[probe]->d_ino == dp->d_ino) {
|
if (selecthash[probe]->d_ino == dp->d_ino) {
|
||||||
selecthash[probe]->visible = 1;
|
selecthash[probe]->visible = 1;
|
||||||
@ -403,8 +426,14 @@ static void explore(char *path)
|
|||||||
entry->d_ino = dp->d_ino;
|
entry->d_ino = dp->d_ino;
|
||||||
entry->d_reclen = dp->d_reclen;
|
entry->d_reclen = dp->d_reclen;
|
||||||
entry->d_type = dp->d_type;
|
entry->d_type = dp->d_type;
|
||||||
|
entry->d_isdir = dp->d_type == DT_DIR;
|
||||||
|
if (!entry->d_isdir && entry->d_type == DT_LNK) {
|
||||||
|
struct stat statbuf;
|
||||||
|
if (stat(entry->d_fullname, &statbuf) == 0)
|
||||||
|
entry->d_isdir = S_ISDIR(statbuf.st_mode);
|
||||||
|
}
|
||||||
entry->d_namlen = dp->d_namlen;
|
entry->d_namlen = dp->d_namlen;
|
||||||
entry->next = NULL, entry->prev = NULL;
|
entry->next = NULL, entry->atme = NULL;
|
||||||
|
|
||||||
if (state.nfiles >= filecap) {
|
if (state.nfiles >= filecap) {
|
||||||
filecap += 100;
|
filecap += 100;
|
||||||
@ -437,9 +466,7 @@ static void explore(char *path)
|
|||||||
redraw:
|
redraw:
|
||||||
render(&state);
|
render(&state);
|
||||||
skip_redraw:
|
skip_redraw:
|
||||||
scrolloff = MIN(SCROLLOFF, height/2);
|
scrolloff = MIN(SCROLLOFF, (height-4)/2);
|
||||||
//sleep(2);
|
|
||||||
//if (1) goto done;
|
|
||||||
int key = term_get_event();
|
int key = term_get_event();
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case KEY_MOUSE_LEFT: {
|
case KEY_MOUSE_LEFT: {
|
||||||
@ -448,8 +475,8 @@ static void explore(char *path)
|
|||||||
double dt_ms = 1e3*(double)(clicktime.tv_sec - state.lastclick.tv_sec);
|
double dt_ms = 1e3*(double)(clicktime.tv_sec - state.lastclick.tv_sec);
|
||||||
dt_ms += 1e-6*(double)(clicktime.tv_nsec - state.lastclick.tv_nsec);
|
dt_ms += 1e-6*(double)(clicktime.tv_nsec - state.lastclick.tv_nsec);
|
||||||
state.lastclick = clicktime;
|
state.lastclick = clicktime;
|
||||||
if (mouse_y > 0 && state.scroll + (mouse_y - 1) < state.nfiles) {
|
if (mouse_y > 0 && state.scroll + (mouse_y - 2) < state.nfiles) {
|
||||||
int clicked = state.scroll + (mouse_y - 1);
|
int clicked = state.scroll + (mouse_y - 2);
|
||||||
if (dt_ms > 200) {
|
if (dt_ms > 200) {
|
||||||
// Single click
|
// Single click
|
||||||
if (mouse_x == 0) {
|
if (mouse_x == 0) {
|
||||||
@ -473,43 +500,52 @@ static void explore(char *path)
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
case KEY_CTRL_D:
|
case KEY_CTRL_D:
|
||||||
state.cursor = MIN(state.nfiles - 1, state.cursor + (height - 3) / 2);
|
state.cursor = MIN(state.nfiles - 1, state.cursor + (height - 4) / 2);
|
||||||
if (state.nfiles <= height - 3)
|
if (state.nfiles <= height - 4)
|
||||||
goto redraw;
|
goto redraw;
|
||||||
state.scroll += (height - 3)/2;
|
state.scroll += (height - 4)/2;
|
||||||
if (state.scroll > state.nfiles - (height - 3))
|
if (state.scroll > state.nfiles - (height - 4))
|
||||||
state.scroll = state.nfiles - (height - 3);
|
state.scroll = state.nfiles - (height - 4);
|
||||||
goto redraw;
|
goto redraw;
|
||||||
|
|
||||||
case KEY_CTRL_U:
|
case KEY_CTRL_U:
|
||||||
state.cursor = MAX(0, state.cursor - (height - 3) / 2);
|
state.cursor = MAX(0, state.cursor - (height - 4) / 2);
|
||||||
if (state.nfiles <= height - 3)
|
if (state.nfiles <= height - 4)
|
||||||
goto redraw;
|
goto redraw;
|
||||||
state.scroll -= (height - 3)/2;
|
state.scroll -= (height - 4)/2;
|
||||||
if (state.scroll < 0)
|
if (state.scroll < 0)
|
||||||
state.scroll = 0;
|
state.scroll = 0;
|
||||||
goto redraw;
|
goto redraw;
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
state.cursor = 0;
|
||||||
|
state.scroll = 0;
|
||||||
|
goto redraw;
|
||||||
|
|
||||||
|
case 'G':
|
||||||
|
state.cursor = state.nfiles - 1;
|
||||||
|
if (state.nfiles > height - 4)
|
||||||
|
state.scroll = state.nfiles - (height - 4);
|
||||||
|
goto redraw;
|
||||||
|
|
||||||
case ' ':
|
case ' ':
|
||||||
picked = state.cursor;
|
picked = state.cursor;
|
||||||
toggle:
|
toggle:
|
||||||
|
if (picked == 0) goto skip_redraw;
|
||||||
if (IS_SELECTED(state.files[picked])) {
|
if (IS_SELECTED(state.files[picked])) {
|
||||||
toggle_off:;
|
toggle_off:;
|
||||||
entry_t *e = state.files[picked];
|
entry_t *e = state.files[picked];
|
||||||
if (state.firstselected == e)
|
if (e->next) e->next->atme = e->atme;
|
||||||
state.firstselected = e->next;
|
*(e->atme) = e->next;
|
||||||
if (e->prev) e->prev->next = e->next;
|
e->next = NULL, e->atme = NULL;
|
||||||
if (e->next) e->next->prev = e->prev;
|
|
||||||
e->next = NULL;
|
|
||||||
e->prev = NULL;
|
|
||||||
--state.nselected;
|
--state.nselected;
|
||||||
} else {
|
} else {
|
||||||
toggle_on:;
|
toggle_on:;
|
||||||
entry_t *e = state.files[picked];
|
entry_t *e = state.files[picked];
|
||||||
if (state.firstselected) {
|
if (state.firstselected)
|
||||||
|
state.firstselected->atme = &e->next;
|
||||||
e->next = state.firstselected;
|
e->next = state.firstselected;
|
||||||
state.firstselected->prev = e;
|
e->atme = &state.firstselected;
|
||||||
}
|
|
||||||
state.firstselected = e;
|
state.firstselected = e;
|
||||||
++state.nselected;
|
++state.nselected;
|
||||||
}
|
}
|
||||||
@ -518,7 +554,7 @@ static void explore(char *path)
|
|||||||
case KEY_ESC:
|
case KEY_ESC:
|
||||||
for (entry_t *e = state.firstselected; e; e = e->next) {
|
for (entry_t *e = state.firstselected; e; e = e->next) {
|
||||||
e->next = NULL;
|
e->next = NULL;
|
||||||
e->prev = NULL;
|
e->atme = NULL;
|
||||||
if (!e->visible) free(e);
|
if (!e->visible) free(e);
|
||||||
}
|
}
|
||||||
state.firstselected = NULL;
|
state.firstselected = NULL;
|
||||||
@ -529,7 +565,7 @@ static void explore(char *path)
|
|||||||
if (state.cursor >= state.nfiles - 1)
|
if (state.cursor >= state.nfiles - 1)
|
||||||
goto skip_redraw;
|
goto skip_redraw;
|
||||||
++state.cursor;
|
++state.cursor;
|
||||||
if (state.cursor > state.scroll + height - 4 - scrolloff && state.scroll < state.nfiles - (height - 3)) {
|
if (state.cursor > state.scroll + height - 4 - 1 - scrolloff && state.scroll < state.nfiles - (height - 4)) {
|
||||||
++state.scroll;
|
++state.scroll;
|
||||||
}
|
}
|
||||||
goto redraw;
|
goto redraw;
|
||||||
@ -547,11 +583,14 @@ static void explore(char *path)
|
|||||||
if (state.cursor < state.nfiles - 1) {
|
if (state.cursor < state.nfiles - 1) {
|
||||||
if (IS_SELECTED(state.files[state.cursor])) {
|
if (IS_SELECTED(state.files[state.cursor])) {
|
||||||
picked = ++state.cursor;
|
picked = ++state.cursor;
|
||||||
|
if (!IS_SELECTED(state.files[picked]))
|
||||||
goto toggle_on;
|
goto toggle_on;
|
||||||
} else {
|
} else {
|
||||||
picked = ++state.cursor;
|
picked = ++state.cursor;
|
||||||
|
if (IS_SELECTED(state.files[picked]))
|
||||||
goto toggle_off;
|
goto toggle_off;
|
||||||
}
|
}
|
||||||
|
goto redraw;
|
||||||
}
|
}
|
||||||
goto skip_redraw;
|
goto skip_redraw;
|
||||||
|
|
||||||
@ -559,64 +598,42 @@ static void explore(char *path)
|
|||||||
if (state.cursor > 0) {
|
if (state.cursor > 0) {
|
||||||
if (IS_SELECTED(state.files[state.cursor])) {
|
if (IS_SELECTED(state.files[state.cursor])) {
|
||||||
picked = --state.cursor;
|
picked = --state.cursor;
|
||||||
|
if (!IS_SELECTED(state.files[picked]))
|
||||||
goto toggle_on;
|
goto toggle_on;
|
||||||
} else {
|
} else {
|
||||||
picked = --state.cursor;
|
picked = --state.cursor;
|
||||||
|
if (IS_SELECTED(state.files[picked]))
|
||||||
goto toggle_off;
|
goto toggle_off;
|
||||||
}
|
}
|
||||||
|
goto redraw;
|
||||||
}
|
}
|
||||||
goto skip_redraw;
|
goto skip_redraw;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
if (strcmp(state.path, "/") != 0) {
|
picked = 0;
|
||||||
char *p = strrchr(state.path, '/');
|
goto open_file;
|
||||||
if (p) strcpy(to_select, p+1);
|
|
||||||
else to_select[0] = '\0';
|
case '.':
|
||||||
char tmp[MAX_PATH], tmp2[MAX_PATH];
|
state.showhidden ^= 1;
|
||||||
strcpy(tmp, state.path);
|
|
||||||
strcat(tmp, "/");
|
|
||||||
strcat(tmp, "..");
|
|
||||||
if (!realpath(tmp, tmp2))
|
|
||||||
err("realpath failed");
|
|
||||||
free(path);
|
|
||||||
path = malloc(strlen(tmp2) + 1);
|
|
||||||
strcpy(path, tmp2);
|
|
||||||
goto tail_call;
|
goto tail_call;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l': case '\r':
|
case 'l': case '\r':
|
||||||
picked = state.cursor;
|
picked = state.cursor;
|
||||||
open_file:
|
open_file:
|
||||||
{
|
{
|
||||||
int is_dir = state.files[picked]->d_type & DT_DIR;
|
if (state.files[picked]->d_isdir) {
|
||||||
if (state.files[picked]->d_type == DT_LNK) {
|
|
||||||
char linkpath[MAX_PATH];
|
|
||||||
if (readlink(state.files[picked]->d_name, linkpath, sizeof(linkpath)) < 0)
|
|
||||||
err("readlink() failed");
|
|
||||||
DIR *dir = opendir(linkpath);
|
|
||||||
if (dir) {
|
|
||||||
is_dir = 1;
|
|
||||||
if (closedir(dir) < 0)
|
|
||||||
err("Failed to close directory: %s", linkpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_dir) {
|
|
||||||
if (strcmp(state.files[picked]->d_name, "..") == 0) {
|
if (strcmp(state.files[picked]->d_name, "..") == 0) {
|
||||||
char *p = strrchr(state.path, '/');
|
char *p = strrchr(state.path, '/');
|
||||||
if (p) strcpy(to_select, p+1);
|
if (p) strcpy(to_select, p+1);
|
||||||
else to_select[0] = '\0';
|
else to_select[0] = '\0';
|
||||||
} else to_select[0] = '\0';
|
} else to_select[0] = '\0';
|
||||||
|
|
||||||
char tmp[MAX_PATH], tmp2[MAX_PATH];
|
char tmp[MAX_PATH];
|
||||||
strcpy(tmp, state.path);
|
if (!realpath(state.files[picked]->d_fullname, tmp))
|
||||||
strcat(tmp, "/");
|
|
||||||
strcat(tmp, state.files[picked]->d_name);
|
|
||||||
if (!realpath(tmp, tmp2))
|
|
||||||
err("realpath failed");
|
err("realpath failed");
|
||||||
free(path);
|
free(path);
|
||||||
path = malloc(strlen(tmp2) + 1);
|
path = calloc(strlen(tmp) + 1, sizeof(char));
|
||||||
strcpy(path, tmp2);
|
strcpy(path, tmp);
|
||||||
goto tail_call;
|
goto tail_call;
|
||||||
} else {
|
} else {
|
||||||
char *name = state.files[picked]->d_name;
|
char *name = state.files[picked]->d_name;
|
||||||
@ -662,10 +679,8 @@ static void explore(char *path)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case '|': {
|
||||||
if (state.nselected) {
|
|
||||||
close_term();
|
close_term();
|
||||||
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t bufsize = 0;
|
size_t bufsize = 0;
|
||||||
printf("> ");
|
printf("> ");
|
||||||
@ -673,8 +688,15 @@ static void explore(char *path)
|
|||||||
getline(&buf, &bufsize, stdin);
|
getline(&buf, &bufsize, stdin);
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
pid_t child = run_cmd(NULL, &fd, "xargs %s", buf);
|
pid_t child = run_cmd(NULL, &fd, buf);
|
||||||
|
if (state.nselected > 0) {
|
||||||
write_selection(fd, state.firstselected);
|
write_selection(fd, state.firstselected);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < state.nfiles; i++) {
|
||||||
|
write(fd, state.files[i]->d_name, state.files[i]->d_namlen);
|
||||||
|
write(fd, "\n", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
waitpid(child, NULL, 0);
|
waitpid(child, NULL, 0);
|
||||||
|
|
||||||
@ -684,9 +706,8 @@ static void explore(char *path)
|
|||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
init_term();
|
init_term();
|
||||||
goto redraw;
|
goto tail_call;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto skip_redraw;
|
goto skip_redraw;
|
||||||
|
Loading…
Reference in New Issue
Block a user