summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2018-07-04 15:29:58 +0200
committerAlan Coopersmith <alan.coopersmith@oracle.com>2018-11-12 11:41:47 -0800
commit52a6e57bfd7f273fc754c12a44eb94200f3de0b9 (patch)
treebd85eca8e61b078f19d38c698858fd1a4f2c67b8
parent3e27b6a63f3baf153bba076e12870f2a88691a13 (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.c51
1 files changed, 14 insertions, 37 deletions
diff --git a/xlsatoms.c b/xlsatoms.c
index 5bed0cc..a971901 100644
--- a/xlsatoms.c
+++ b/xlsatoms.c
@@ -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;
}