Git.pm: Handle failed commands' output
[gitweb.git] / exec_cmd.c
index b5e59a9ae9777183d3110defc2c8964aa0d8b62b..c1539d12ce9e350811b5b110206f5577a151e8ef 100644 (file)
@@ -21,7 +21,7 @@ const char *git_exec_path(void)
                return current_exec_path;
 
        env = getenv("GIT_EXEC_PATH");
-       if (env) {
+       if (env && *env) {
                return env;
        }
 
@@ -29,24 +29,28 @@ const char *git_exec_path(void)
 }
 
 
-int execv_git_cmd(char **argv)
+int execv_git_cmd(const char **argv)
 {
        char git_command[PATH_MAX + 1];
-       char *tmp;
-       int len, err, i;
+       int i;
        const char *paths[] = { current_exec_path,
                                getenv("GIT_EXEC_PATH"),
                                builtin_exec_path };
 
-       for (i = 0; i < sizeof(paths)/sizeof(paths[0]); ++i) {
+       for (i = 0; i < ARRAY_SIZE(paths); ++i) {
+               size_t len;
+               int rc;
                const char *exec_dir = paths[i];
-               if (!exec_dir) continue;
+               const char *tmp;
+
+               if (!exec_dir || !*exec_dir) continue;
 
                if (*exec_dir != '/') {
                        if (!getcwd(git_command, sizeof(git_command))) {
                                fprintf(stderr, "git: cannot determine "
-                                       "current directory\n");
-                               exit(1);
+                                       "current directory: %s\n",
+                                       strerror(errno));
+                               break;
                        }
                        len = strlen(git_command);
 
@@ -56,17 +60,28 @@ int execv_git_cmd(char **argv)
                                while (*exec_dir == '/')
                                        exec_dir++;
                        }
-                       snprintf(git_command + len, sizeof(git_command) - len,
-                                "/%s", exec_dir);
+
+                       rc = snprintf(git_command + len,
+                                     sizeof(git_command) - len, "/%s",
+                                     exec_dir);
+                       if (rc < 0 || rc >= sizeof(git_command) - len) {
+                               fprintf(stderr, "git: command name given "
+                                       "is too long.\n");
+                               break;
+                       }
                } else {
+                       if (strlen(exec_dir) + 1 > sizeof(git_command)) {
+                               fprintf(stderr, "git: command name given "
+                                       "is too long.\n");
+                               break;
+                       }
                        strcpy(git_command, exec_dir);
                }
 
                len = strlen(git_command);
-               len += snprintf(git_command + len, sizeof(git_command) - len,
-                               "/git-%s", argv[0]);
-
-               if (sizeof(git_command) <= len) {
+               rc = snprintf(git_command + len, sizeof(git_command) - len,
+                             "/git-%s", argv[0]);
+               if (rc < 0 || rc >= sizeof(git_command) - len) {
                        fprintf(stderr,
                                "git: command name given is too long.\n");
                        break;
@@ -82,9 +97,7 @@ int execv_git_cmd(char **argv)
                argv[0] = git_command;
 
                /* execve() can only ever return if it fails */
-               execve(git_command, argv, environ);
-
-               err = errno;
+               execve(git_command, (char **)argv, environ);
 
                argv[0] = tmp;
        }
@@ -93,11 +106,11 @@ int execv_git_cmd(char **argv)
 }
 
 
-int execl_git_cmd(char *cmd,...)
+int execl_git_cmd(const char *cmd,...)
 {
        int argc;
-       char *argv[MAX_ARGS + 1];
-       char *arg;
+       const char *argv[MAX_ARGS + 1];
+       const char *arg;
        va_list param;
 
        va_start(param, cmd);