2021-09-24 21:45:48 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2020-12-29 18:08:35 +00:00
|
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
|
#include <assert.h>
|
2020-06-19 22:00:22 +01:00
|
|
|
#include <glib.h>
|
2020-12-29 18:08:35 +00:00
|
|
|
#include <signal.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
#include <unistd.h>
|
2021-07-23 21:15:55 +01:00
|
|
|
#include <wlr/util/log.h>
|
2020-12-29 18:08:35 +00:00
|
|
|
#include "common/spawn.h"
|
2020-06-19 22:00:22 +01:00
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
|
|
|
|
spawn_async_no_shell(char const *command)
|
2020-06-19 22:00:22 +01:00
|
|
|
{
|
|
|
|
|
GError *err = NULL;
|
|
|
|
|
gchar **argv = NULL;
|
|
|
|
|
|
2020-12-29 18:08:35 +00:00
|
|
|
assert(command);
|
|
|
|
|
|
|
|
|
|
/* Use glib's shell-parse to mimic Openbox's behaviour */
|
2020-06-19 22:00:22 +01:00
|
|
|
g_shell_parse_argv((gchar *)command, NULL, &argv, &err);
|
|
|
|
|
if (err) {
|
|
|
|
|
g_message("%s", err->message);
|
|
|
|
|
g_error_free(err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-12-29 18:08:35 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Avoid zombie processes by using a double-fork, whereby the
|
|
|
|
|
* grandchild becomes orphaned & the responsibility of the OS.
|
|
|
|
|
*/
|
|
|
|
|
pid_t child = 0, grandchild = 0;
|
|
|
|
|
|
|
|
|
|
child = fork();
|
|
|
|
|
switch (child) {
|
|
|
|
|
case -1:
|
2021-07-23 21:15:55 +01:00
|
|
|
wlr_log(WLR_ERROR, "unable to fork()");
|
2020-12-29 18:08:35 +00:00
|
|
|
goto out;
|
|
|
|
|
case 0:
|
|
|
|
|
setsid();
|
|
|
|
|
sigset_t set;
|
|
|
|
|
sigemptyset(&set);
|
|
|
|
|
sigprocmask(SIG_SETMASK, &set, NULL);
|
|
|
|
|
grandchild = fork();
|
|
|
|
|
if (grandchild == 0) {
|
|
|
|
|
execvp(argv[0], argv);
|
2021-02-15 17:57:20 +00:00
|
|
|
_exit(0);
|
2020-12-29 18:08:35 +00:00
|
|
|
} else if (grandchild < 0) {
|
2021-07-23 21:15:55 +01:00
|
|
|
wlr_log(WLR_ERROR, "unable to fork()");
|
2020-12-29 18:08:35 +00:00
|
|
|
}
|
2021-02-15 17:57:20 +00:00
|
|
|
_exit(0);
|
2020-12-29 18:08:35 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-06-19 22:00:22 +01:00
|
|
|
}
|
2020-12-29 18:08:35 +00:00
|
|
|
waitpid(child, NULL, 0);
|
|
|
|
|
out:
|
2020-06-19 22:00:22 +01:00
|
|
|
g_strfreev(argv);
|
|
|
|
|
}
|
2020-12-29 18:08:35 +00:00
|
|
|
|