[PATCH app/xlsatoms 3/3] Always use chunks when retrieving atoms.
Tobias Stoeckmann
tobias at stoeckmann.org
Wed Jul 4 13:29:58 UTC 2018
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 at stoeckmann.org>
---
xlsatoms.c | 51 ++++++++++++++-------------------------------------
1 file 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;
}
--
2.18.0
More information about the xorg-devel
mailing list