summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémie Courrèges-Anglas <jca@wxcvbn.org>2013-02-22 19:08:11 +0100
committerJérémie Courrèges-Anglas <jca@wxcvbn.org>2013-02-22 19:21:35 +0100
commitc58386717db86dc7f5e954d2c972c8d606044bb1 (patch)
tree2a82ac0b04e9871ca019059d58214f29183118de
parentf42b5f6fcb244d9b5ad159113cd921c7f69d6134 (diff)
downloadratpoison-c58386717db86dc7f5e954d2c972c8d606044bb1.zip
make ratpoison -c provide a useful exit status
* properly define the way the wm may give feedback to ratpoison -c; see communications.c:receive_command_result() * follow this protocol in events.c:receive_command() * modify receive_command_result() to return an int (which is the mirror of the struct cmdret "success" member used on the wm side) * pass that error status back to main.c; exit with an error status if any of the commands we sent failed
-rw-r--r--src/communications.c66
-rw-r--r--src/events.c7
-rw-r--r--src/main.c15
3 files changed, 54 insertions, 34 deletions
diff --git a/src/communications.c b/src/communications.c
index 0b50c9e..be406e6 100644
--- a/src/communications.c
+++ b/src/communications.c
@@ -31,10 +31,11 @@
/* Sending commands to ratpoison */
-static void
+static int
receive_command_result (Window w)
{
- int status;
+ int query;
+ int return_status = RET_FAILURE;
Atom type_ret;
int format_ret;
unsigned long nitems;
@@ -42,16 +43,16 @@ receive_command_result (Window w)
unsigned char *result = NULL;
/* First, find out how big the property is. */
- status = XGetWindowProperty (dpy, w, rp_command_result,
- 0, 0, False, xa_string,
- &type_ret, &format_ret, &nitems, &bytes_after,
- &result);
+ query = XGetWindowProperty (dpy, w, rp_command_result,
+ 0, 0, False, xa_string,
+ &type_ret, &format_ret, &nitems, &bytes_after,
+ &result);
/* Failed to retrieve property. */
- if (status != Success || result == NULL)
+ if (query != Success || result == NULL)
{
PRINT_DEBUG (("failed to get command result length\n"));
- return;
+ return return_status;
}
/* XGetWindowProperty always allocates one extra byte even if
@@ -60,36 +61,53 @@ receive_command_result (Window w)
/* Now that we have the length of the message, we can get the
whole message. */
- status = XGetWindowProperty (dpy, w, rp_command_result,
- 0, (bytes_after / 4) + (bytes_after % 4 ? 1 : 0),
- True, xa_string, &type_ret, &format_ret, &nitems,
- &bytes_after, &result);
+ query = XGetWindowProperty (dpy, w, rp_command_result,
+ 0, (bytes_after / 4) + (bytes_after % 4 ? 1 : 0),
+ True, xa_string, &type_ret, &format_ret, &nitems,
+ &bytes_after, &result);
/* Failed to retrieve property. */
- if (status != Success || result == NULL)
+ if (query != Success || result == NULL)
{
PRINT_DEBUG (("failed to get command result\n"));
- return;
+ return return_status;
}
- /* If result is not the empty string, print it. */
- if (strlen ((char *)result))
+ /*
+ * We can receive:
+ * - an empty string, indicating a success but no output
+ * - a string starting with '0', indicating a success and an output
+ * - a string starting with '1', indicating a failure and an optional output
+ */
+ switch (result[0])
{
- if (result[0] == '1')
- printf ("%s\n", &result[1]);
- else
- fprintf (stderr, "%s\n", &result[1]);
+ case '\0': /* Command succeeded but no string to print */
+ return_status = RET_SUCCESS;
+ break;
+ case '0': /* Command failed, don't print an empty line if no explanation
+ was given */
+ if (result[1] != '\0')
+ fprintf (stderr, "%s\n", &result[1]);
+ return_status = RET_FAILURE;
+ break;
+ case '1': /* Command succeeded, print the output */
+ printf ("%s\n", &result[1]);
+ return_status = RET_SUCCESS;
+ default: /* We probably got junk, so ignore it */
+ return_status = RET_FAILURE;
}
/* Free the result. */
XFree (result);
+
+ return return_status;
}
int
send_command (unsigned char interactive, unsigned char *cmd, int screen_num)
{
Window w, root;
- int done = 0;
+ int done = 0, return_status = RET_FAILURE;
struct sbuf *s;
s = sbuf_new(0);
@@ -125,12 +143,12 @@ send_command (unsigned char interactive, unsigned char *cmd, int screen_num)
if (ev.xproperty.atom == rp_command_result
&& ev.xproperty.state == PropertyNewValue)
{
- receive_command_result(ev.xproperty.window);
- done = 1;
+ return_status = receive_command_result(ev.xproperty.window);
+ done = 1;
}
}
XDestroyWindow (dpy, w);
- return 1;
+ return return_status;
}
diff --git a/src/events.c b/src/events.c
index 816d7b7..7ca9cb7 100644
--- a/src/events.c
+++ b/src/events.c
@@ -567,11 +567,14 @@ receive_command (Window root)
cmd_ret = execute_remote_command (w);
/* notify the client of any text that was returned by the
- command. */
+ command. see communications.c:receive_command_result() */
if (cmd_ret->output)
result = xsprintf ("%c%s", cmd_ret->success ? '1':'0', cmd_ret->output);
+ else if (!cmd_ret->success)
+ result = xstrdup("0");
else
- result = NULL;
+ result = NULL;
+
if (result)
XChangeProperty (dpy, w, rp_command_result, xa_string,
8, PropModeReplace, (unsigned char *)result, strlen (result));
diff --git a/src/main.c b/src/main.c
index ce90847..44cb2e3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -680,21 +680,20 @@ main (int argc, char *argv[])
if (cmd_count > 0)
{
- int j;
+ int j, screen, exit_status = EXIT_SUCCESS;
- for (j=0; j<cmd_count; j++)
- {
- if (screen_arg)
- send_command (interactive, (unsigned char *)cmd[j], screen_num);
- else
- send_command (interactive, (unsigned char *)cmd[j], -1);
+ screen = screen_arg ? screen_num : -1;
+ for (j = 0; j < cmd_count; j++)
+ {
+ if (!send_command (interactive, (unsigned char *)cmd[j], screen))
+ exit_status = EXIT_FAILURE;
free (cmd[j]);
}
free (cmd);
XCloseDisplay (dpy);
- return EXIT_SUCCESS;
+ return exit_status;
}
/* Set our Atoms */