aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/exec_always.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-07-23 20:27:56 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-07-23 20:31:11 -0400
commitf4b882475eee7a81c206c7825616cc4656b2f60b (patch)
tree38e6ebf81b235424f105dcbcbb194e5e9eac70c0 /sway/commands/exec_always.c
parentImplement pid->workspace tracking (diff)
parentMerge pull request #2342 from RyanDwyer/update-cursor (diff)
downloadsway-f4b882475eee7a81c206c7825616cc4656b2f60b.tar.gz
sway-f4b882475eee7a81c206c7825616cc4656b2f60b.tar.zst
sway-f4b882475eee7a81c206c7825616cc4656b2f60b.zip
Merge branch 'master' into pid-workspaces
Diffstat (limited to 'sway/commands/exec_always.c')
-rw-r--r--sway/commands/exec_always.c35
1 files changed, 17 insertions, 18 deletions
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index abd52e59..9bf2b320 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -20,7 +20,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
20 20
21 char *tmp = NULL; 21 char *tmp = NULL;
22 if (strcmp((char*)*argv, "--no-startup-id") == 0) { 22 if (strcmp((char*)*argv, "--no-startup-id") == 0) {
23 wlr_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored."); 23 wlr_log(WLR_INFO, "exec switch '--no-startup-id' not supported, ignored.");
24 if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) { 24 if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) {
25 return error; 25 return error;
26 } 26 }
@@ -35,50 +35,49 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
35 strncpy(cmd, tmp, sizeof(cmd) - 1); 35 strncpy(cmd, tmp, sizeof(cmd) - 1);
36 cmd[sizeof(cmd) - 1] = 0; 36 cmd[sizeof(cmd) - 1] = 0;
37 free(tmp); 37 free(tmp);
38 wlr_log(L_DEBUG, "Executing %s", cmd); 38 wlr_log(WLR_DEBUG, "Executing %s", cmd);
39 39
40 int fd[2]; 40 int fd[2];
41 if (pipe(fd) != 0) { 41 if (pipe(fd) != 0) {
42 wlr_log(L_ERROR, "Unable to create pipe for fork"); 42 wlr_log(WLR_ERROR, "Unable to create pipe for fork");
43 } 43 }
44 44
45 pid_t pid; 45 pid_t pid, child;
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 46 // Fork process
51 if ((pid = fork()) == 0) { 47 if ((pid = fork()) == 0) {
52 // Fork child process again 48 // Fork child process again
53 setsid(); 49 setsid();
54 if ((*child = fork()) == 0) { 50 close(fd[0]);
51 if ((child = fork()) == 0) {
52 close(fd[1]);
55 execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); 53 execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL);
56 // Not reached 54 _exit(0);
57 } 55 }
58 close(fd[0]);
59 ssize_t s = 0; 56 ssize_t s = 0;
60 while ((size_t)s < sizeof(pid_t)) { 57 while ((size_t)s < sizeof(pid_t)) {
61 s += write(fd[1], ((uint8_t *)child) + s, sizeof(pid_t) - s); 58 s += write(fd[1], ((uint8_t *)&child) + s, sizeof(pid_t) - s);
62 } 59 }
63 close(fd[1]); 60 close(fd[1]);
64 _exit(0); // Close child process 61 _exit(0); // Close child process
65 } else if (pid < 0) { 62 } else if (pid < 0) {
66 free(child); 63 close(fd[0]);
64 close(fd[1]);
67 return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); 65 return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed");
68 } 66 }
69 close(fd[1]); // close write 67 close(fd[1]); // close write
70 ssize_t s = 0; 68 ssize_t s = 0;
71 while ((size_t)s < sizeof(pid_t)) { 69 while ((size_t)s < sizeof(pid_t)) {
72 s += read(fd[0], ((uint8_t *)child) + s, sizeof(pid_t) - s); 70 s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s);
73 } 71 }
74 close(fd[0]); 72 close(fd[0]);
75 // cleanup child process 73 // cleanup child process
76 waitpid(pid, NULL, 0); 74 waitpid(pid, NULL, 0);
77 if (*child > 0) { 75 if (child > 0) {
78 wlr_log(L_DEBUG, "Child process created with pid %d", *child); 76 wlr_log(WLR_DEBUG, "Child process created with pid %d", child);
79 workspace_record_pid(*child); 77 workspace_record_pid(child);
80 } else { 78 } else {
81 free(child); 79 return cmd_results_new(CMD_FAILURE, "exec_always",
80 "Second fork() failed");
82 } 81 }
83 82
84 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 83 return cmd_results_new(CMD_SUCCESS, NULL, NULL);