2006-01-11 10:12:17 +08:00
|
|
|
#include "cache.h"
|
|
|
|
#include "exec_cmd.h"
|
2006-06-25 21:56:18 +08:00
|
|
|
#include "quote.h"
|
prepare_{git,shell}_cmd: use argv_array
These functions transform an existing argv into one suitable
for exec-ing or spawning via git or a shell. We can use an
argv_array in each to avoid dealing with manual counting and
allocation.
This also makes the memory allocation more clear and fixes
some leaks. In prepare_shell_cmd, we would sometimes
allocate a new string with "$@" in it and sometimes not,
meaning the caller could not correctly free it. On the
non-Windows side, we are in a child process which will
exec() or exit() immediately, so the leak isn't a big deal.
On Windows, though, we use spawn() from the parent process,
and leak a string for each shell command we run. On top of
that, the Windows code did not free the allocated argv array
at all (but does for the prepare_git_cmd case!).
By switching both of these functions to write into an
argv_array, we can consistently free the result as
appropriate.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:44:39 +08:00
|
|
|
#include "argv-array.h"
|
2006-01-11 10:12:17 +08:00
|
|
|
#define MAX_ARGS 32
|
|
|
|
|
2007-10-27 16:36:51 +08:00
|
|
|
static const char *argv_exec_path;
|
2008-07-22 03:19:52 +08:00
|
|
|
static const char *argv0_path;
|
2006-01-11 10:12:17 +08:00
|
|
|
|
2014-11-25 03:33:54 +08:00
|
|
|
char *system_path(const char *path)
|
2008-07-14 04:31:18 +08:00
|
|
|
{
|
Compute prefix at runtime if RUNTIME_PREFIX is set
This commit adds support for relocatable binaries (called
RUNTIME_PREFIX). Such binaries can be moved together with the
system configuration files to a different directory, as long as the
relative paths from the binary to the configuration files is
preserved. This functionality is essential on Windows where we
deliver git binaries with an installer that allows to freely choose
the installation location.
If RUNTIME_PREFIX is unset we use the static prefix. This will be
the default on Unix. Thus, the behavior on Unix will remain
identical to the old implementation, which used to add the prefix
in the Makefile.
If RUNTIME_PREFIX is set the prefix is computed from the location
of the executable. In this case, system_path() tries to strip
known directories that executables can be located in from the path
of the executable. If the path is successfully stripped it is used
as the prefix. For example, if the executable is
"/msysgit/bin/git" and BINDIR is "bin", then the prefix computed is
"/msysgit".
If the runtime prefix computation fails, we fall back to the static
prefix specified in the makefile. This can be the case if the
executable is not installed at a known location. Note that our
test system sets GIT_CONFIG_NOSYSTEM to tell git to ignore global
configuration files during testing. Hence testing does not trigger
the fall back.
Note that RUNTIME_PREFIX only works on Windows, though adding
support on Unix should not be too hard. The implementation
requires argv0_path to be set to an absolute path. argv0_path must
point to the directory of the executable. We use assert() to
verify this in debug builds. On Windows, the wrapper for main()
(see compat/mingw.h) guarantees that argv0_path is correctly
initialized. On Unix, further work is required before
RUNTIME_PREFIX can be enabled.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18 20:00:14 +08:00
|
|
|
#ifdef RUNTIME_PREFIX
|
|
|
|
static const char *prefix;
|
|
|
|
#else
|
2009-01-18 20:00:09 +08:00
|
|
|
static const char *prefix = PREFIX;
|
Compute prefix at runtime if RUNTIME_PREFIX is set
This commit adds support for relocatable binaries (called
RUNTIME_PREFIX). Such binaries can be moved together with the
system configuration files to a different directory, as long as the
relative paths from the binary to the configuration files is
preserved. This functionality is essential on Windows where we
deliver git binaries with an installer that allows to freely choose
the installation location.
If RUNTIME_PREFIX is unset we use the static prefix. This will be
the default on Unix. Thus, the behavior on Unix will remain
identical to the old implementation, which used to add the prefix
in the Makefile.
If RUNTIME_PREFIX is set the prefix is computed from the location
of the executable. In this case, system_path() tries to strip
known directories that executables can be located in from the path
of the executable. If the path is successfully stripped it is used
as the prefix. For example, if the executable is
"/msysgit/bin/git" and BINDIR is "bin", then the prefix computed is
"/msysgit".
If the runtime prefix computation fails, we fall back to the static
prefix specified in the makefile. This can be the case if the
executable is not installed at a known location. Note that our
test system sets GIT_CONFIG_NOSYSTEM to tell git to ignore global
configuration files during testing. Hence testing does not trigger
the fall back.
Note that RUNTIME_PREFIX only works on Windows, though adding
support on Unix should not be too hard. The implementation
requires argv0_path to be set to an absolute path. argv0_path must
point to the directory of the executable. We use assert() to
verify this in debug builds. On Windows, the wrapper for main()
(see compat/mingw.h) guarantees that argv0_path is correctly
initialized. On Unix, further work is required before
RUNTIME_PREFIX can be enabled.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18 20:00:14 +08:00
|
|
|
#endif
|
2009-01-18 20:00:09 +08:00
|
|
|
struct strbuf d = STRBUF_INIT;
|
|
|
|
|
|
|
|
if (is_absolute_path(path))
|
2014-11-25 03:33:54 +08:00
|
|
|
return xstrdup(path);
|
2009-01-18 20:00:09 +08:00
|
|
|
|
Compute prefix at runtime if RUNTIME_PREFIX is set
This commit adds support for relocatable binaries (called
RUNTIME_PREFIX). Such binaries can be moved together with the
system configuration files to a different directory, as long as the
relative paths from the binary to the configuration files is
preserved. This functionality is essential on Windows where we
deliver git binaries with an installer that allows to freely choose
the installation location.
If RUNTIME_PREFIX is unset we use the static prefix. This will be
the default on Unix. Thus, the behavior on Unix will remain
identical to the old implementation, which used to add the prefix
in the Makefile.
If RUNTIME_PREFIX is set the prefix is computed from the location
of the executable. In this case, system_path() tries to strip
known directories that executables can be located in from the path
of the executable. If the path is successfully stripped it is used
as the prefix. For example, if the executable is
"/msysgit/bin/git" and BINDIR is "bin", then the prefix computed is
"/msysgit".
If the runtime prefix computation fails, we fall back to the static
prefix specified in the makefile. This can be the case if the
executable is not installed at a known location. Note that our
test system sets GIT_CONFIG_NOSYSTEM to tell git to ignore global
configuration files during testing. Hence testing does not trigger
the fall back.
Note that RUNTIME_PREFIX only works on Windows, though adding
support on Unix should not be too hard. The implementation
requires argv0_path to be set to an absolute path. argv0_path must
point to the directory of the executable. We use assert() to
verify this in debug builds. On Windows, the wrapper for main()
(see compat/mingw.h) guarantees that argv0_path is correctly
initialized. On Unix, further work is required before
RUNTIME_PREFIX can be enabled.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18 20:00:14 +08:00
|
|
|
#ifdef RUNTIME_PREFIX
|
|
|
|
assert(argv0_path);
|
|
|
|
assert(is_absolute_path(argv0_path));
|
|
|
|
|
2009-02-20 03:10:53 +08:00
|
|
|
if (!prefix &&
|
|
|
|
!(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
|
|
|
|
!(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
|
|
|
|
!(prefix = strip_path_suffix(argv0_path, "git"))) {
|
Compute prefix at runtime if RUNTIME_PREFIX is set
This commit adds support for relocatable binaries (called
RUNTIME_PREFIX). Such binaries can be moved together with the
system configuration files to a different directory, as long as the
relative paths from the binary to the configuration files is
preserved. This functionality is essential on Windows where we
deliver git binaries with an installer that allows to freely choose
the installation location.
If RUNTIME_PREFIX is unset we use the static prefix. This will be
the default on Unix. Thus, the behavior on Unix will remain
identical to the old implementation, which used to add the prefix
in the Makefile.
If RUNTIME_PREFIX is set the prefix is computed from the location
of the executable. In this case, system_path() tries to strip
known directories that executables can be located in from the path
of the executable. If the path is successfully stripped it is used
as the prefix. For example, if the executable is
"/msysgit/bin/git" and BINDIR is "bin", then the prefix computed is
"/msysgit".
If the runtime prefix computation fails, we fall back to the static
prefix specified in the makefile. This can be the case if the
executable is not installed at a known location. Note that our
test system sets GIT_CONFIG_NOSYSTEM to tell git to ignore global
configuration files during testing. Hence testing does not trigger
the fall back.
Note that RUNTIME_PREFIX only works on Windows, though adding
support on Unix should not be too hard. The implementation
requires argv0_path to be set to an absolute path. argv0_path must
point to the directory of the executable. We use assert() to
verify this in debug builds. On Windows, the wrapper for main()
(see compat/mingw.h) guarantees that argv0_path is correctly
initialized. On Unix, further work is required before
RUNTIME_PREFIX can be enabled.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18 20:00:14 +08:00
|
|
|
prefix = PREFIX;
|
2010-02-23 19:42:56 +08:00
|
|
|
trace_printf("RUNTIME_PREFIX requested, "
|
Compute prefix at runtime if RUNTIME_PREFIX is set
This commit adds support for relocatable binaries (called
RUNTIME_PREFIX). Such binaries can be moved together with the
system configuration files to a different directory, as long as the
relative paths from the binary to the configuration files is
preserved. This functionality is essential on Windows where we
deliver git binaries with an installer that allows to freely choose
the installation location.
If RUNTIME_PREFIX is unset we use the static prefix. This will be
the default on Unix. Thus, the behavior on Unix will remain
identical to the old implementation, which used to add the prefix
in the Makefile.
If RUNTIME_PREFIX is set the prefix is computed from the location
of the executable. In this case, system_path() tries to strip
known directories that executables can be located in from the path
of the executable. If the path is successfully stripped it is used
as the prefix. For example, if the executable is
"/msysgit/bin/git" and BINDIR is "bin", then the prefix computed is
"/msysgit".
If the runtime prefix computation fails, we fall back to the static
prefix specified in the makefile. This can be the case if the
executable is not installed at a known location. Note that our
test system sets GIT_CONFIG_NOSYSTEM to tell git to ignore global
configuration files during testing. Hence testing does not trigger
the fall back.
Note that RUNTIME_PREFIX only works on Windows, though adding
support on Unix should not be too hard. The implementation
requires argv0_path to be set to an absolute path. argv0_path must
point to the directory of the executable. We use assert() to
verify this in debug builds. On Windows, the wrapper for main()
(see compat/mingw.h) guarantees that argv0_path is correctly
initialized. On Unix, further work is required before
RUNTIME_PREFIX can be enabled.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18 20:00:14 +08:00
|
|
|
"but prefix computation failed. "
|
|
|
|
"Using static fallback '%s'.\n", prefix);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-01-18 20:00:09 +08:00
|
|
|
strbuf_addf(&d, "%s/%s", prefix, path);
|
2014-11-25 03:33:54 +08:00
|
|
|
return strbuf_detach(&d, NULL);
|
2008-07-14 04:31:18 +08:00
|
|
|
}
|
|
|
|
|
common-main: stop munging argv[0] path
Since 650c44925 (common-main: call git_extract_argv0_path(),
2016-07-01), the argv[0] that is seen in cmd_main() of
individual programs is always the basename of the
executable, as common-main strips off the full path. This
can produce confusing results for git-daemon, which wants to
re-exec itself.
For instance, if the program was originally run as
"/usr/lib/git/git-daemon", it will try just re-execing
"git-daemon", which will find the first instance in $PATH.
If git's exec-path has not been prepended to $PATH, we may
find the git-daemon from a different version (or no
git-daemon at all).
Normally this isn't a problem. Git commands are run as "git
daemon", the git wrapper puts the exec-path at the front of
$PATH, and argv[0] is already "daemon" anyway. But running
git-daemon via its full exec-path, while not really a
recommended method, did work prior to 650c44925. Let's make
it work again.
The real goal of 650c44925 was not to munge argv[0], but to
reliably set the argv0_path global. The only reason it
munges at all is that one caller, the git.c wrapper,
piggy-backed on that computation to find the command
basename. Instead, let's leave argv[0] untouched in
common-main, and have git.c do its own basename computation.
While we're at it, let's drop the return value from
git_extract_argv0_path(). It was only ever used in this one
callsite, and its dual purposes is what led to this
confusion in the first place.
Note that by changing the interface, the compiler can
confirm for us that there are no other callers storing the
return value. But the compiler can't tell us whether any of
the cmd_main() functions (besides git.c) were relying on the
basename munging. However, we can observe that prior to
650c44925, no other cmd_main() functions did that munging,
and no new cmd_main() functions have been introduced since
then. So we can't be regressing any of those cases.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-11-27 12:31:13 +08:00
|
|
|
void git_extract_argv0_path(const char *argv0)
|
2008-07-22 03:19:52 +08:00
|
|
|
{
|
2009-01-18 20:00:11 +08:00
|
|
|
const char *slash;
|
|
|
|
|
|
|
|
if (!argv0 || !*argv0)
|
common-main: stop munging argv[0] path
Since 650c44925 (common-main: call git_extract_argv0_path(),
2016-07-01), the argv[0] that is seen in cmd_main() of
individual programs is always the basename of the
executable, as common-main strips off the full path. This
can produce confusing results for git-daemon, which wants to
re-exec itself.
For instance, if the program was originally run as
"/usr/lib/git/git-daemon", it will try just re-execing
"git-daemon", which will find the first instance in $PATH.
If git's exec-path has not been prepended to $PATH, we may
find the git-daemon from a different version (or no
git-daemon at all).
Normally this isn't a problem. Git commands are run as "git
daemon", the git wrapper puts the exec-path at the front of
$PATH, and argv[0] is already "daemon" anyway. But running
git-daemon via its full exec-path, while not really a
recommended method, did work prior to 650c44925. Let's make
it work again.
The real goal of 650c44925 was not to munge argv[0], but to
reliably set the argv0_path global. The only reason it
munges at all is that one caller, the git.c wrapper,
piggy-backed on that computation to find the command
basename. Instead, let's leave argv[0] untouched in
common-main, and have git.c do its own basename computation.
While we're at it, let's drop the return value from
git_extract_argv0_path(). It was only ever used in this one
callsite, and its dual purposes is what led to this
confusion in the first place.
Note that by changing the interface, the compiler can
confirm for us that there are no other callers storing the
return value. But the compiler can't tell us whether any of
the cmd_main() functions (besides git.c) were relying on the
basename munging. However, we can observe that prior to
650c44925, no other cmd_main() functions did that munging,
and no new cmd_main() functions have been introduced since
then. So we can't be regressing any of those cases.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-11-27 12:31:13 +08:00
|
|
|
return;
|
2009-01-18 20:00:10 +08:00
|
|
|
|
2016-02-19 16:44:48 +08:00
|
|
|
slash = find_last_dir_sep(argv0);
|
2009-01-18 20:00:10 +08:00
|
|
|
|
common-main: stop munging argv[0] path
Since 650c44925 (common-main: call git_extract_argv0_path(),
2016-07-01), the argv[0] that is seen in cmd_main() of
individual programs is always the basename of the
executable, as common-main strips off the full path. This
can produce confusing results for git-daemon, which wants to
re-exec itself.
For instance, if the program was originally run as
"/usr/lib/git/git-daemon", it will try just re-execing
"git-daemon", which will find the first instance in $PATH.
If git's exec-path has not been prepended to $PATH, we may
find the git-daemon from a different version (or no
git-daemon at all).
Normally this isn't a problem. Git commands are run as "git
daemon", the git wrapper puts the exec-path at the front of
$PATH, and argv[0] is already "daemon" anyway. But running
git-daemon via its full exec-path, while not really a
recommended method, did work prior to 650c44925. Let's make
it work again.
The real goal of 650c44925 was not to munge argv[0], but to
reliably set the argv0_path global. The only reason it
munges at all is that one caller, the git.c wrapper,
piggy-backed on that computation to find the command
basename. Instead, let's leave argv[0] untouched in
common-main, and have git.c do its own basename computation.
While we're at it, let's drop the return value from
git_extract_argv0_path(). It was only ever used in this one
callsite, and its dual purposes is what led to this
confusion in the first place.
Note that by changing the interface, the compiler can
confirm for us that there are no other callers storing the
return value. But the compiler can't tell us whether any of
the cmd_main() functions (besides git.c) were relying on the
basename munging. However, we can observe that prior to
650c44925, no other cmd_main() functions did that munging,
and no new cmd_main() functions have been introduced since
then. So we can't be regressing any of those cases.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-11-27 12:31:13 +08:00
|
|
|
if (slash)
|
2009-01-18 20:00:10 +08:00
|
|
|
argv0_path = xstrndup(argv0, slash - argv0);
|
2008-07-22 03:19:52 +08:00
|
|
|
}
|
|
|
|
|
2007-10-27 16:36:51 +08:00
|
|
|
void git_set_argv_exec_path(const char *exec_path)
|
2006-01-11 10:12:17 +08:00
|
|
|
{
|
2007-10-27 16:36:51 +08:00
|
|
|
argv_exec_path = exec_path;
|
Propagate --exec-path setting to external commands via GIT_EXEC_PATH
Let PATH0=$PATH that was set before the invocation.
Let /foo be a build directory.
Let /pfx be the installation prefix.
Let pfxexecpath=/pfx/libexec/git-core.
The following is going on when 'git --exec-path=/foo gc' is invoked:
1. git sets PATH=/foo:$PATH0 using the path from --exec-path
2. gc execs 'git repack' (note: no dash).
3. Since there is a git in /foo (it's a build directory), /foo/git is
taken.
4. No explicit exec-path is set this time, hence, this secondary git sets
PATH=$pfxexecpath:/foo:$PATH
5. Since 'repack' is not a built-in, execv_dashed_external execs
'git-repack' (note: dash).
6. There is a $pfxexecpath/git-repack, and it is taken.
7. This git-repack runs 'git pack-objects' (note: no dash).
8. There is no git in $pfxexecpath, but there is one in /foo. Hence,
/foo/git is run.
9. pack-objects is a builtin, hence, in effect /foo/git-pack-objects
is run.
As you can see, the way in which we previously set the PATH allowed to
mix gits of different vintage. By setting GIT_EXEC_PATH when --exec-path
was given on the command line, we reduce the confusion.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-22 06:21:18 +08:00
|
|
|
/*
|
|
|
|
* Propagate this setting to external programs.
|
|
|
|
*/
|
|
|
|
setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
|
2006-01-11 10:12:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Returns the highest-priority, location to look for git programs. */
|
2006-02-26 23:13:46 +08:00
|
|
|
const char *git_exec_path(void)
|
2006-01-11 10:12:17 +08:00
|
|
|
{
|
2017-01-09 14:00:12 +08:00
|
|
|
static char *cached_exec_path;
|
2006-01-11 10:12:17 +08:00
|
|
|
|
2007-10-27 16:36:51 +08:00
|
|
|
if (argv_exec_path)
|
|
|
|
return argv_exec_path;
|
2006-01-11 10:12:17 +08:00
|
|
|
|
2017-01-09 14:00:12 +08:00
|
|
|
if (!cached_exec_path) {
|
|
|
|
const char *env = getenv(EXEC_PATH_ENVIRONMENT);
|
|
|
|
if (env && *env)
|
|
|
|
cached_exec_path = xstrdup(env);
|
|
|
|
else
|
|
|
|
cached_exec_path = system_path(GIT_EXEC_PATH);
|
2006-01-11 10:12:17 +08:00
|
|
|
}
|
2017-01-09 14:00:12 +08:00
|
|
|
return cached_exec_path;
|
2006-01-11 10:12:17 +08:00
|
|
|
}
|
|
|
|
|
2007-10-28 19:17:20 +08:00
|
|
|
static void add_path(struct strbuf *out, const char *path)
|
|
|
|
{
|
|
|
|
if (path && *path) {
|
2014-07-29 02:34:42 +08:00
|
|
|
strbuf_add_absolute_path(out, path);
|
2007-12-04 04:55:57 +08:00
|
|
|
strbuf_addch(out, PATH_SEP);
|
2007-10-28 19:17:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-22 03:19:52 +08:00
|
|
|
void setup_path(void)
|
2007-10-28 19:17:20 +08:00
|
|
|
{
|
|
|
|
const char *old_path = getenv("PATH");
|
2008-10-10 03:12:12 +08:00
|
|
|
struct strbuf new_path = STRBUF_INIT;
|
2007-10-28 19:17:20 +08:00
|
|
|
|
Modify setup_path() to only add git_exec_path() to PATH
Searching git programs only in the highest priority location is
sufficient. It does not make sense that some of the required
programs are located at the highest priority location but other
programs are picked up from a lower priority exec-path. If
exec-path is overridden a complete set of commands should be
provided, otherwise several different versions could get mixed,
which is likely to cause confusion.
If a user explicitly overrides the default location (by --exec-path
or GIT_EXEC_PATH), we now expect that all the required programs are
found there. Instead of adding the directories "argv_exec_path",
"getenv(EXEC_PATH_ENVIRONMENT)", and "system_path(GIT_EXEC_PATH)"
to PATH, we now rely on git_exec_path(), which implements the same
order, but only returns the highest priority location to search for
executables.
Accessing only the location with highest priority is also required
for testing executables built with RUNTIME_PREFIX. The call to
system_path() should be avoided if RUNTIME_PREFIX is set and the
executable is not installed at its final destination. Because we
test before installing, we want to avoid calling system_path()
during tests. The modifications in this commit avoid calling
system_path(GIT_EXEC_PATH) if a higher-priority location is
provided, which is the case when running the tests.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18 20:00:13 +08:00
|
|
|
add_path(&new_path, git_exec_path());
|
2007-10-28 19:17:20 +08:00
|
|
|
|
|
|
|
if (old_path)
|
|
|
|
strbuf_addstr(&new_path, old_path);
|
|
|
|
else
|
2010-04-13 17:07:13 +08:00
|
|
|
strbuf_addstr(&new_path, _PATH_DEFPATH);
|
2007-10-28 19:17:20 +08:00
|
|
|
|
|
|
|
setenv("PATH", new_path.buf, 1);
|
|
|
|
|
|
|
|
strbuf_release(&new_path);
|
|
|
|
}
|
2006-01-11 10:12:17 +08:00
|
|
|
|
prepare_{git,shell}_cmd: use argv_array
These functions transform an existing argv into one suitable
for exec-ing or spawning via git or a shell. We can use an
argv_array in each to avoid dealing with manual counting and
allocation.
This also makes the memory allocation more clear and fixes
some leaks. In prepare_shell_cmd, we would sometimes
allocate a new string with "$@" in it and sometimes not,
meaning the caller could not correctly free it. On the
non-Windows side, we are in a child process which will
exec() or exit() immediately, so the leak isn't a big deal.
On Windows, though, we use spawn() from the parent process,
and leak a string for each shell command we run. On top of
that, the Windows code did not free the allocated argv array
at all (but does for the prepare_git_cmd case!).
By switching both of these functions to write into an
argv_array, we can consistently free the result as
appropriate.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:44:39 +08:00
|
|
|
const char **prepare_git_cmd(struct argv_array *out, const char **argv)
|
2006-01-11 10:12:17 +08:00
|
|
|
{
|
prepare_{git,shell}_cmd: use argv_array
These functions transform an existing argv into one suitable
for exec-ing or spawning via git or a shell. We can use an
argv_array in each to avoid dealing with manual counting and
allocation.
This also makes the memory allocation more clear and fixes
some leaks. In prepare_shell_cmd, we would sometimes
allocate a new string with "$@" in it and sometimes not,
meaning the caller could not correctly free it. On the
non-Windows side, we are in a child process which will
exec() or exit() immediately, so the leak isn't a big deal.
On Windows, though, we use spawn() from the parent process,
and leak a string for each shell command we run. On top of
that, the Windows code did not free the allocated argv array
at all (but does for the prepare_git_cmd case!).
By switching both of these functions to write into an
argv_array, we can consistently free the result as
appropriate.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:44:39 +08:00
|
|
|
argv_array_push(out, "git");
|
|
|
|
argv_array_pushv(out, argv);
|
|
|
|
return out->argv;
|
2008-07-28 13:50:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int execv_git_cmd(const char **argv) {
|
prepare_{git,shell}_cmd: use argv_array
These functions transform an existing argv into one suitable
for exec-ing or spawning via git or a shell. We can use an
argv_array in each to avoid dealing with manual counting and
allocation.
This also makes the memory allocation more clear and fixes
some leaks. In prepare_shell_cmd, we would sometimes
allocate a new string with "$@" in it and sometimes not,
meaning the caller could not correctly free it. On the
non-Windows side, we are in a child process which will
exec() or exit() immediately, so the leak isn't a big deal.
On Windows, though, we use spawn() from the parent process,
and leak a string for each shell command we run. On top of
that, the Windows code did not free the allocated argv array
at all (but does for the prepare_git_cmd case!).
By switching both of these functions to write into an
argv_array, we can consistently free the result as
appropriate.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:44:39 +08:00
|
|
|
struct argv_array nargv = ARGV_ARRAY_INIT;
|
|
|
|
|
|
|
|
prepare_git_cmd(&nargv, argv);
|
|
|
|
trace_argv_printf(nargv.argv, "trace: exec:");
|
2006-06-25 21:56:18 +08:00
|
|
|
|
2007-10-28 19:17:20 +08:00
|
|
|
/* execvp() can only ever return if it fails */
|
prepare_{git,shell}_cmd: use argv_array
These functions transform an existing argv into one suitable
for exec-ing or spawning via git or a shell. We can use an
argv_array in each to avoid dealing with manual counting and
allocation.
This also makes the memory allocation more clear and fixes
some leaks. In prepare_shell_cmd, we would sometimes
allocate a new string with "$@" in it and sometimes not,
meaning the caller could not correctly free it. On the
non-Windows side, we are in a child process which will
exec() or exit() immediately, so the leak isn't a big deal.
On Windows, though, we use spawn() from the parent process,
and leak a string for each shell command we run. On top of
that, the Windows code did not free the allocated argv array
at all (but does for the prepare_git_cmd case!).
By switching both of these functions to write into an
argv_array, we can consistently free the result as
appropriate.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:44:39 +08:00
|
|
|
sane_execvp("git", (char **)nargv.argv);
|
2006-01-11 10:12:17 +08:00
|
|
|
|
2007-10-28 19:17:20 +08:00
|
|
|
trace_printf("trace: exec failed: %s\n", strerror(errno));
|
2006-06-25 21:56:18 +08:00
|
|
|
|
prepare_{git,shell}_cmd: use argv_array
These functions transform an existing argv into one suitable
for exec-ing or spawning via git or a shell. We can use an
argv_array in each to avoid dealing with manual counting and
allocation.
This also makes the memory allocation more clear and fixes
some leaks. In prepare_shell_cmd, we would sometimes
allocate a new string with "$@" in it and sometimes not,
meaning the caller could not correctly free it. On the
non-Windows side, we are in a child process which will
exec() or exit() immediately, so the leak isn't a big deal.
On Windows, though, we use spawn() from the parent process,
and leak a string for each shell command we run. On top of
that, the Windows code did not free the allocated argv array
at all (but does for the prepare_git_cmd case!).
By switching both of these functions to write into an
argv_array, we can consistently free the result as
appropriate.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:44:39 +08:00
|
|
|
argv_array_clear(&nargv);
|
2007-10-28 19:17:20 +08:00
|
|
|
return -1;
|
2006-01-11 10:12:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-05 18:47:29 +08:00
|
|
|
int execl_git_cmd(const char *cmd,...)
|
2006-01-11 10:12:17 +08:00
|
|
|
{
|
|
|
|
int argc;
|
2006-03-05 18:47:29 +08:00
|
|
|
const char *argv[MAX_ARGS + 1];
|
|
|
|
const char *arg;
|
2006-01-11 10:12:17 +08:00
|
|
|
va_list param;
|
|
|
|
|
|
|
|
va_start(param, cmd);
|
|
|
|
argv[0] = cmd;
|
|
|
|
argc = 1;
|
|
|
|
while (argc < MAX_ARGS) {
|
|
|
|
arg = argv[argc++] = va_arg(param, char *);
|
|
|
|
if (!arg)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
va_end(param);
|
|
|
|
if (MAX_ARGS <= argc)
|
|
|
|
return error("too many args to run %s", cmd);
|
|
|
|
|
|
|
|
argv[argc] = NULL;
|
|
|
|
return execv_git_cmd(argv);
|
|
|
|
}
|