aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2017-12-04 22:43:49 +0100
committerLibravatar emersion <contact@emersion.fr>2017-12-04 22:43:49 +0100
commit514c819ff98d72880c5b7e0beb7bd9ca866bc1ad (patch)
treed2ddf512ebc46ea2c93c7a487cdf758c84e3d0bd
parentMerge pull request #1494 from acrisci/feature/xwayland (diff)
downloadsway-514c819ff98d72880c5b7e0beb7bd9ca866bc1ad.tar.gz
sway-514c819ff98d72880c5b7e0beb7bd9ca866bc1ad.tar.zst
sway-514c819ff98d72880c5b7e0beb7bd9ca866bc1ad.zip
Add exec and exec_always commands
-rw-r--r--sway/commands.c2
-rw-r--r--sway/commands/exec.c16
-rw-r--r--sway/commands/exec_always.c85
-rw-r--r--sway/meson.build2
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 */
92static struct cmd_handler handlers[] = { 92static 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
6struct 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
13struct 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',