On execwm, we should properly release resources before exec'ing into a

new window manager; so allow CWM_EXEC_WM to assign new wm to wm_argv and
pass through cwm_status (now EXECWM) so that x_teardown() gets called
before exec'ing the new window manager.  Removes the need for a separate
x_restart() now, using new wm_argv; and consolidates errno for execvp.
This commit is contained in:
okan 2015-09-16 17:58:25 +00:00
parent 47a10cc055
commit 0fdcf3f3df
5 changed files with 39 additions and 20 deletions

View File

@ -46,12 +46,12 @@ struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
int HasRandr, Randr_ev; int HasRandr, Randr_ev;
struct conf Conf; struct conf Conf;
const char *homedir; const char *homedir;
char *wm_argv;
volatile sig_atomic_t cwm_status; volatile sig_atomic_t cwm_status;
static void sighdlr(int); static void sighdlr(int);
static int x_errorhandler(Display *, XErrorEvent *); static int x_errorhandler(Display *, XErrorEvent *);
static void x_init(const char *); static void x_init(const char *);
static void x_restart(char **);
static void x_teardown(void); static void x_teardown(void);
static int x_wmerrorhandler(Display *, XErrorEvent *); static int x_wmerrorhandler(Display *, XErrorEvent *);
@ -60,7 +60,6 @@ main(int argc, char **argv)
{ {
const char *conf_file = NULL; const char *conf_file = NULL;
char *conf_path, *display_name = NULL; char *conf_path, *display_name = NULL;
char **cwm_argv;
int ch; int ch;
struct passwd *pw; struct passwd *pw;
@ -68,7 +67,7 @@ main(int argc, char **argv)
warnx("no locale support"); warnx("no locale support");
mbtowc(NULL, NULL, MB_CUR_MAX); mbtowc(NULL, NULL, MB_CUR_MAX);
cwm_argv = argv; wm_argv = u_argv(argv);
while ((ch = getopt(argc, argv, "c:d:")) != -1) { while ((ch = getopt(argc, argv, "c:d:")) != -1) {
switch (ch) { switch (ch) {
case 'c': case 'c':
@ -117,8 +116,8 @@ main(int argc, char **argv)
while (cwm_status == CWM_RUNNING) while (cwm_status == CWM_RUNNING)
xev_process(); xev_process();
x_teardown(); x_teardown();
if (cwm_status == CWM_RESTART) if (cwm_status == CWM_EXECWM)
x_restart(cwm_argv); u_exec(wm_argv);
return(0); return(0);
} }
@ -145,13 +144,6 @@ x_init(const char *dpyname)
screen_init(i); screen_init(i);
} }
static void
x_restart(char **args)
{
(void)setsid();
(void)execvp(args[0], args);
}
static void static void
x_teardown(void) x_teardown(void)
{ {

View File

@ -88,7 +88,7 @@
#define CWM_QUIT 0x0000 #define CWM_QUIT 0x0000
#define CWM_RUNNING 0x0001 #define CWM_RUNNING 0x0001
#define CWM_RESTART 0x0002 #define CWM_EXECWM 0x0002
union arg { union arg {
char *c; char *c;
@ -334,6 +334,7 @@ extern Display *X_Dpy;
extern Time Last_Event_Time; extern Time Last_Event_Time;
extern struct screen_ctx_q Screenq; extern struct screen_ctx_q Screenq;
extern struct conf Conf; extern struct conf Conf;
extern char *wm_argv;
extern const char *homedir; extern const char *homedir;
extern int HasRandr, Randr_ev; extern int HasRandr, Randr_ev;
@ -581,6 +582,7 @@ void xu_ewmh_handle_net_wm_state_msg(struct client_ctx *,
void xu_ewmh_set_net_wm_state(struct client_ctx *); void xu_ewmh_set_net_wm_state(struct client_ctx *);
void xu_ewmh_restore_net_wm_state(struct client_ctx *); void xu_ewmh_restore_net_wm_state(struct client_ctx *);
char *u_argv(char * const *);
void u_exec(char *); void u_exec(char *);
void u_spawn(char *); void u_spawn(char *);

2
conf.c
View File

@ -400,7 +400,7 @@ static const struct {
{ "vmaximize", kbfunc_client_toggle_vmaximize, CWM_WIN, {0} }, { "vmaximize", kbfunc_client_toggle_vmaximize, CWM_WIN, {0} },
{ "hmaximize", kbfunc_client_toggle_hmaximize, CWM_WIN, {0} }, { "hmaximize", kbfunc_client_toggle_hmaximize, CWM_WIN, {0} },
{ "freeze", kbfunc_client_toggle_freeze, CWM_WIN, {0} }, { "freeze", kbfunc_client_toggle_freeze, CWM_WIN, {0} },
{ "restart", kbfunc_cwm_status, 0, {.i = CWM_RESTART} }, { "restart", kbfunc_cwm_status, 0, {.i = CWM_EXECWM} },
{ "quit", kbfunc_cwm_status, 0, {.i = CWM_QUIT} }, { "quit", kbfunc_cwm_status, 0, {.i = CWM_QUIT} },
{ "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} }, { "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} },
{ "exec_wm", kbfunc_exec, 0, {.i = CWM_EXEC_WM} }, { "exec_wm", kbfunc_exec, 0, {.i = CWM_EXEC_WM} },

View File

@ -325,8 +325,9 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
u_spawn(mi->text); u_spawn(mi->text);
break; break;
case CWM_EXEC_WM: case CWM_EXEC_WM:
u_exec(mi->text); cwm_status = CWM_EXECWM;
warn("%s", mi->text); free(wm_argv);
wm_argv = xstrdup(mi->text);
break; break;
default: default:
errx(1, "kb_func: egad, cmd changed value!"); errx(1, "kb_func: egad, cmd changed value!");

32
util.c
View File

@ -31,15 +31,12 @@
#include "calmwm.h" #include "calmwm.h"
#define MAXARGLEN 20
void void
u_spawn(char *argstr) u_spawn(char *argstr)
{ {
switch (fork()) { switch (fork()) {
case 0: case 0:
u_exec(argstr); u_exec(argstr);
err(1, "%s", argstr);
break; break;
case -1: case -1:
warn("fork"); warn("fork");
@ -51,8 +48,10 @@ u_spawn(char *argstr)
void void
u_exec(char *argstr) u_exec(char *argstr)
{ {
#define MAXARGLEN 20
char *args[MAXARGLEN], **ap = args; char *args[MAXARGLEN], **ap = args;
char **end = &args[MAXARGLEN - 1], *tmp; char **end = &args[MAXARGLEN - 1], *tmp;
char *s = argstr;
while (ap < end && (*ap = strsep(&argstr, " \t")) != NULL) { while (ap < end && (*ap = strsep(&argstr, " \t")) != NULL) {
if (**ap == '\0') if (**ap == '\0')
@ -75,8 +74,33 @@ u_exec(char *argstr)
} }
} }
} }
*ap = NULL; *ap = NULL;
(void)setsid(); (void)setsid();
(void)execvp(args[0], args); (void)execvp(args[0], args);
err(1, "%s", s);
}
char *
u_argv(char * const *argv)
{
size_t siz = 0;
int i;
char *p;
if (argv == 0)
return(NULL);
for (i = 0; argv[i]; i++)
siz += strlen(argv[i]) + 1;
if (siz == 0)
return(NULL);
p = xmalloc(siz);
strlcpy(p, argv[0], siz);
for (i = 1; argv[i]; i++) {
strlcat(p, " ", siz);
strlcat(p, argv[i], siz);
}
return(p);
} }