Introduction
Introduction Statistics Contact Development Disclaimer Help
noice: No need to perform so many memory allocations - noice - small file brows…
git clone git://git.codemadness.org/noice
Log
Files
Refs
README
LICENSE
---
commit 65fae61bea713e004b7698cb424fa2a24847b40d
parent 6d4166f0d6b67bbaecb57cdf821d28f4356ae67f
Author: sin <[email protected]>
Date: Thu, 7 Jan 2016 10:26:44 +0000
noice: No need to perform so many memory allocations
The code was quite fragile. As a first pass, use buffers of size
PATH_MAX and LINE_MAX accordingly until we simplify the overall logic.
Diffstat:
M noice.c | 140 ++++++++++++-----------------…
1 file changed, 55 insertions(+), 85 deletions(-)
---
diff --git a/noice.c b/noice.c
@@ -74,7 +74,7 @@ struct key {
#include "config.h"
struct entry {
- char *name;
+ char name[PATH_MAX];
mode_t mode;
time_t t;
};
@@ -82,8 +82,8 @@ struct entry {
/* Global context */
struct entry *dents;
int n, cur;
-char *path, *oldpath;
-char *fltr;
+char path[PATH_MAX], oldpath[PATH_MAX];
+char fltr[LINE_MAX];
int idle;
/*
@@ -106,7 +106,7 @@ int idle;
void printmsg(char *);
void printwarn(void);
void printerr(int, char *);
-char *mkpath(char *, char *);
+char *mkpath(char *, char *, char *, size_t);
#undef dprintf
int
@@ -155,20 +155,20 @@ xstrdup(const char *s)
return p;
}
+/* Some implementations of dirname(3) may modify `path' and some
+ * return a pointer inside `path'. */
char *
xdirname(const char *path)
{
+ static char out[PATH_MAX];
char tmp[PATH_MAX], *p;
- /* Some implementations of dirname(3) may modify `path' and some
- * return a pointer inside `path' and we cannot free(3) the
- * original string if we lose track of it. */
strlcpy(tmp, path, sizeof(tmp));
p = dirname(tmp);
if (p == NULL)
printerr(1, "dirname");
- /* Make sure this is a malloc(3)-ed string */
- return xstrdup(p);
+ strlcpy(out, p, sizeof(out));
+ return out;
}
void
@@ -226,15 +226,17 @@ openwith(char *file)
int
setfilter(regex_t *regex, char *filter)
{
- char *errbuf;
+ char errbuf[LINE_MAX];
+ size_t len;
int r;
r = regcomp(regex, filter, REG_NOSUB | REG_EXTENDED | REG_ICASE);
if (r != 0) {
- errbuf = xmalloc(COLS);
- regerror(r, regex, errbuf, COLS);
+ len = COLS;
+ if (len > sizeof(errbuf))
+ len = sizeof(errbuf);
+ regerror(r, regex, errbuf, len);
printmsg(errbuf);
- free(errbuf);
}
return r;
@@ -461,10 +463,10 @@ int
dentfill(char *path, struct entry **dents,
int (*filter)(regex_t *, char *), regex_t *re)
{
+ char newpath[PATH_MAX];
DIR *dirp;
struct dirent *dp;
struct stat sb;
- char *newpath;
int r, n = 0;
dirp = opendir(path);
@@ -479,13 +481,12 @@ dentfill(char *path, struct entry **dents,
if (filter(re, dp->d_name) == 0)
continue;
*dents = xrealloc(*dents, (n + 1) * sizeof(**dents));
- (*dents)[n].name = xstrdup(dp->d_name);
+ strlcpy((*dents)[n].name, dp->d_name, sizeof((*dents)[n].name)…
/* Get mode flags */
- newpath = mkpath(path, dp->d_name);
+ mkpath(path, dp->d_name, newpath, sizeof(newpath));
r = lstat(newpath, &sb);
if (r == -1)
printerr(1, "lstat");
- free(newpath);
(*dents)[n].mode = sb.st_mode;
(*dents)[n].t = sb.st_mtime;
n++;
@@ -500,58 +501,47 @@ dentfill(char *path, struct entry **dents,
}
void
-dentfree(struct entry *dents, int n)
+dentfree(struct entry *dents)
{
- int i;
-
- for (i = 0; i < n; i++)
- free(dents[i].name);
free(dents);
}
char *
-mkpath(char *dir, char *name)
+mkpath(char *dir, char *name, char *out, size_t n)
{
- char path[PATH_MAX];
-
/* Handle absolute path */
if (name[0] == '/') {
- strlcpy(path, name, sizeof(path));
+ strlcpy(out, name, n);
} else {
/* Handle root case */
if (strcmp(dir, "/") == 0) {
- strlcpy(path, "/", sizeof(path));
- strlcat(path, name, sizeof(path));
+ strlcpy(out, "/", n);
+ strlcat(out, name, n);
} else {
- strlcpy(path, dir, sizeof(path));
- strlcat(path, "/", sizeof(path));
- strlcat(path, name, sizeof(path));
+ strlcpy(out, dir, n);
+ strlcat(out, "/", n);
+ strlcat(out, name, n);
}
}
- return xstrdup(path);
+ return out;
}
/* Return the position of the matching entry or 0 otherwise */
int
dentfind(struct entry *dents, int n, char *cwd, char *path)
{
+ char tmp[PATH_MAX];
int i;
- char *tmp;
if (path == NULL)
return 0;
-
for (i = 0; i < n; i++) {
- tmp = mkpath(cwd, dents[i].name);
+ mkpath(cwd, dents[i].name, tmp, sizeof(tmp));
DPRINTF_S(path);
DPRINTF_S(tmp);
- if (strcmp(tmp, path) == 0) {
- free(tmp);
+ if (strcmp(tmp, path) == 0)
return i;
- }
- free(tmp);
}
-
return 0;
}
@@ -570,7 +560,7 @@ populate(void)
if (r != 0)
return -1;
- dentfree(dents, n);
+ dentfree(dents);
n = 0;
dents = NULL;
@@ -581,9 +571,6 @@ populate(void)
/* Find cur from history */
cur = dentfind(dents, n, path, oldpath);
- free(oldpath);
- oldpath = NULL;
-
return 0;
}
@@ -638,18 +625,16 @@ redraw(void)
void
browse(const char *ipath, const char *ifilter)
{
- int r, fd;
- regex_t re;
- char *newpath;
- struct stat sb;
+ char newpath[PATH_MAX];
char *name, *bin, *dir, *tmp, *run, *env;
+ struct stat sb;
+ regex_t re;
+ int r, fd;
int nowtyping = 0;
- oldpath = NULL;
- path = xstrdup(ipath);
- fltr = xstrdup(ifilter);
+ strlcpy(path, ipath, sizeof(path));
+ strlcpy(fltr, ifilter, sizeof(fltr));
begin:
- /* Path and filter should be malloc(3)-ed strings at all times */
r = populate();
if (r == -1) {
if (!nowtyping) {
@@ -667,9 +652,7 @@ begin:
nochange:
switch (nextsel(&run, &env)) {
case SEL_QUIT:
- free(path);
- free(fltr);
- dentfree(dents, n);
+ dentfree(dents);
return;
case SEL_BACK:
/* There is no going back */
@@ -679,16 +662,14 @@ nochange:
goto nochange;
dir = xdirname(path);
if (canopendir(dir) == 0) {
- free(dir);
printwarn();
goto nochange;
}
/* Save history */
- oldpath = path;
- path = dir;
+ strlcpy(oldpath, path, sizeof(path));
+ strlcpy(path, dir, sizeof(path));
/* Reset filter */
- free(fltr);
- fltr = xstrdup(ifilter);
+ strlcpy(fltr, ifilter, sizeof(fltr));
goto begin;
case SEL_GOIN:
/* Cannot descend in empty directories */
@@ -696,21 +677,19 @@ nochange:
goto nochange;
name = dents[cur].name;
- newpath = mkpath(path, name);
+ mkpath(path, name, newpath, sizeof(newpath));
DPRINTF_S(newpath);
/* Get path info */
fd = open(newpath, O_RDONLY | O_NONBLOCK);
if (fd == -1) {
printwarn();
- free(newpath);
goto nochange;
}
r = fstat(fd, &sb);
if (r == -1) {
printwarn();
close(fd);
- free(newpath);
goto nochange;
}
close(fd);
@@ -720,26 +699,21 @@ nochange:
case S_IFDIR:
if (canopendir(newpath) == 0) {
printwarn();
- free(newpath);
goto nochange;
}
- free(path);
- path = newpath;
+ strlcpy(path, newpath, sizeof(path));
/* Reset filter */
- free(fltr);
- fltr = xstrdup(ifilter);
+ strlcpy(fltr, ifilter, sizeof(fltr));
goto begin;
case S_IFREG:
bin = openwith(newpath);
if (bin == NULL) {
printmsg("No association");
- free(newpath);
goto nochange;
}
exitcurses();
spawn(bin, newpath, NULL);
initcurses();
- free(newpath);
continue;
default:
printmsg("Unsupported file");
@@ -757,12 +731,11 @@ nochange:
free(tmp);
goto nochange;
}
- free(fltr);
- fltr = tmp;
+ strlcpy(fltr, tmp, sizeof(fltr));
DPRINTF_S(fltr);
/* Save current */
if (n > 0)
- oldpath = mkpath(path, dents[cur].name);
+ mkpath(path, dents[cur].name, oldpath, sizeof(…
goto begin;
case SEL_TYPE:
nowtyping = 1;
@@ -788,14 +761,13 @@ moretyping:
}
}
/* Copy or reset filter */
- free(fltr);
if (tmp != NULL)
- fltr = xstrdup(tmp);
+ strlcpy(fltr, tmp, sizeof(fltr));
else
- fltr = xstrdup(ifilter);
+ strlcpy(fltr, ifilter, sizeof(fltr));
/* Save current */
if (n > 0)
- oldpath = mkpath(path, dents[cur].name);
+ mkpath(path, dents[cur].name, oldpath, sizeof(…
if (!nowtyping)
free(tmp);
goto begin;
@@ -829,29 +801,27 @@ moretyping:
clearprompt();
goto nochange;
}
- newpath = mkpath(path, tmp);
+ mkpath(path, tmp, newpath, sizeof(newpath));
free(tmp);
if (canopendir(newpath) == 0) {
- free(newpath);
printwarn();
goto nochange;
}
- free(path);
- path = newpath;
- free(fltr);
- fltr = xstrdup(ifilter); /* Reset filter */
+ strlcpy(path, newpath, sizeof(path));
+ /* Reset filter */
+ strlcpy(fltr, ifilter, sizeof(fltr))
DPRINTF_S(path);
goto begin;
case SEL_MTIME:
mtimeorder = !mtimeorder;
/* Save current */
if (n > 0)
- oldpath = mkpath(path, dents[cur].name);
+ mkpath(path, dents[cur].name, oldpath, sizeof(…
goto begin;
case SEL_REDRAW:
/* Save current */
if (n > 0)
- oldpath = mkpath(path, dents[cur].name);
+ mkpath(path, dents[cur].name, oldpath, sizeof(…
goto begin;
case SEL_RUN:
run = xgetenv(env, run);
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.