summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2014-10-26 15:01:06 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2014-10-26 15:01:06 +0200
commit8d08365645d1ee22b9c1fe8ab763e21dd7b0e77b (patch)
tree3c1b5971d0f8f2fce374fa9cf5860d6e84f61397 /client
parentc5debe04b0af44bf2fe9610996116f0c03c25820 (diff)
downloadbemenu-8d08365645d1ee22b9c1fe8ab763e21dd7b0e77b.tar.gz
bemenu-8d08365645d1ee22b9c1fe8ab763e21dd7b0e77b.tar.bz2
bemenu-8d08365645d1ee22b9c1fe8ab763e21dd7b0e77b.zip
Tokenize launch arguments.
Diffstat (limited to 'client')
-rw-r--r--client/bemenu-run.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/client/bemenu-run.c b/client/bemenu-run.c
index 0df48d5..4ac1175 100644
--- a/client/bemenu-run.c
+++ b/client/bemenu-run.c
@@ -144,6 +144,38 @@ read_items_to_menu_from_path(struct bm_menu *menu)
read_items_to_menu_from_dir(menu, path);
}
+static bool
+tokenize_args(const char *buf, char **out_copy, char ***out_list)
+{
+ assert(buf && out_copy && out_list);
+ *out_copy = NULL;
+ *out_list = NULL;
+
+ char *copy;
+ if (!(copy = c_strdup(buf)))
+ return false;
+
+ size_t pos, count = 0;
+ for (const char *s = copy; *s && (pos = strcspn(s, " ")) != 0; s += pos + 1)
+ ++count;
+
+ char **list;
+ if (!(list = calloc(count + 1, sizeof(char*)))) {
+ free(copy);
+ return false;
+ }
+
+ count = 0;
+ for (char *s = copy; *s && (pos = strcspn(s, " ")) != 0; s += pos + 1, ++count) {
+ s[pos] = 0;
+ list[count] = s;
+ }
+
+ *out_copy = copy;
+ *out_list = list;
+ return true;
+}
+
static void
launch(const char *bin)
{
@@ -154,7 +186,14 @@ launch(const char *bin)
setsid();
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
- execlp(bin, bin, NULL);
+
+ char *first, **args;
+ if (!tokenize_args(bin, &first, &args))
+ _exit(EXIT_FAILURE);
+
+ execvp(first, args);
+ free(first);
+ free(args);
_exit(EXIT_SUCCESS);
}
}