diff options
author | Zandr Martin <zandrmartin@gmail.com> | 2016-09-01 21:39:08 -0500 |
---|---|---|
committer | Zandr Martin <zandrmartin@gmail.com> | 2016-09-01 21:39:08 -0500 |
commit | b374c35758777f98e5ddbe4b0dc43bd7c80f36d7 (patch) | |
tree | 04bb4cfc3da7d2e0de7fbc38db42f65c66d2df4c /sway/commands/exec_always.c | |
parent | Merge pull request #874 from yohanesu75/ipc-client-fix (diff) | |
download | sway-b374c35758777f98e5ddbe4b0dc43bd7c80f36d7.tar.gz sway-b374c35758777f98e5ddbe4b0dc43bd7c80f36d7.tar.zst sway-b374c35758777f98e5ddbe4b0dc43bd7c80f36d7.zip |
refactor commands.c
Diffstat (limited to 'sway/commands/exec_always.c')
-rw-r--r-- | sway/commands/exec_always.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c new file mode 100644 index 00000000..dbac9f9a --- /dev/null +++ b/sway/commands/exec_always.c | |||
@@ -0,0 +1,83 @@ | |||
1 | #include <string.h> | ||
2 | #include <sys/wait.h> | ||
3 | #include <unistd.h> | ||
4 | #include "commands.h" | ||
5 | #include "config.h" | ||
6 | #include "log.h" | ||
7 | #include "stringop.h" | ||
8 | |||
9 | struct cmd_results *cmd_exec_always(int argc, char **argv) { | ||
10 | struct cmd_results *error = NULL; | ||
11 | if (!config->active) return cmd_results_new(CMD_DEFER, NULL, NULL); | ||
12 | if ((error = checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0))) { | ||
13 | return error; | ||
14 | } | ||
15 | |||
16 | char *tmp = NULL; | ||
17 | if (strcmp((char*)*argv, "--no-startup-id") == 0) { | ||
18 | sway_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored."); | ||
19 | if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) { | ||
20 | return error; | ||
21 | } | ||
22 | |||
23 | tmp = join_args(argv + 1, argc - 1); | ||
24 | } else { | ||
25 | tmp = join_args(argv, argc); | ||
26 | } | ||
27 | |||
28 | // Put argument into cmd array | ||
29 | char cmd[4096]; | ||
30 | strncpy(cmd, tmp, sizeof(cmd)); | ||
31 | cmd[sizeof(cmd) - 1] = 0; | ||
32 | free(tmp); | ||
33 | sway_log(L_DEBUG, "Executing %s", cmd); | ||
34 | |||
35 | int fd[2]; | ||
36 | if (pipe(fd) != 0) { | ||
37 | sway_log(L_ERROR, "Unable to create pipe for fork"); | ||
38 | } | ||
39 | |||
40 | pid_t pid; | ||
41 | pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space | ||
42 | // Fork process | ||
43 | if ((pid = fork()) == 0) { | ||
44 | // Fork child process again | ||
45 | setsid(); | ||
46 | if ((*child = fork()) == 0) { | ||
47 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); | ||
48 | /* Not reached */ | ||
49 | } | ||
50 | close(fd[0]); | ||
51 | ssize_t s = 0; | ||
52 | while ((size_t)s < sizeof(pid_t)) { | ||
53 | s += write(fd[1], ((uint8_t *)child) + s, sizeof(pid_t) - s); | ||
54 | } | ||
55 | close(fd[1]); | ||
56 | _exit(0); // Close child process | ||
57 | } else if (pid < 0) { | ||
58 | free(child); | ||
59 | return cmd_results_new(CMD_FAILURE, "exec_always", "Command failed (sway could not fork)."); | ||
60 | } | ||
61 | close(fd[1]); // close write | ||
62 | ssize_t s = 0; | ||
63 | while ((size_t)s < sizeof(pid_t)) { | ||
64 | s += read(fd[0], ((uint8_t *)child) + s, sizeof(pid_t) - s); | ||
65 | } | ||
66 | close(fd[0]); | ||
67 | // cleanup child process | ||
68 | wait(0); | ||
69 | swayc_t *ws = swayc_active_workspace(); | ||
70 | if (*child > 0 && ws) { | ||
71 | sway_log(L_DEBUG, "Child process created with pid %d for workspace %s", *child, ws->name); | ||
72 | struct pid_workspace *pw = malloc(sizeof(struct pid_workspace)); | ||
73 | pw->pid = child; | ||
74 | pw->workspace = strdup(ws->name); | ||
75 | pid_workspace_add(pw); | ||
76 | // TODO: keep track of this pid and open the corresponding view on the current workspace | ||
77 | // blocked pending feature in wlc | ||
78 | } else { | ||
79 | free(child); | ||
80 | } | ||
81 | |||
82 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
83 | } | ||