weston-launch: Move child setup and exec to its own function
This commit is contained in:
+83
-76
@@ -73,6 +73,7 @@ struct weston_launch {
|
|||||||
|
|
||||||
pid_t child;
|
pid_t child;
|
||||||
int verbose;
|
int verbose;
|
||||||
|
int sleep_fork;
|
||||||
};
|
};
|
||||||
|
|
||||||
union cmsg_data { unsigned char b[4]; int fd; };
|
union cmsg_data { unsigned char b[4]; int fd; };
|
||||||
@@ -511,6 +512,65 @@ setup_tty(struct weston_launch *wl, const char *tty)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
launch_compositor(struct weston_launch *wl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *child_argv[MAX_ARGV_SIZE];
|
||||||
|
char **env;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (wl->verbose)
|
||||||
|
printf("weston-launch: spawned weston with pid: %d\n", getpid());
|
||||||
|
if (wl->tty != STDIN_FILENO) {
|
||||||
|
if (setsid() < 0)
|
||||||
|
error(1, errno, "setsid failed");
|
||||||
|
if (ioctl(wl->tty, TIOCSCTTY, 0) < 0)
|
||||||
|
error(1, errno, "TIOCSCTTY failed - tty is in use");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setgid(wl->pw->pw_gid) < 0 ||
|
||||||
|
#ifdef HAVE_INITGROUPS
|
||||||
|
initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
|
||||||
|
#endif
|
||||||
|
setuid(wl->pw->pw_uid) < 0)
|
||||||
|
error(1, errno, "dropping privileges failed");
|
||||||
|
|
||||||
|
if (wl->sleep_fork) {
|
||||||
|
if (wl->verbose)
|
||||||
|
printf("weston-launch: waiting %d seconds\n",
|
||||||
|
wl->sleep_fork);
|
||||||
|
sleep(wl->sleep_fork);
|
||||||
|
}
|
||||||
|
|
||||||
|
env = pam_getenvlist(wl->ph);
|
||||||
|
if (env) {
|
||||||
|
for (i = 0; env[i]; ++i) {
|
||||||
|
if (putenv(env[i]) < 0)
|
||||||
|
error(0, 0, "putenv %s failed", env[i]);
|
||||||
|
}
|
||||||
|
free(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wl->tty != STDIN_FILENO)
|
||||||
|
setenv_fd("WESTON_TTY_FD", wl->tty);
|
||||||
|
|
||||||
|
setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
|
||||||
|
|
||||||
|
unsetenv("DISPLAY");
|
||||||
|
|
||||||
|
child_argv[0] = wl->pw->pw_shell;
|
||||||
|
child_argv[1] = "-l";
|
||||||
|
child_argv[2] = "-c";
|
||||||
|
child_argv[3] = BINDIR "/weston \"$@\"";
|
||||||
|
child_argv[4] = "weston";
|
||||||
|
for (i = 0; i < argc; ++i)
|
||||||
|
child_argv[5 + i] = argv[i];
|
||||||
|
child_argv[5 + i] = NULL;
|
||||||
|
|
||||||
|
execv(child_argv[0], child_argv);
|
||||||
|
error(1, errno, "exec failed");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
help(const char *name)
|
help(const char *name)
|
||||||
{
|
{
|
||||||
@@ -526,12 +586,9 @@ int
|
|||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct weston_launch wl;
|
struct weston_launch wl;
|
||||||
char **env;
|
|
||||||
int i, c;
|
int i, c;
|
||||||
char *child_argv[MAX_ARGV_SIZE];
|
|
||||||
char *tty = NULL, *new_user = NULL;
|
char *tty = NULL, *new_user = NULL;
|
||||||
char *term;
|
char *term;
|
||||||
int sleep_fork = 0;
|
|
||||||
struct option opts[] = {
|
struct option opts[] = {
|
||||||
{ "user", required_argument, NULL, 'u' },
|
{ "user", required_argument, NULL, 'u' },
|
||||||
{ "tty", required_argument, NULL, 't' },
|
{ "tty", required_argument, NULL, 't' },
|
||||||
@@ -558,9 +615,9 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (optarg)
|
if (optarg)
|
||||||
sleep_fork = atoi(optarg);
|
wl.sleep_fork = atoi(optarg);
|
||||||
else
|
else
|
||||||
sleep_fork = 10;
|
wl.sleep_fork = 10;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
help("weston-launch");
|
help("weston-launch");
|
||||||
@@ -578,15 +635,6 @@ main(int argc, char *argv[])
|
|||||||
if (wl.pw == NULL)
|
if (wl.pw == NULL)
|
||||||
error(1, errno, "failed to get username");
|
error(1, errno, "failed to get username");
|
||||||
|
|
||||||
child_argv[0] = wl.pw->pw_shell;
|
|
||||||
child_argv[1] = "-l";
|
|
||||||
child_argv[2] = "-c";
|
|
||||||
child_argv[3] = BINDIR "/weston \"$@\"";
|
|
||||||
child_argv[4] = "weston";
|
|
||||||
for (i = 0; i < (argc - optind); ++i)
|
|
||||||
child_argv[5 + i] = argv[optind + i];
|
|
||||||
child_argv[5 + i] = NULL;
|
|
||||||
|
|
||||||
term = getenv("TERM");
|
term = getenv("TERM");
|
||||||
clearenv();
|
clearenv();
|
||||||
setenv("TERM", term, 1);
|
setenv("TERM", term, 1);
|
||||||
@@ -620,74 +668,33 @@ main(int argc, char *argv[])
|
|||||||
if (setup_signals(&wl) < 0)
|
if (setup_signals(&wl) < 0)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
switch ((wl.child = fork())) {
|
wl.child = fork();
|
||||||
case -1:
|
if (wl.child == -1) {
|
||||||
error(1, errno, "fork failed");
|
error(1, errno, "fork failed");
|
||||||
break;
|
exit(EXIT_FAILURE);
|
||||||
case 0:
|
}
|
||||||
if (wl.verbose)
|
|
||||||
printf("weston-launch: spawned weston with pid: %d\n", getpid());
|
|
||||||
if (wl.tty != STDIN_FILENO) {
|
|
||||||
if (setsid() < 0)
|
|
||||||
error(1, errno, "setsid failed");
|
|
||||||
if (ioctl(wl.tty, TIOCSCTTY, 0) < 0)
|
|
||||||
error(1, errno, "TIOCSCTTY failed - tty is in use");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setgid(wl.pw->pw_gid) < 0 ||
|
if (wl.child == 0)
|
||||||
#ifdef HAVE_INITGROUPS
|
launch_compositor(&wl, argc - optind, argv + optind);
|
||||||
initgroups(wl.pw->pw_name, wl.pw->pw_gid) < 0 ||
|
|
||||||
#endif
|
|
||||||
setuid(wl.pw->pw_uid) < 0)
|
|
||||||
error(1, errno, "dropping privileges failed");
|
|
||||||
|
|
||||||
|
close(wl.sock[1]);
|
||||||
|
if (wl.tty != STDIN_FILENO)
|
||||||
|
close(wl.tty);
|
||||||
|
|
||||||
if (sleep_fork) {
|
while (1) {
|
||||||
if (wl.verbose)
|
struct epoll_event ev;
|
||||||
printf("weston-launch: waiting %d seconds\n", sleep_fork);
|
int n;
|
||||||
sleep(sleep_fork);
|
|
||||||
}
|
|
||||||
|
|
||||||
env = pam_getenvlist(wl.ph);
|
n = epoll_wait(wl.epollfd, &ev, 1, -1);
|
||||||
if (env) {
|
if (n < 0)
|
||||||
for (i = 0; env[i]; ++i) {
|
error(0, errno, "epoll_wait failed");
|
||||||
if (putenv(env[i]) < 0)
|
if (n != 1)
|
||||||
error(0, 0, "putenv %s failed", env[i]);
|
continue;
|
||||||
}
|
|
||||||
free(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wl.tty != STDIN_FILENO)
|
if (ev.data.fd == wl.sock[0])
|
||||||
setenv_fd("WESTON_TTY_FD", wl.tty);
|
handle_socket_msg(&wl);
|
||||||
|
else if (ev.data.fd == wl.signalfd)
|
||||||
setenv_fd("WESTON_LAUNCHER_SOCK", wl.sock[1]);
|
handle_signal(&wl);
|
||||||
|
|
||||||
unsetenv("DISPLAY");
|
|
||||||
|
|
||||||
execv(child_argv[0], child_argv);
|
|
||||||
error(1, errno, "exec failed");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
close(wl.sock[1]);
|
|
||||||
if (wl.tty != STDIN_FILENO)
|
|
||||||
close(wl.tty);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
struct epoll_event ev;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
n = epoll_wait(wl.epollfd, &ev, 1, -1);
|
|
||||||
if (n < 0)
|
|
||||||
error(0, errno, "epoll_wait failed");
|
|
||||||
if (n != 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ev.data.fd == wl.sock[0])
|
|
||||||
handle_socket_msg(&wl);
|
|
||||||
else if (ev.data.fd == wl.signalfd)
|
|
||||||
handle_signal(&wl);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user