From 82e39df891c261352a86f0d94898a23a8d5a4d31 Mon Sep 17 00:00:00 2001 From: sabetts Date: Wed, 9 Apr 2003 22:56:15 +0000 Subject: (receive_command): handle the case when more than one client requests a command (fix infinite loop bug). --- ChangeLog | 5 ++++ NEWS | 2 ++ src/events.c | 80 ++++++++++++++++++++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40d8a6c..5ce4951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-04-09 Shawn Betts + + * src/events.c (receive_command): handle the case when more than + one client requests a command (fix infinite loop bug). + 2003-04-08 Shawn Betts * src/main.c (WAIT_ANY): define it if it isn't already define. diff --git a/NEWS b/NEWS index c6188a8..b487346 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ ratpoison NEWS --- history of user-visible changes. -*- outline -*- +* Changes since 1.2.0-beta2 + * Changes since 1.1.1 ** new comand 'defwrapwinlist' when turned on, the window list is displayed in a column, not a row. diff --git a/src/events.c b/src/events.c index 5241977..9960e5a 100644 --- a/src/events.c +++ b/src/events.c @@ -487,44 +487,66 @@ receive_command () unsigned long nitems; unsigned long bytes_after; void *prop_return; + int offset; + /* Init offset to 0. In the case where there is more than one window + in the property, a partial read does not delete the property and + we need to grab the next window by incementing offset to the + offset of the next window. */ + offset = 0; do { - if (XGetWindowProperty (dpy, DefaultRootWindow (dpy), - rp_command_request, 0, - sizeof (Window) / 4 + (sizeof (Window) % 4 ?1:0), - True, XA_WINDOW, &type_ret, &format_ret, &nitems, - &bytes_after, (unsigned char **)&prop_return) == Success) + int ret; + int length; + Window w; + + length = sizeof (Window) / 4 + (sizeof (Window) % 4 ?1:0); + ret = XGetWindowProperty (dpy, DefaultRootWindow (dpy), + rp_command_request, + offset, length, + True, XA_WINDOW, &type_ret, &format_ret, + &nitems, + &bytes_after, (unsigned char **)&prop_return); + + /* Update the offset to point to the next window (if there is + another one). */ + offset += length; + + if (ret != Success) { + PRINT_ERROR (("XGetWindowProperty Failed\n")); if (prop_return) - { - Window w; + XFree (prop_return); + break; + } - w = *(Window *)prop_return; - XFree (prop_return); + /* If there was no window, then we're done. */ + if (prop_return == NULL) + { + PRINT_DEBUG (("No property to read\n")); + break; + } - result = execute_remote_command (w); - if (result) - { - XChangeProperty (dpy, w, rp_command_result, XA_STRING, - 8, PropModeReplace, result, strlen (result)); - free (result); - } - else - { - XChangeProperty (dpy, w, rp_command_result, XA_STRING, - 8, PropModeReplace, NULL, 0); - } - } - else - { - PRINT_DEBUG (("Couldn't get RP_COMMAND_REQUEST Property\n")); - } + /* We grabbed a window, so now find read the command stored in + this window and execute it. */ + w = *(Window *)prop_return; + XFree (prop_return); + result = execute_remote_command (w); - PRINT_DEBUG (("command requests: %ld\n", nitems)); + /* notify the client of any text that was returned by the + command. */ + if (result) + { + XChangeProperty (dpy, w, rp_command_result, XA_STRING, + 8, PropModeReplace, result, strlen (result)); + free (result); + } + else + { + XChangeProperty (dpy, w, rp_command_result, XA_STRING, + 8, PropModeReplace, NULL, 0); } - } while (nitems > 0); - + } while (bytes_after > 0); } static void -- cgit v1.2.3