Use command line instead of env for passing children
Commit e54361a374
added code so that we pass the list of
currently running children across restart via an environment variable.
As Colin Walters correctly points out, setenv() is not safe in a
multi-threaded processes.
Thus, instead of using the environment, use the command line to pass
this information along.
https://github.com/awesomeWM/awesome/issues/1812
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
d799eea2cf
commit
af8288335b
|
@ -115,8 +115,6 @@ awesome_atexit(bool restart)
|
|||
/* Disconnect *after* closing lua */
|
||||
xcb_cursor_context_free(globalconf.cursor_ctx);
|
||||
xcb_disconnect(globalconf.connection);
|
||||
|
||||
spawn_before_exit(restart);
|
||||
}
|
||||
|
||||
/** Restore the client order after a restart */
|
||||
|
@ -465,7 +463,7 @@ void
|
|||
awesome_restart(void)
|
||||
{
|
||||
awesome_atexit(true);
|
||||
execvp(awesome_argv[0], awesome_argv);
|
||||
execvp(awesome_argv[0], spawn_transform_commandline(awesome_argv));
|
||||
fatal("execv() failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
|
@ -529,6 +527,7 @@ main(int argc, char **argv)
|
|||
{ "search", 1, NULL, 's' },
|
||||
{ "no-argb", 0, NULL, 'a' },
|
||||
{ "replace", 0, NULL, 'r' },
|
||||
{ "reap", 1, NULL, '\1' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -578,6 +577,9 @@ main(int argc, char **argv)
|
|||
case 'r':
|
||||
replace_wm = true;
|
||||
break;
|
||||
case '\1':
|
||||
spawn_handle_reap(optarg);
|
||||
break;
|
||||
default:
|
||||
exit_help(EXIT_FAILURE);
|
||||
break;
|
||||
|
|
63
spawn.c
63
spawn.c
|
@ -291,40 +291,61 @@ spawn_init(void)
|
|||
globalconf.default_screen,
|
||||
spawn_monitor_event,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
const char* children = getenv("AWESOME_RUNNING_CHILDREN");
|
||||
while (children != NULL) {
|
||||
int pid, length;
|
||||
if (sscanf(children, "%d%n", &pid, &length) != 1)
|
||||
break;
|
||||
children += length;
|
||||
if (*children == ',')
|
||||
children++;
|
||||
|
||||
void
|
||||
spawn_handle_reap(const char *arg)
|
||||
{
|
||||
GPid pid = atoll(arg);
|
||||
pid_array_insert(&running_children, pid);
|
||||
g_child_watch_add((GPid) pid, remove_running_child, NULL);
|
||||
}
|
||||
unsetenv("AWESOME_RUNNING_CHILDREN");
|
||||
}
|
||||
|
||||
/** Called right before exit, serialise state in case of a restart.
|
||||
*/
|
||||
void
|
||||
spawn_before_exit(bool restart)
|
||||
char * const *
|
||||
spawn_transform_commandline(char **argv)
|
||||
{
|
||||
if (!restart)
|
||||
return;
|
||||
size_t offset = 0;
|
||||
size_t length = 0;
|
||||
while(argv[offset] != NULL)
|
||||
{
|
||||
if(A_STREQ(argv[offset], "--reap"))
|
||||
offset += 2;
|
||||
else {
|
||||
length++;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
length += 2*running_children.len;
|
||||
|
||||
const char ** transformed = p_new(const char *, length+1);
|
||||
size_t index = 0;
|
||||
offset = 0;
|
||||
while(argv[index + offset] != NULL)
|
||||
{
|
||||
if(A_STREQ(argv[index + offset], "--reap"))
|
||||
offset += 2;
|
||||
else {
|
||||
transformed[index] = argv[index + offset];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(pid, running_children)
|
||||
{
|
||||
buffer_t buffer;
|
||||
buffer_init(&buffer);
|
||||
foreach(pid, running_children) {
|
||||
if(buffer.len != 0)
|
||||
buffer_addc(&buffer, ',');
|
||||
buffer_addf(&buffer, "%d", (int) *pid);
|
||||
}
|
||||
if(buffer.len != 0)
|
||||
setenv("AWESOME_RUNNING_CHILDREN", buffer.s, 1);
|
||||
|
||||
transformed[index++] = "--reap";
|
||||
transformed[index++] = buffer_detach(&buffer);
|
||||
buffer_wipe(&buffer);
|
||||
}
|
||||
transformed[index++] = NULL;
|
||||
|
||||
return (char * const *) transformed;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
Loading…
Reference in New Issue