aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/exec_always.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands/exec_always.c')
-rw-r--r--sway/commands/exec_always.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index 39e48a44..8fca1909 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -7,6 +7,8 @@
7#include <signal.h> 7#include <signal.h>
8#include "sway/commands.h" 8#include "sway/commands.h"
9#include "sway/config.h" 9#include "sway/config.h"
10#include "sway/server.h"
11#include "sway/desktop/launcher.h"
10#include "sway/tree/container.h" 12#include "sway/tree/container.h"
11#include "sway/tree/root.h" 13#include "sway/tree/root.h"
12#include "sway/tree/workspace.h" 14#include "sway/tree/workspace.h"
@@ -24,11 +26,22 @@ struct cmd_results *cmd_exec_validate(int argc, char **argv) {
24 return error; 26 return error;
25} 27}
26 28
29static void export_xdga_token(struct launcher_ctx *ctx) {
30 const char *token = launcher_ctx_get_token_name(ctx);
31 setenv("XDG_ACTIVATION_TOKEN", token, 1);
32}
33
34static void export_startup_id(struct launcher_ctx *ctx) {
35 const char *token = launcher_ctx_get_token_name(ctx);
36 setenv("DESKTOP_STARTUP_ID", token, 1);
37}
38
27struct cmd_results *cmd_exec_process(int argc, char **argv) { 39struct cmd_results *cmd_exec_process(int argc, char **argv) {
28 struct cmd_results *error = NULL; 40 struct cmd_results *error = NULL;
29 char *tmp = NULL; 41 char *cmd = NULL;
42 bool no_startup_id = false;
30 if (strcmp(argv[0], "--no-startup-id") == 0) { 43 if (strcmp(argv[0], "--no-startup-id") == 0) {
31 sway_log(SWAY_INFO, "exec switch '--no-startup-id' not supported, ignored."); 44 no_startup_id = true;
32 --argc; ++argv; 45 --argc; ++argv;
33 if ((error = checkarg(argc, argv[-1], EXPECTED_AT_LEAST, 1))) { 46 if ((error = checkarg(argc, argv[-1], EXPECTED_AT_LEAST, 1))) {
34 return error; 47 return error;
@@ -36,17 +49,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
36 } 49 }
37 50
38 if (argc == 1 && (argv[0][0] == '\'' || argv[0][0] == '"')) { 51 if (argc == 1 && (argv[0][0] == '\'' || argv[0][0] == '"')) {
39 tmp = strdup(argv[0]); 52 cmd = strdup(argv[0]);
40 strip_quotes(tmp); 53 strip_quotes(cmd);
41 } else { 54 } else {
42 tmp = join_args(argv, argc); 55 cmd = join_args(argv, argc);
43 } 56 }
44 57
45 // Put argument into cmd array
46 char cmd[4096];
47 strncpy(cmd, tmp, sizeof(cmd) - 1);
48 cmd[sizeof(cmd) - 1] = 0;
49 free(tmp);
50 sway_log(SWAY_DEBUG, "Executing %s", cmd); 58 sway_log(SWAY_DEBUG, "Executing %s", cmd);
51 59
52 int fd[2]; 60 int fd[2];
@@ -55,18 +63,28 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
55 } 63 }
56 64
57 pid_t pid, child; 65 pid_t pid, child;
66 struct launcher_ctx *ctx = launcher_ctx_create_internal();
58 // Fork process 67 // Fork process
59 if ((pid = fork()) == 0) { 68 if ((pid = fork()) == 0) {
60 // Fork child process again 69 // Fork child process again
70 restore_nofile_limit();
61 setsid(); 71 setsid();
62 sigset_t set; 72 sigset_t set;
63 sigemptyset(&set); 73 sigemptyset(&set);
64 sigprocmask(SIG_SETMASK, &set, NULL); 74 sigprocmask(SIG_SETMASK, &set, NULL);
75 signal(SIGPIPE, SIG_DFL);
65 close(fd[0]); 76 close(fd[0]);
66 if ((child = fork()) == 0) { 77 if ((child = fork()) == 0) {
67 close(fd[1]); 78 close(fd[1]);
68 execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); 79 if (ctx) {
69 _exit(0); 80 export_xdga_token(ctx);
81 }
82 if (ctx && !no_startup_id) {
83 export_startup_id(ctx);
84 }
85 execlp("sh", "sh", "-c", cmd, (void *)NULL);
86 sway_log_errno(SWAY_ERROR, "execlp failed");
87 _exit(1);
70 } 88 }
71 ssize_t s = 0; 89 ssize_t s = 0;
72 while ((size_t)s < sizeof(pid_t)) { 90 while ((size_t)s < sizeof(pid_t)) {
@@ -75,10 +93,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
75 close(fd[1]); 93 close(fd[1]);
76 _exit(0); // Close child process 94 _exit(0); // Close child process
77 } else if (pid < 0) { 95 } else if (pid < 0) {
96 free(cmd);
78 close(fd[0]); 97 close(fd[0]);
79 close(fd[1]); 98 close(fd[1]);
80 return cmd_results_new(CMD_FAILURE, "fork() failed"); 99 return cmd_results_new(CMD_FAILURE, "fork() failed");
81 } 100 }
101 free(cmd);
82 close(fd[1]); // close write 102 close(fd[1]); // close write
83 ssize_t s = 0; 103 ssize_t s = 0;
84 while ((size_t)s < sizeof(pid_t)) { 104 while ((size_t)s < sizeof(pid_t)) {
@@ -89,8 +109,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
89 waitpid(pid, NULL, 0); 109 waitpid(pid, NULL, 0);
90 if (child > 0) { 110 if (child > 0) {
91 sway_log(SWAY_DEBUG, "Child process created with pid %d", child); 111 sway_log(SWAY_DEBUG, "Child process created with pid %d", child);
92 root_record_workspace_pid(child); 112 if (ctx != NULL) {
113 sway_log(SWAY_DEBUG, "Recording workspace for process %d", child);
114 ctx->pid = child;
115 }
93 } else { 116 } else {
117 launcher_ctx_destroy(ctx);
94 return cmd_results_new(CMD_FAILURE, "Second fork() failed"); 118 return cmd_results_new(CMD_FAILURE, "Second fork() failed");
95 } 119 }
96 120