summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiltjo Posthuma <hiltjo@codemadness.org>2023-03-08 21:20:52 +0100
committerRafael Marçalo <raroma09@gmail.com>2023-03-10 13:18:28 +0000
commitef8a3a73913a2ff294682612f1512891aae76252 (patch)
tree2a5867df033113b40ef128e855bcb745899e9533
parentb5f961fb13ee39724e5fcbff5d3d2a81669586bf (diff)
readstdin: reduce memory-usage by duplicating the line from getline()
Improves upon commit 32db2b125190d366be472ccb7cad833248696144 The getline() implementation often uses a more greedy way of allocating memory. Using this buffer directly and forcing an allocation (by setting it to NULL) would waste a bit of extra space, depending on the implementation of course. Tested on musl libc and glibc. The current glibc version allocates a minimum of 120 bytes per line. For smaller lines musl libc seems less wasteful but still wastes a few bytes per line. On a dmenu_path listing on my system the memory usage was about 350kb (old) vs 30kb (new) on Void Linux glibc. Side-note that getline() also reads NUL bytes in lines, while strdup() would read until the NUL byte. Since dmenu reads text lines either is probably fine(tm). Also rename junk to linesiz.
-rw-r--r--dmenu.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/dmenu.c b/dmenu.c
index 721ec45..5e4fe3e 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -557,7 +557,7 @@ static void
readstdin(void)
{
char *line = NULL;
- size_t i, junk, itemsiz = 0;
+ size_t i, itemsiz = 0, linesiz = 0;
ssize_t len;
if(passwd){
inputw = lines = 0;
@@ -565,7 +565,7 @@ readstdin(void)
}
/* read each line from stdin and add it to the item list */
- for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) {
+ for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) {
if (i + 1 >= itemsiz) {
itemsiz += 256;
if (!(items = realloc(items, itemsiz * sizeof(*items))))
@@ -573,9 +573,10 @@ readstdin(void)
}
if (line[len - 1] == '\n')
line[len - 1] = '\0';
- items[i].text = line;
+ if (!(items[i].text = strdup(line)))
+ die("strdup:");
+
items[i].out = 0;
- line = NULL; /* next call of getline() allocates a new line */
}
free(line);
if (items)