diff options
author | emersion <contact@emersion.fr> | 2017-12-04 22:43:49 +0100 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2017-12-04 22:43:49 +0100 |
commit | 514c819ff98d72880c5b7e0beb7bd9ca866bc1ad (patch) | |
tree | d2ddf512ebc46ea2c93c7a487cdf758c84e3d0bd /sway | |
parent | Merge pull request #1494 from acrisci/feature/xwayland (diff) | |
download | sway-514c819ff98d72880c5b7e0beb7bd9ca866bc1ad.tar.gz sway-514c819ff98d72880c5b7e0beb7bd9ca866bc1ad.tar.zst sway-514c819ff98d72880c5b7e0beb7bd9ca866bc1ad.zip |
Add exec and exec_always commands
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 2 | ||||
-rw-r--r-- | sway/commands/exec.c | 16 | ||||
-rw-r--r-- | sway/commands/exec_always.c | 85 | ||||
-rw-r--r-- | sway/meson.build | 2 |
4 files changed, 105 insertions, 0 deletions
diff --git a/sway/commands.c b/sway/commands.c index 94a45253..5fdcdbb6 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -90,6 +90,8 @@ struct cmd_results *add_color(const char *name, char *buffer, const char *color) | |||
90 | 90 | ||
91 | /* Keep alphabetized */ | 91 | /* Keep alphabetized */ |
92 | static struct cmd_handler handlers[] = { | 92 | static struct cmd_handler handlers[] = { |
93 | { "exec", cmd_exec }, | ||
94 | { "exec_always", cmd_exec_always }, | ||
93 | { "exit", cmd_exit }, | 95 | { "exit", cmd_exit }, |
94 | }; | 96 | }; |
95 | 97 | ||
diff --git a/sway/commands/exec.c b/sway/commands/exec.c new file mode 100644 index 00000000..dd71500a --- /dev/null +++ b/sway/commands/exec.c | |||
@@ -0,0 +1,16 @@ | |||
1 | #include <string.h> | ||
2 | #include "sway/commands.h" | ||
3 | #include "log.h" | ||
4 | #include "stringop.h" | ||
5 | |||
6 | struct cmd_results *cmd_exec(int argc, char **argv) { | ||
7 | // TODO: config | ||
8 | /*if (!config->active) return cmd_results_new(CMD_DEFER, "exec", NULL); | ||
9 | if (config->reloading) { | ||
10 | char *args = join_args(argv, argc); | ||
11 | sway_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args); | ||
12 | free(args); | ||
13 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
14 | }*/ | ||
15 | return cmd_exec_always(argc, argv); | ||
16 | } | ||
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c new file mode 100644 index 00000000..0a252e7b --- /dev/null +++ b/sway/commands/exec_always.c | |||
@@ -0,0 +1,85 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <stdlib.h> | ||
3 | #include <stdint.h> | ||
4 | #include <string.h> | ||
5 | #include <sys/wait.h> | ||
6 | #include <unistd.h> | ||
7 | #include "sway/commands.h" | ||
8 | #include "sway/workspace.h" | ||
9 | #include "sway/container.h" | ||
10 | #include "log.h" | ||
11 | #include "stringop.h" | ||
12 | |||
13 | struct cmd_results *cmd_exec_always(int argc, char **argv) { | ||
14 | struct cmd_results *error = NULL; | ||
15 | // TODO: config | ||
16 | //if (!config->active) return cmd_results_new(CMD_DEFER, NULL, NULL); | ||
17 | if ((error = checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0))) { | ||
18 | return error; | ||
19 | } | ||
20 | |||
21 | char *tmp = NULL; | ||
22 | if (strcmp((char*)*argv, "--no-startup-id") == 0) { | ||
23 | sway_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored."); | ||
24 | if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) { | ||
25 | return error; | ||
26 | } | ||
27 | |||
28 | tmp = join_args(argv + 1, argc - 1); | ||
29 | } else { | ||
30 | tmp = join_args(argv, argc); | ||
31 | } | ||
32 | |||
33 | // Put argument into cmd array | ||
34 | char cmd[4096]; | ||
35 | strncpy(cmd, tmp, sizeof(cmd)); | ||
36 | cmd[sizeof(cmd) - 1] = 0; | ||
37 | free(tmp); | ||
38 | sway_log(L_DEBUG, "Executing %s", cmd); | ||
39 | |||
40 | int fd[2]; | ||
41 | if (pipe(fd) != 0) { | ||
42 | sway_log(L_ERROR, "Unable to create pipe for fork"); | ||
43 | } | ||
44 | |||
45 | pid_t pid; | ||
46 | pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space | ||
47 | if (!child) { | ||
48 | return cmd_results_new(CMD_FAILURE, "exec_always", "Unable to allocate child pid"); | ||
49 | } | ||
50 | // Fork process | ||
51 | if ((pid = fork()) == 0) { | ||
52 | // Fork child process again | ||
53 | setsid(); | ||
54 | if ((*child = fork()) == 0) { | ||
55 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); | ||
56 | // Not reached | ||
57 | } | ||
58 | close(fd[0]); | ||
59 | ssize_t s = 0; | ||
60 | while ((size_t)s < sizeof(pid_t)) { | ||
61 | s += write(fd[1], ((uint8_t *)child) + s, sizeof(pid_t) - s); | ||
62 | } | ||
63 | close(fd[1]); | ||
64 | _exit(0); // Close child process | ||
65 | } else if (pid < 0) { | ||
66 | free(child); | ||
67 | return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); | ||
68 | } | ||
69 | close(fd[1]); // close write | ||
70 | ssize_t s = 0; | ||
71 | while ((size_t)s < sizeof(pid_t)) { | ||
72 | s += read(fd[0], ((uint8_t *)child) + s, sizeof(pid_t) - s); | ||
73 | } | ||
74 | close(fd[0]); | ||
75 | // cleanup child process | ||
76 | wait(0); | ||
77 | if (*child > 0) { | ||
78 | sway_log(L_DEBUG, "Child process created with pid %d", *child); | ||
79 | // TODO: add PID to active workspace | ||
80 | } else { | ||
81 | free(child); | ||
82 | } | ||
83 | |||
84 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
85 | } | ||
diff --git a/sway/meson.build b/sway/meson.build index 9f92f5d1..b224f15f 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -3,6 +3,8 @@ sway_sources = files( | |||
3 | 'server.c', | 3 | 'server.c', |
4 | 'commands.c', | 4 | 'commands.c', |
5 | 'commands/exit.c', | 5 | 'commands/exit.c', |
6 | 'commands/exec.c', | ||
7 | 'commands/exec_always.c', | ||
6 | 'ipc-json.c', | 8 | 'ipc-json.c', |
7 | 'ipc-server.c', | 9 | 'ipc-server.c', |
8 | 'desktop/output.c', | 10 | 'desktop/output.c', |