Commit Diff


commit - 486a1459319a656b0b4b218c6451e629858d6060
commit + 21152dd558248363f497649e01611fccbb89f974
blob - 47699d3dfda45aac1703a3156787968b2d2017d5
blob + 6b53196e9bc9e297c56f645602da9931cd3dd963
--- rover.c
+++ rover.c
@@ -314,7 +314,32 @@ spawn(char **args)
     } else if (pid == 0) {
         /* Child process. */
         execvp(args[0], args);
+    }
+}
+
+static void
+shell_escaped_cat(char *buf, char *str, size_t n)
+{
+    char *p = buf + strlen(buf);
+    *p++ = '\'';
+    for (n--; n; n--, str++) {
+        switch (*str) {
+        case '\'':
+            if (n < 4)
+                goto done;
+            strcpy(p, "'\\''");
+            n -= 4;
+            p += 4;
+            break;
+        case '\0':
+            goto done;
+        default:
+            *p = *str;
+            p++;
+        }
     }
+done:
+    strncat(p, "'", n);
 }
 
 static int
@@ -324,9 +349,8 @@ open_with_env(const char *env, char *path)
     if (program) {
 #ifdef RV_SHELL
         strncpy(BUF1, program, BUFLEN - 1);
-        strncat(BUF1, " '", BUFLEN - strlen(program) - 1);
-        strncat(BUF1, path, BUFLEN - strlen(program) - 3);
-        strncat(BUF1, "'", BUFLEN - strlen(program) - strlen(path) - 3);
+        strncat(BUF1, " ", BUFLEN - strlen(program) - 1);
+        shell_escaped_cat(BUF1, path, BUFLEN - strlen(program) - 2);
         spawn((char *[]) {RV_SHELL, "-c", BUF1, NULL});
 #else
         spawn((char *[]) {program, path, NULL});