Files
git/spawn-pipe.c
Steffen Prohaska 69cadd4e60 Merge commit 'mingw/master' into msysgit/merge-mingw-v2
Conflicts:

	Makefile
	RelNotes
	builtin-ls-files.c
	builtin-tag.c
	cache.h
	compat/mingw.c
	config.c
	connect.c
	cpio.sh
	diff.c
	exec_cmd.c
	git-gui/Makefile
	git-gui/lib/commit.tcl
	git-gui/lib/console.tcl
	git-mergetool.sh
	lockfile.c
	path.c
	rsh.c
	run-command.c
	setup.c
	show-index.c
	spawn-pipe.c
	t/Makefile
	t/t0000-basic.sh
	t/t1300-repo-config.sh
	t/t7501-commit.sh
	t/test-lib.sh

    Resolve as follows
    --- Makefile
    - mingw/devel removes
        SHELL_PATH = /bin/sh
        PERL_PATH = /bin/perl

    This looks ok. Both are set early in the Makefile to sensible values.
    mingw accepts to execute /usr/bin/perl.

    - NO_SYMLINKS is no longer needed. Should be auto-detected.

    - According to our 0e2bdc35af
      we want

    NO_R_TO_GCC_LINKER = YesPlease

      take our before their change.

    - Conflict prefix, SCRIPT_SH:
    our 7999f434d7 set prefix =
    their 4a7c98dbaf removes cpio emulator

    resolve to achieve both.

    - Conflict NO_MEMMEM, THREADED_DELTA_SEARCH: take theirs

    --- RelNotes
    take our: removed file

    --- builtin-ls-files.c
    Conflict write_name_quoted: take their change.

    --- builtin-tag.c
    Conflict strip CR

    our 7734ad404c adds strip CR
    their fd17f5b5f7 modifies code to use strbuf

    resolve by removing our code. TODO: we probably need a replacement?

    --- cache.h
    Conflict is_absolute_path()
    our ef5af72062 ifdef
    their 637fc51696 ifndef
    both achieve the same.

    our is a bit more strict but we take their code because we want
    to reduce differences to mingw.

    --- compat/mingw.c
    Conflict at end of file:
    our 194c1dbb5a adds git_exit()

    resolve by taking their first, followed by our.

    --- config.c
    Conflict 'fd ='
    our 0a453a237e merge junio/master
    introduced strange 'fd ='. Resolve by removing 'fd ='.

    --- connect.c
    - Conflict 'host must have at least 2 chars ...' take their code.

    - git_connect(): take their implementation.

    --- cpio.sh
    Accepted their delete file.

    --- diff.c
    Resolve using their implementation.

    --- exec_cmd.c
    Resolve using their implementation.

    --- git-gui/**
    Resolve using our implementation.

    --- git-mergetool.sh
    Resolve using their implementation

    --- lockfile.c
    trivial resolution (empty line removed)

    --- path.c
    Conflict 'tmp': accepting their implementation, trying TMP, TEMP on all platforms.

    --- rsh.c
    Accept their delete file.

    --- run-command.c
    Resolve using their implementation

    --- setup.c
    Resolve using their implementation

    --- show-index.c
    Conflict PRIuMAX
    our 89697a4c15 fix warning
    their 5be507fc95 PRIuMAX

    resolve fixing warning in their code.

    --- spawn-pipe.c
    Conflict environ vs lookup_prog: resolve taking neither

    --- t/Makefile
    our d1f83218dc --no-hardlinks
    their c603988c10 automtically detect symlink support

    Resolve using our --no-hardlinks but removing --no-symlinks.

    --- t/0000-basic.sh
    Resolve using their implementation.

    --- t/t1300-repo-config.sh
    Resolve using their implementation.

    --- t/t7501-commit.sh
    Resolve using their implementation.

    --- t/test-lib.sh
    our d1f83218dc --no-hardlink
    their c603988c10 automatically detect symlink support

    Resolve using our --no-hardlinks but removing --no-symlinks.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
2007-11-05 21:55:44 +01:00

170 lines
3.3 KiB
C

#include "git-compat-util.h"
#include "spawn-pipe.h"
/* cmd specifies the command to invoke.
* argv specifies its arguments; argv[0] will be replaced by the basename of cmd.
* env specifies the environment.
* pin and pout specify pipes; the read end of pin is made the standard input
* of the spawned process, and the write end of pout is mad the standard output.
* The respective unused ends of the pipes are closed both in the parent
* process as well as in the child process.
* Anyone of pin or pout can be NULL, or any one of the ends can be -1 to
* indicate that no processing shall occur.
*/
int spawnvpe_pipe(const char *cmd, const char **argv, const char **env,
int pin[], int pout[])
{
#ifdef __MINGW32__
char **path = mingw_get_path_split();
pid_t pid = spawnvppe_pipe(cmd, argv, env, path, pin, pout);
mingw_free_path_split(path);
#else
pid_t pid = spawnvppe_pipe(cmd, argv, env, NULL, pin, pout);
#endif
return pid;
}
int spawnvppe_pipe(const char *cmd, const char **argv, const char **env,
char **path,
int pin[], int pout[])
{
const char *cmd_basename = strrchr(cmd, '/');
const char *argv0 = argv[0];
pid_t pid;
#ifdef __MINGW32__
int s0 = -1, s1 = -1, argc;
char *prog;
const char **qargv, *interpr;
if (!cmd_basename)
cmd_basename = strrchr(cmd, '\\');
#endif
if (!cmd_basename)
cmd_basename = cmd;
else
cmd_basename++;
argv[0] = cmd_basename;
#ifndef __MINGW32__
pid = fork();
if (pid < 0)
die("unable to fork");
if (!pid) {
if (pin) {
if (pin[0] >= 0) {
dup2(pin[0], 0);
close(pin[0]);
}
if (pin[1] >= 0)
close(pin[1]);
}
if (pout) {
if (pout[1] >= 0) {
dup2(pout[1], 1);
close(pout[1]);
}
if (pout[0] >= 0)
close(pout[0]);
}
environ = env;
execvp(cmd, argv);
die("exec failed");
}
if (pin && pin[0] >= 0)
close(pin[0]);
if (pout && pout[1] >= 1)
close(pout[1]);
#else
if (pin) {
if (pin[0] >= 0) {
s0 = dup(0);
dup2(pin[0], 0);
close(pin[0]);
}
}
if (pout) {
if (pout[1] >= 0) {
s1 = dup(1);
dup2(pout[1], 1);
close(pout[1]);
}
}
prog = mingw_path_lookup(cmd, path);
interpr = parse_interpreter(prog);
for (argc = 0; argv[argc];) argc++;
qargv = xmalloc((argc+2)*sizeof(char*));
if (!interpr) {
quote_argv(qargv, argv);
pid = spawnve(_P_NOWAIT, prog, qargv, (const char**) env);
} else {
qargv[0] = interpr;
argv[0] = prog;
quote_argv(&qargv[1], argv);
pid = spawnvpe(_P_NOWAIT, interpr, qargv, env);
}
free(qargv); /* TODO: quoted args should be freed, too */
free(prog);
if (s0 >= 0) {
dup2(s0, 0);
close(s0);
}
if (s1 >= 0) {
dup2(s1, 1);
close(s1);
}
#endif
argv[0] = argv0;
return pid;
}
const char **copy_environ()
{
return copy_env( (const char**)environ);
}
const char **copy_env(const char **env)
{
const char **s;
int n = 1;
for (s = env; *s; s++)
n++;
s = xmalloc(n*sizeof(const char *));
memcpy(s, env, n*sizeof(const char *));
return s;
}
void env_unsetenv(const char **env, const char *name)
{
int src, dst;
size_t nmln;
nmln = strlen(name);
for (src = dst = 0; env[src]; ++src) {
size_t enln;
enln = strlen(env[src]);
if (enln > nmln) {
/* might match, and can test for '=' safely */
if (0 == strncmp (env[src], name, nmln)
&& '=' == env[src][nmln])
/* matches, so skip */
continue;
}
env[dst] = env[src];
++dst;
}
env[dst] = NULL;
}