diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2018-07-04 15:29:58 +0200 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2018-11-12 11:41:47 -0800 |
commit | 52a6e57bfd7f273fc754c12a44eb94200f3de0b9 (patch) | |
tree | bd85eca8e61b078f19d38c698858fd1a4f2c67b8 | |
parent | 3e27b6a63f3baf153bba076e12870f2a88691a13 (diff) |
Always use chunks when retrieving atoms.
If a low and high range limit has been specified, all atoms are
retrieved at once. This is also the reason why malloc() is used:
All cookies are stored before collecting the data.
By using chunks it is possible to specify a huge range or even
all possible atoms without running out of memory.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | xlsatoms.c | 51 |
1 files changed, 14 insertions, 37 deletions
@@ -234,7 +234,7 @@ do_range(xcb_connection_t *c, const char *format, char *range) } static int -say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, xcb_atom_t low, long count) +say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, xcb_atom_t low, long count, int stop_error) { xcb_generic_error_t *e; char atom_name[1024]; @@ -248,7 +248,7 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c xcb_get_atom_name_reply_t *r; r = xcb_get_atom_name_reply(c, cookie[i], &e); if (r) { - if (!done) { + if (!done || !stop_error) { /* We could just use %.*s in 'format', but we want to be compatible with legacy command line usage */ snprintf(atom_name, sizeof(atom_name), "%.*s", @@ -265,50 +265,27 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c } } - return done; + return done && stop_error; } static void list_atoms(xcb_connection_t *c, const char *format, int mask, xcb_atom_t low, xcb_atom_t high) { - xcb_get_atom_name_cookie_t *cookie_jar; + xcb_get_atom_name_cookie_t cookie_jar[ATOMS_PER_BATCH]; int done = 0; + long count; - switch (mask) { - case RangeHigh: + if ((mask & RangeLow) == 0) low = 1; - /* fall through */ - case (RangeLow | RangeHigh): - if (high - low >= SIZE_MAX / sizeof(xcb_get_atom_name_cookie_t)) { - fprintf(stderr, "Cannot allocate space for %lu atom requests\n", (unsigned long) (high - low)); - return; - } - cookie_jar = malloc((high - low + 1) * sizeof(xcb_get_atom_name_cookie_t)); - if (!cookie_jar) { - fprintf(stderr, "Out of memory allocating space for %lu atom requests\n", (unsigned long) (high - low)); - return; - } + if ((mask & RangeHigh) == 0) + high = UINT32_MAX; - say_batch(c, format, cookie_jar, low, high - low + 1); - free(cookie_jar); - break; - - default: - low = 1; - /* fall through */ - case RangeLow: - cookie_jar = malloc(ATOMS_PER_BATCH * sizeof(xcb_get_atom_name_cookie_t)); - if (!cookie_jar) { - fprintf(stderr, "Out of memory allocating space for %ld atom requests\n", (long) ATOMS_PER_BATCH); - return; - } - while (!done) { - done = say_batch(c, format, cookie_jar, low, ATOMS_PER_BATCH); - low += ATOMS_PER_BATCH; + while (!done) { + count = high - low < ATOMS_PER_BATCH - 1 ? high - low + 1 : ATOMS_PER_BATCH; + done = say_batch(c, format, cookie_jar, low, count, (mask & RangeHigh) == 0); + if (high - low < UINT32_MAX && low == high - count + 1) { + done = 1; } - free(cookie_jar); - break; + low += count; } - - return; } |