summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c35
-rw-r--r--src/main.c21
-rw-r--r--src/ratpoison.h4
3 files changed, 42 insertions, 18 deletions
diff --git a/src/actions.c b/src/actions.c
index 67d1289..8f016fe 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -26,6 +26,7 @@
#include <strings.h>
#include <time.h>
#include <errno.h>
+#include <signal.h>
#include "ratpoison.h"
@@ -2405,7 +2406,6 @@ cmd_exec (int interactive, struct cmdarg **args)
int
spawn(char *cmd)
{
- char *tmp;
rp_child_info *child;
int pid;
@@ -2423,9 +2423,7 @@ spawn(char *cmd)
#elif defined (HAVE_SETPGRP)
setpgrp (0, 0);
#endif
- /* Prepend with exec to avoid excess /bin/sh's. */
- tmp = xsprintf ("exec %s", cmd);
- execl("/bin/sh", "sh", "-c", tmp, 0);
+ execl("/bin/sh", "sh", "-c", cmd, 0);
_exit(EXIT_FAILURE);
}
@@ -3290,7 +3288,7 @@ static cmdret *
set_wingravity (struct cmdarg **args)
{
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, wingravity_to_string (defaults.win_gravity));
+ return cmdret_new (RET_SUCCESS, "%s", wingravity_to_string (defaults.win_gravity));
defaults.win_gravity = ARG(0,gravity);
@@ -3301,7 +3299,7 @@ static cmdret *
set_transgravity (struct cmdarg **args)
{
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, wingravity_to_string (defaults.trans_gravity));
+ return cmdret_new (RET_SUCCESS, "%s", wingravity_to_string (defaults.trans_gravity));
defaults.trans_gravity = ARG(0,gravity);
@@ -3312,7 +3310,7 @@ static cmdret *
set_maxsizegravity (struct cmdarg **args)
{
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, wingravity_to_string (defaults.maxsize_gravity));
+ return cmdret_new (RET_SUCCESS, "%s", wingravity_to_string (defaults.maxsize_gravity));
defaults.maxsize_gravity = ARG(0,gravity);
@@ -3340,7 +3338,7 @@ static cmdret *
set_bargravity (struct cmdarg **args)
{
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, wingravity_to_string (defaults.bar_location));
+ return cmdret_new (RET_SUCCESS, "%s", wingravity_to_string (defaults.bar_location));
defaults.bar_location = ARG(0,gravity);
@@ -3382,7 +3380,7 @@ set_font (struct cmdarg **args)
XFontStruct *font;
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, defaults.font_string);
+ return cmdret_new (RET_SUCCESS, "%s", defaults.font_string);
font = XLoadQueryFont (dpy, ARG_STRING(0));
if (font == NULL)
@@ -3535,7 +3533,7 @@ static cmdret *
set_winfmt (struct cmdarg **args)
{
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, defaults.window_fmt);
+ return cmdret_new (RET_SUCCESS, "%s", defaults.window_fmt);
free (defaults.window_fmt);
defaults.window_fmt = xstrdup (ARG_STRING(0));
@@ -3585,7 +3583,7 @@ set_fgcolor (struct cmdarg **args)
XColor color, junk;
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, defaults.fgcolor_string);
+ return cmdret_new (RET_SUCCESS, "%s", defaults.fgcolor_string);
for (i=0; i<num_screens; i++)
{
@@ -3613,7 +3611,7 @@ set_bgcolor (struct cmdarg **args)
XColor color, junk;
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, defaults.bgcolor_string);
+ return cmdret_new (RET_SUCCESS, "%s", defaults.bgcolor_string);
for (i=0; i<num_screens; i++)
{
@@ -4154,6 +4152,9 @@ cmd_tmpwm (int interactive, struct cmdarg **args)
XUnmapWindow (dpy, screens[i].key_window);
}
+ /* Ungrab all our keys. */
+ ungrab_keys_all_wins();
+
/* Don't listen for any events from any window. */
list_for_each_safe_entry (win, iter, tmp, &rp_mapped_window, node)
{
@@ -4167,12 +4168,20 @@ cmd_tmpwm (int interactive, struct cmdarg **args)
XSync (dpy, False);
+ /* Disable our SIGCHLD handler */
+ set_sig_handler (SIGCHLD, SIG_IGN);
/* Launch the new WM and wait for it to terminate. */
pid = spawn (ARG_STRING(0));
+ PRINT_DEBUG (("spawn pid: %d\n", pid));
do
{
child = waitpid (pid, &status, 0);
} while (child != pid);
+ /* Enable our SIGCHLD handler */
+ set_sig_handler (SIGCHLD, chld_handler);
+ /* Some processes may have quit while our sigchld handler was
+ disabled, so check for them. */
+ check_child_procs();
/* This xsync seems to be needed. Otherwise, the following code dies
because X thinks another WM is running. */
@@ -4701,7 +4710,7 @@ static cmdret *
set_framesels (struct cmdarg **args)
{
if (args[0] == NULL)
- return cmdret_new (RET_SUCCESS, defaults.frame_selectors);
+ return cmdret_new (RET_SUCCESS, "%s", defaults.frame_selectors);
free (defaults.frame_selectors);
defaults.frame_selectors = xstrdup (ARG_STRING(0));
diff --git a/src/main.c b/src/main.c
index 32f28e5..365985c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -181,14 +181,13 @@ alrm_handler (int signum)
alarm_signalled++;
}
+/* Check for child processes that have quit but haven't been
+ acknowledged yet. Update their structure. */
void
-chld_handler (int signum)
+check_child_procs ()
{
rp_child_info *cur;
- int pid, status, serrno;
-
- serrno = errno;
-
+ int pid, status;
while (1)
{
pid = waitpid (WAIT_ANY, &status, WNOHANG);
@@ -210,6 +209,15 @@ chld_handler (int signum)
chld_signalled = 1;
}
+}
+
+void
+chld_handler (int signum)
+{
+ int serrno;
+
+ serrno = errno;
+ check_child_procs();
errno = serrno;
}
@@ -681,6 +689,9 @@ free_screen (rp_screen *s)
rp_frame *frame;
struct list_head *iter, *tmp;
+ /* Relinquish our hold on the root window. */
+ XSelectInput(dpy, RootWindow (dpy, s->screen_num), 0);
+
list_for_each_safe_entry (frame, iter, tmp, &s->frames, node)
{
frame_free (s, frame);
diff --git a/src/ratpoison.h b/src/ratpoison.h
index 1c84bb4..448e021 100644
--- a/src/ratpoison.h
+++ b/src/ratpoison.h
@@ -101,5 +101,9 @@ char *xstrdup (char *s);
char *xsprintf (char *fmt, ...);
char *xvsprintf (char *fmt, va_list ap);
int str_comp (char *s1, char *s2, int len);
+/* Needed in cmd_tmpwm */
+void check_child_procs ();
+void chld_handler (int signum);
+void set_sig_handler (int sig, void (*action)(int));
#endif /* ! _RATPOISON_H */