commit ee8898547cb4ddab3724c8df0d3c4e18c79beab6
parent 46669d7606e7e763f63aa7b2533291a3699d5911
Author: lostd <lostd@2f30.org>
Date: Thu, 9 Oct 2014 16:23:12 +0300
Use our own entry struct instead of dirent
Diffstat:
M | noice.c | | | 65 | ++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
1 file changed, 48 insertions(+), 17 deletions(-)
diff --git a/noice.c b/noice.c
@@ -49,6 +49,11 @@ struct assoc assocs[] = {
{ "^README$", "less" },
};
+struct entry {
+ char *name;
+ mode_t mode;
+};
+
#define CWD "cwd: "
#define CURSR " > "
#define EMPTY " "
@@ -94,14 +99,14 @@ openwith(char *file)
}
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;
- b = (struct dirent *)vb;
+ a = (struct entry *)va;
+ b = (struct entry *)vb;
- return strcmp(a->d_name, b->d_name);
+ return strcmp(a->name, b->name);
}
void
@@ -208,12 +213,14 @@ void
browse(const char *ipath)
{
DIR *dirp;
+ int dfd;
struct dirent *dp;
- struct dirent *dents;
+ struct entry *dents;
int i, n, cur;
int r, ret;
char *path = strdup(ipath);
char *cwd;
+ struct stat sb;
begin:
/* Path should be a malloc(3)-ed string at all times */
@@ -226,8 +233,13 @@ begin:
printwarn();
goto nochange;
}
+ dfd = dirfd(dirp);
+ if (dfd == -1)
+ printerr(1, "dirfd");
while ((dp = readdir(dirp)) != NULL) {
+ char *name;
+
/* Skip self and parent */
if (strcmp(dp->d_name, ".") == 0
|| strcmp(dp->d_name, "..") == 0)
@@ -236,15 +248,23 @@ begin:
dents = realloc(dents, (n + 1) * sizeof(*dents));
if (dents == NULL)
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++;
}
- qsort(dents, n, sizeof(*dents), dentcmp);
+ qsort(dents, n, sizeof(*dents), entrycmp);
for (;;) {
int nlines;
- struct dirent *tmpents;
+ struct entry *tmpents;
+ int maxlen;
int odd;
redraw:
@@ -270,9 +290,17 @@ redraw:
/* No text wrapping in entries */
tmpents = malloc(n * sizeof(*tmpents));
- memcpy(tmpents, dents, n * sizeof(*tmpents));
- for (i = 0; i < n; i++)
- tmpents[i].d_name[COLS - strlen(CURSR) - 1] = '\0';
+ maxlen = COLS - strlen(CURSR) - 1;
+ for (i = 0; i < n; i++) {
+ 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
* as an empty string so that when we navigate in /mnt
@@ -287,20 +315,22 @@ redraw:
for (i = 0; i < nlines; i++)
printw("%s%s\n",
i == cur ? CURSR : EMPTY,
- tmpents[i].d_name);
+ tmpents[i].name);
} else if (cur >= n - nlines / 2) {
for (i = n - nlines; i < n; i++)
printw("%s%s\n",
i == cur ? CURSR : EMPTY,
- tmpents[i].d_name);
+ tmpents[i].name);
} else {
for (i = cur - nlines / 2;
i < cur + nlines / 2 + odd; i++)
printw("%s%s\n",
i == cur ? CURSR : EMPTY,
- tmpents[i].d_name);
+ tmpents[i].name);
}
+ for (i = 0; i < n; i++)
+ free(tmpents[i].name);
free(tmpents);
nochange:
@@ -330,13 +360,12 @@ nochange:
char *bin;
pid_t pid;
int fd;
- struct stat sb;
/* Cannot descend in empty directories */
if (n == 0)
goto nochange;
- name = dents[cur].d_name;
+ name = dents[cur].name;
asprintf(&pathnew, "%s/%s", path, name);
@@ -396,6 +425,8 @@ nochange:
}
out:
+ for (i = 0; i < n; i++)
+ free(dents[i].name);
free(dents);
r = closedir(dirp);