commit 32ae26e519eeb6a5108f1d82fe36ce5b6ef65af3
parent ed227f5664196d85194d63d01a5382499867a386
Author: Mikkel Oscar Lyderik <mikkeloscar@gmail.com>
Date: Mon, 25 Jan 2016 00:02:28 +0100
Add quotes to multiword arguments.
This adds quotes around multiword arguments before they are passed to
`/bin/sh -c` in an exec command.
Example:
I connect to irc like this:
exec termite -e "mosh server tmux a"
Without this patch the arguments are passed to sh as:
termite -e mosh server tmux a
When it should be:
termite -e "mosh server tmux a"
For the command to work.
Diffstat:
3 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/common/stringop.c b/common/stringop.c
@@ -273,6 +273,32 @@ char *join_args(char **argv, int argc) {
return res;
}
+static bool has_whitespace(const char *str) {
+ while (*str) {
+ if (isspace(*str)) {
+ return true;
+ }
+ ++str;
+ }
+ return false;
+}
+
+/**
+ * Add quotes around any argv with whitespaces.
+ */
+void add_quotes(char **argv, int argc) {
+ int i;
+ for (i = 0; i < argc; ++i) {
+ if (has_whitespace(argv[i])) {
+ int len = strlen(argv[i]) + 3;
+ char *tmp = argv[i];
+ argv[i] = malloc(len * sizeof(char));
+ snprintf(argv[i], len, "\"%s\"", tmp);
+ free(tmp);
+ }
+ }
+}
+
/*
* Join a list of strings, adding separator in between. Separator can be NULL.
*/
diff --git a/include/stringop.h b/include/stringop.h
@@ -31,6 +31,11 @@ int unescape_string(char *string);
char *join_args(char **argv, int argc);
char *join_list(list_t *list, char *separator);
+/**
+ * Add quotes around any argv with whitespaces.
+ */
+void add_quotes(char **argv, int argc);
+
// split string into 2 by delim.
char *cmdsep(char **stringp, const char *delim);
// Split string into 2 by delim, handle quotes
diff --git a/sway/commands.c b/sway/commands.c
@@ -361,8 +361,10 @@ static struct cmd_results *cmd_exec_always(int argc, char **argv) {
return error;
}
+ add_quotes(argv + 1, argc - 1);
tmp = join_args(argv + 1, argc - 1);
} else {
+ add_quotes(argv, argc);
tmp = join_args(argv, argc);
}