Use our own entry struct instead of dirent

This commit is contained in:
lostd 2014-10-09 16:23:12 +03:00
parent 46669d7606
commit ee8898547c

65
noice.c
View file

@ -49,6 +49,11 @@ struct assoc assocs[] = {
{ "^README$", "less" }, { "^README$", "less" },
}; };
struct entry {
char *name;
mode_t mode;
};
#define CWD "cwd: " #define CWD "cwd: "
#define CURSR " > " #define CURSR " > "
#define EMPTY " " #define EMPTY " "
@ -94,14 +99,14 @@ openwith(char *file)
} }
int int
dentcmp(const void *va, const void *vb) entrycmp(const void *va, const void *vb)
{ {
const struct dirent *a, *b; const struct entry *a, *b;
a = (struct dirent *)va; a = (struct entry *)va;
b = (struct dirent *)vb; b = (struct entry *)vb;
return strcmp(a->d_name, b->d_name); return strcmp(a->name, b->name);
} }
void void
@ -208,12 +213,14 @@ void
browse(const char *ipath) browse(const char *ipath)
{ {
DIR *dirp; DIR *dirp;
int dfd;
struct dirent *dp; struct dirent *dp;
struct dirent *dents; struct entry *dents;
int i, n, cur; int i, n, cur;
int r, ret; int r, ret;
char *path = strdup(ipath); char *path = strdup(ipath);
char *cwd; char *cwd;
struct stat sb;
begin: begin:
/* Path should be a malloc(3)-ed string at all times */ /* Path should be a malloc(3)-ed string at all times */
@ -226,8 +233,13 @@ begin:
printwarn(); printwarn();
goto nochange; goto nochange;
} }
dfd = dirfd(dirp);
if (dfd == -1)
printerr(1, "dirfd");
while ((dp = readdir(dirp)) != NULL) { while ((dp = readdir(dirp)) != NULL) {
char *name;
/* Skip self and parent */ /* Skip self and parent */
if (strcmp(dp->d_name, ".") == 0 if (strcmp(dp->d_name, ".") == 0
|| strcmp(dp->d_name, "..") == 0) || strcmp(dp->d_name, "..") == 0)
@ -236,15 +248,23 @@ begin:
dents = realloc(dents, (n + 1) * sizeof(*dents)); dents = realloc(dents, (n + 1) * sizeof(*dents));
if (dents == NULL) if (dents == NULL)
printerr(1, "realloc"); printerr(1, "realloc");
memcpy(&dents[n], dp, sizeof(*dents)); dents[n].name = strdup(dp->d_name);
if (dents[n].name == NULL)
printerr(1, "strdup");
/* Get mode flags */
r = fstatat(dfd, dents[n].name, &sb, 0);
if (r == -1)
printerr(1, "stat");
dents[n].mode = sb.st_mode;
n++; n++;
} }
qsort(dents, n, sizeof(*dents), dentcmp); qsort(dents, n, sizeof(*dents), entrycmp);
for (;;) { for (;;) {
int nlines; int nlines;
struct dirent *tmpents; struct entry *tmpents;
int maxlen;
int odd; int odd;
redraw: redraw:
@ -270,9 +290,17 @@ redraw:
/* No text wrapping in entries */ /* No text wrapping in entries */
tmpents = malloc(n * sizeof(*tmpents)); tmpents = malloc(n * sizeof(*tmpents));
memcpy(tmpents, dents, n * sizeof(*tmpents)); maxlen = COLS - strlen(CURSR) - 1;
for (i = 0; i < n; i++) for (i = 0; i < n; i++) {
tmpents[i].d_name[COLS - strlen(CURSR) - 1] = '\0'; struct entry *tmpent = &tmpents[i];
tmpent->name = strdup(dents[i].name);
if (tmpent->name == NULL)
printerr(1, "strdup tmp");
tmpent->mode = dents[i].mode;
if (strlen(tmpent->name) > maxlen)
tmpent->name[maxlen] = '\0';
}
/* Print cwd. If empty we are on the root. We store it /* Print cwd. If empty we are on the root. We store it
* as an empty string so that when we navigate in /mnt * as an empty string so that when we navigate in /mnt
@ -287,20 +315,22 @@ redraw:
for (i = 0; i < nlines; i++) for (i = 0; i < nlines; i++)
printw("%s%s\n", printw("%s%s\n",
i == cur ? CURSR : EMPTY, i == cur ? CURSR : EMPTY,
tmpents[i].d_name); tmpents[i].name);
} else if (cur >= n - nlines / 2) { } else if (cur >= n - nlines / 2) {
for (i = n - nlines; i < n; i++) for (i = n - nlines; i < n; i++)
printw("%s%s\n", printw("%s%s\n",
i == cur ? CURSR : EMPTY, i == cur ? CURSR : EMPTY,
tmpents[i].d_name); tmpents[i].name);
} else { } else {
for (i = cur - nlines / 2; for (i = cur - nlines / 2;
i < cur + nlines / 2 + odd; i++) i < cur + nlines / 2 + odd; i++)
printw("%s%s\n", printw("%s%s\n",
i == cur ? CURSR : EMPTY, i == cur ? CURSR : EMPTY,
tmpents[i].d_name); tmpents[i].name);
} }
for (i = 0; i < n; i++)
free(tmpents[i].name);
free(tmpents); free(tmpents);
nochange: nochange:
@ -330,13 +360,12 @@ nochange:
char *bin; char *bin;
pid_t pid; pid_t pid;
int fd; int fd;
struct stat sb;
/* Cannot descend in empty directories */ /* Cannot descend in empty directories */
if (n == 0) if (n == 0)
goto nochange; goto nochange;
name = dents[cur].d_name; name = dents[cur].name;
asprintf(&pathnew, "%s/%s", path, name); asprintf(&pathnew, "%s/%s", path, name);
@ -396,6 +425,8 @@ nochange:
} }
out: out:
for (i = 0; i < n; i++)
free(dents[i].name);
free(dents); free(dents);
r = closedir(dirp); r = closedir(dirp);