| diff --git a/Makefile b/Makefile |
| --- a/Makefile |
| +++ b/Makefile |
| @@ -898,14 +898,22 @@ BUILTIN_OBJS += builtin/verify-tag.o |
| BUILTIN_OBJS += builtin/write-tree.o |
| |
| GITLIBS = $(LIB_FILE) $(XDIFF_LIB) |
| -EXTLIBS = |
| +EXTLIBS ?= |
| |
| GIT_USER_AGENT = git/$(GIT_VERSION) |
| |
| +ifdef CROSS_COMPILE |
| +HAVE_DEV_TTY = YesPlease |
| +NEEDS_SSL_WITH_CRYPTO = YesPlease |
| +NEEDS_SSL_WITH_CURL = YesPlease |
| +else |
| include config.mak.uname |
| +endif |
| -include config.mak.autogen |
| -include config.mak |
| |
| +CCLD = $(CC) |
| + |
| ifndef sysconfdir |
| ifeq ($(prefix),/usr) |
| sysconfdir = /etc |
| @@ -1407,8 +1415,10 @@ endif |
| |
| ifdef HAVE_CLOCK_GETTIME |
| BASIC_CFLAGS += -DHAVE_CLOCK_GETTIME |
| +ifndef NO_RT_LIBRARY |
| EXTLIBS += -lrt |
| endif |
| +endif |
| |
| ifdef HAVE_CLOCK_MONOTONIC |
| BASIC_CFLAGS += -DHAVE_CLOCK_MONOTONIC |
| @@ -1642,7 +1652,7 @@ git.sp git.s git.o: EXTRA_CPPFLAGS = \ |
| '-DGIT_INFO_PATH="$(infodir_relative_SQ)"' |
| |
| git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) git.o \ |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) git.o \ |
| $(BUILTIN_OBJS) $(LIBS) |
| |
| help.sp help.s help.o: common-cmds.h |
| @@ -1660,7 +1670,6 @@ version.sp version.s version.o: EXTRA_CPPFLAGS = \ |
| |
| $(BUILT_INS): git$X |
| $(QUIET_BUILT_IN)$(RM) $@ && \ |
| - ln $< $@ 2>/dev/null || \ |
| ln -s $< $@ 2>/dev/null || \ |
| cp $< $@ |
| |
| @@ -1931,32 +1940,31 @@ compat/nedmalloc/nedmalloc.sp: SPARSE_FLAGS += -Wno-non-pointer-null |
| endif |
| |
| git-%$X: %.o GIT-LDFLAGS $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) |
| |
| git-imap-send$X: imap-send.o $(IMAP_SEND_BUILDDEPS) GIT-LDFLAGS $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| - $(LIBS) $(IMAP_SEND_LDFLAGS) |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| + $(IMAP_SEND_LDFLAGS) $(LIBS) |
| |
| git-http-fetch$X: http.o http-walker.o http-fetch.o GIT-LDFLAGS $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| - $(LIBS) $(CURL_LIBCURL) |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| + $(CURL_LIBCURL) $(LIBS) |
| git-http-push$X: http.o http-push.o GIT-LDFLAGS $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| - $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| + $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIBS) |
| |
| git-remote-testsvn$X: remote-testsvn.o GIT-LDFLAGS $(GITLIBS) $(VCSSVN_LIB) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) \ |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) \ |
| $(VCSSVN_LIB) |
| |
| $(REMOTE_CURL_ALIASES): $(REMOTE_CURL_PRIMARY) |
| $(QUIET_LNCP)$(RM) $@ && \ |
| - ln $< $@ 2>/dev/null || \ |
| ln -s $< $@ 2>/dev/null || \ |
| cp $< $@ |
| |
| $(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o GIT-LDFLAGS $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| - $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ |
| + $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(EXTLIBS) |
| |
| $(LIB_FILE): $(LIB_OBJS) |
| $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $^ |
| @@ -2169,7 +2177,7 @@ test-svn-fe$X: vcs-svn/lib.a |
| .PRECIOUS: $(TEST_OBJS) |
| |
| test-%$X: test-%.o GIT-LDFLAGS $(GITLIBS) |
| - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) |
| + $(QUIET_LINK)$(CCLD) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) |
| |
| check-sha1:: test-sha1$X |
| ./test-sha1.sh |
| @@ -2264,14 +2272,12 @@ endif |
| for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \ |
| $(RM) "$$bindir/$$p" && \ |
| test -z "$(NO_INSTALL_HARDLINKS)" && \ |
| - ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \ |
| ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \ |
| cp "$$bindir/git$X" "$$bindir/$$p" || exit; \ |
| done && \ |
| for p in $(BUILT_INS); do \ |
| $(RM) "$$execdir/$$p" && \ |
| test -z "$(NO_INSTALL_HARDLINKS)" && \ |
| - ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \ |
| ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \ |
| cp "$$execdir/git$X" "$$execdir/$$p" || exit; \ |
| done && \ |
| @@ -2279,7 +2285,6 @@ endif |
| for p in $$remote_curl_aliases; do \ |
| $(RM) "$$execdir/$$p" && \ |
| test -z "$(NO_INSTALL_HARDLINKS)" && \ |
| - ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ |
| ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ |
| cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; \ |
| done && \ |
| diff --git a/builtin/log.c b/builtin/log.c |
| --- a/builtin/log.c |
| +++ b/builtin/log.c |
| @@ -229,7 +229,9 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr) |
| printf(_("Final output: %d %s\n"), nr, stage); |
| } |
| |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| static struct itimerval early_output_timer; |
| +#endif |
| |
| static void log_show_early(struct rev_info *revs, struct commit_list *list) |
| { |
| @@ -271,9 +273,12 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list) |
| * trigger every second even if we're blocked on a |
| * reader! |
| */ |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| + /* TODO(bradnelson): Turn this back on once nacl_io supports it. */ |
| early_output_timer.it_value.tv_sec = 0; |
| early_output_timer.it_value.tv_usec = 500000; |
| setitimer(ITIMER_REAL, &early_output_timer, NULL); |
| +#endif |
| } |
| |
| static void early_output(int signal) |
| @@ -292,11 +297,14 @@ static void setup_early_output(struct rev_info *rev) |
| * system dependencies and headers), and using |
| * SA_RESTART. |
| */ |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| + /* TODO(bradnelson): Turn this back on once nacl_io supports it. */ |
| memset(&sa, 0, sizeof(sa)); |
| sa.sa_handler = early_output; |
| sigemptyset(&sa.sa_mask); |
| sa.sa_flags = SA_RESTART; |
| sigaction(SIGALRM, &sa, NULL); |
| +#endif |
| |
| /* |
| * If we can get the whole output in less than a |
| @@ -305,9 +313,12 @@ static void setup_early_output(struct rev_info *rev) |
| * |
| * This is a one-time-only trigger. |
| */ |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| + /* TODO(bradnelson): Turn this back on once nacl_io supports it. */ |
| early_output_timer.it_value.tv_sec = 0; |
| early_output_timer.it_value.tv_usec = 100000; |
| setitimer(ITIMER_REAL, &early_output_timer, NULL); |
| +#endif |
| } |
| |
| static void finish_early_output(struct rev_info *rev) |
| diff --git a/compat/nacl.c b/compat/nacl.c |
| new file mode 100644 |
| --- /dev/null |
| +++ b/compat/nacl.c |
| @@ -0,0 +1,73 @@ |
| +static char **copy_environ(void) |
| +{ |
| + char **env; |
| + int i = 0; |
| + while (environ[i]) |
| + i++; |
| + env = xmalloc((i+1)*sizeof(*env)); |
| + for (i = 0; environ[i]; i++) |
| + env[i] = xstrdup(environ[i]); |
| + env[i] = NULL; |
| + return env; |
| +} |
| + |
| +void free_environ(char **env) |
| +{ |
| + int i; |
| + for (i = 0; env[i]; i++) |
| + free(env[i]); |
| + free(env); |
| +} |
| + |
| +static int lookup_env(char **env, const char *name, size_t nmln) |
| +{ |
| + int i; |
| + |
| + for (i = 0; env[i]; i++) { |
| + if (0 == strncmp(env[i], name, nmln) |
| + && '=' == env[i][nmln]) |
| + /* matches */ |
| + return i; |
| + } |
| + return -1; |
| +} |
| + |
| +/* |
| + * If name contains '=', then sets the variable, otherwise it unsets it |
| + */ |
| +static char **env_setenv(char **env, const char *name) |
| +{ |
| + char *eq = strchrnul(name, '='); |
| + int i = lookup_env(env, name, eq-name); |
| + |
| + if (i < 0) { |
| + if (*eq) { |
| + for (i = 0; env[i]; i++) |
| + ; |
| + env = xrealloc(env, (i+2)*sizeof(*env)); |
| + env[i] = xstrdup(name); |
| + env[i+1] = NULL; |
| + } |
| + } |
| + else { |
| + free(env[i]); |
| + if (*eq) |
| + env[i] = xstrdup(name); |
| + else |
| + for (; env[i]; i++) |
| + env[i] = env[i+1]; |
| + } |
| + return env; |
| +} |
| + |
| +/* |
| + * Copies global environ and adjusts variables as specified by vars. |
| + */ |
| +char **make_augmented_environ(const char *const *vars) |
| +{ |
| + char **env = copy_environ(); |
| + |
| + while (*vars) |
| + env = env_setenv(env, *vars++); |
| + return env; |
| +} |
| diff --git a/configure.ac b/configure.ac |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -616,11 +616,13 @@ GIT_CONF_SUBST([NO_DEFLATE_BOUND]) |
| # |
| # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, |
| # Patrick Mauritz). |
| -AC_CHECK_LIB([c], [socket], |
| -[NEEDS_SOCKET=], |
| -[NEEDS_SOCKET=YesPlease]) |
| -GIT_CONF_SUBST([NEEDS_SOCKET]) |
| -test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket" |
| +# TODO(bradnelson): Do this just for NaCl newlib. |
| +#AC_CHECK_LIB([c], [socket], |
| +#[NEEDS_SOCKET=], |
| +#[NEEDS_SOCKET=YesPlease]) |
| +#GIT_CONF_SUBST([NEEDS_SOCKET]) |
| +#test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket" |
| +NEEDS_SOCKET= |
| |
| # |
| # The next few tests will define NEEDS_RESOLV if linking with |
| @@ -673,7 +675,8 @@ AC_CHECK_LIB([c], [basename], |
| [NEEDS_LIBGEN=], |
| [NEEDS_LIBGEN=YesPlease]) |
| GIT_CONF_SUBST([NEEDS_LIBGEN]) |
| -test -n "$NEEDS_LIBGEN" && LIBS="$LIBS -lgen" |
| +# TODO(bradnelson): Do this just for NaCl newlib. |
| +#test -n "$NEEDS_LIBGEN" && LIBS="$LIBS -lgen" |
| |
| AC_CHECK_LIB([c], [gettext], |
| [LIBC_CONTAINS_LIBINTL=YesPlease], |
| @@ -844,7 +847,8 @@ AC_RUN_IFELSE( |
| FILE *f = fopen(".", "r"); |
| return f && fread(&c, 1, 1, f)]])], |
| [ac_cv_fread_reads_directories=no], |
| - [ac_cv_fread_reads_directories=yes]) |
| + [ac_cv_fread_reads_directories=yes], |
| + [ac_cv_fread_reads_directories=no]) |
| ]) |
| if test $ac_cv_fread_reads_directories = yes; then |
| FREAD_READS_DIRECTORIES=UnfortunatelyYes |
| @@ -878,7 +882,8 @@ AC_RUN_IFELSE( |
| if (snprintf(buf, 3, "%s", "12345") != 5 |
| || strcmp(buf, "12")) return 1]])], |
| [ac_cv_snprintf_returns_bogus=no], |
| - [ac_cv_snprintf_returns_bogus=yes]) |
| + [ac_cv_snprintf_returns_bogus=yes], |
| + [ac_cv_snprintf_returns_bogus=no]) |
| ]) |
| if test $ac_cv_snprintf_returns_bogus = yes; then |
| SNPRINTF_RETURNS_BOGUS=UnfortunatelyYes |
| diff --git a/daemon.c b/daemon.c |
| --- a/daemon.c |
| +++ b/daemon.c |
| @@ -66,7 +66,9 @@ static void logreport(int priority, const char *err, va_list params) |
| if (log_syslog) { |
| char buf[1024]; |
| vsnprintf(buf, sizeof(buf), err, params); |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| syslog(priority, "%s", buf); |
| +#endif |
| } else { |
| /* |
| * Since stderr is set to buffered mode, the |
| @@ -1247,7 +1253,9 @@ int main(int argc, char **argv) |
| } |
| |
| if (log_syslog) { |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| openlog("git-daemon", LOG_PID, LOG_DAEMON); |
| +#endif |
| set_die_routine(daemon_die); |
| } else |
| /* avoid splitting a message in the middle */ |
| diff --git a/fast-import.c b/fast-import.c |
| --- a/fast-import.c |
| +++ b/fast-import.c |
| @@ -527,6 +527,8 @@ static void checkpoint_signal(int signo) |
| |
| static void set_checkpoint_signal(void) |
| { |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| + /* TODO(bradnelson): Reenable when nacl_io can do this. */ |
| struct sigaction sa; |
| |
| memset(&sa, 0, sizeof(sa)); |
| @@ -534,6 +536,7 @@ static void set_checkpoint_signal(void) |
| sigemptyset(&sa.sa_mask); |
| sa.sa_flags = SA_RESTART; |
| sigaction(SIGUSR1, &sa, NULL); |
| +#endif |
| } |
| |
| #endif |
| diff --git a/fetch-pack.c b/fetch-pack.c |
| --- a/fetch-pack.c |
| +++ b/fetch-pack.c |
| @@ -649,11 +649,23 @@ static int everything_local(struct fetch_pack_args *args, |
| return retval; |
| } |
| |
| +/* |
| + * TODO(bradnelson): Remove when corruption figured out. |
| + * Adding synchronization to backgroun demuxer. |
| + */ |
| +#include <semaphore.h> |
| +static sem_t holdup; |
| + |
| static int sideband_demux(int in, int out, void *data) |
| { |
| int *xd = data; |
| |
| int ret = recv_sideband("fetch-pack", xd[0], out); |
| + /* |
| + * TODO(bradnelson): Remove when corruption figured out. |
| + * Adding synchronization to backgroun demuxer. |
| + */ |
| + sem_post(&holdup); |
| close(out); |
| return ret; |
| } |
| @@ -670,6 +682,11 @@ static int get_pack(struct fetch_pack_args *args, |
| struct child_process cmd = CHILD_PROCESS_INIT; |
| int ret; |
| |
| + /* |
| + * TODO(bradnelson): Remove when corruption figured out. |
| + * Adding synchronization to backgroun demuxer. |
| + */ |
| + sem_init(&holdup, 0, 0); |
| memset(&demux, 0, sizeof(demux)); |
| if (use_sideband) { |
| /* xd[] is talking with upload-pack; subprocess reads from |
| @@ -682,6 +699,11 @@ static int get_pack(struct fetch_pack_args *args, |
| if (start_async(&demux)) |
| die("fetch-pack: unable to fork off sideband" |
| " demultiplexer"); |
| + /* |
| + * TODO(bradnelson): Remove when corruption figured out. |
| + * Adding synchronization to backgroun demuxer. |
| + */ |
| + sem_wait(&holdup); |
| } |
| else |
| demux.out = xd[0]; |
| diff --git a/git-compat-util.h b/git-compat-util.h |
| --- a/git-compat-util.h |
| +++ b/git-compat-util.h |
| @@ -796,8 +796,8 @@ void git_qsort(void *base, size_t nmemb, size_t size, |
| #define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec)) |
| #define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec)) |
| #else |
| -#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec)) |
| -#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec)) |
| +#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctime)) |
| +#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtime)) |
| #endif |
| #endif |
| |
| @@ -870,4 +870,12 @@ struct tm *git_gmtime_r(const time_t *, struct tm *); |
| #define gmtime_r git_gmtime_r |
| #endif |
| |
| +#if defined(__native_client__) && !defined(__GLIBC__) |
| +#define gethostname(dst, len) strcpy(dst, "localhost") |
| +#define getservbyname(dst, len) 0 |
| +#define setsid(n) 0 |
| +#define alarm(n) 0 |
| +#define getgrnam(n) 0 |
| +#endif |
| + |
| #endif |
| diff --git a/progress.c b/progress.c |
| --- a/progress.c |
| +++ b/progress.c |
| @@ -47,6 +47,8 @@ static void progress_interval(int signum) |
| |
| static void set_progress_signal(void) |
| { |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| + /* TODO(bradnelson): Renable when nacl_io can do this. */ |
| struct sigaction sa; |
| struct itimerval v; |
| |
| @@ -62,14 +64,18 @@ static void set_progress_signal(void) |
| v.it_interval.tv_usec = 0; |
| v.it_value = v.it_interval; |
| setitimer(ITIMER_REAL, &v, NULL); |
| +#endif |
| } |
| |
| static void clear_progress_signal(void) |
| { |
| +#if !defined(__native_client__) || defined(__GLIBC__) |
| + /* TODO(bradnelson): Renable when nacl_io can do this. */ |
| struct itimerval v = {{0,},}; |
| setitimer(ITIMER_REAL, &v, NULL); |
| signal(SIGALRM, SIG_IGN); |
| progress_update = 0; |
| +#endif |
| } |
| |
| static int display(struct progress *progress, unsigned n, const char *done) |
| diff --git a/run-command.c b/run-command.c |
| --- a/run-command.c |
| +++ b/run-command.c |
| @@ -4,6 +4,11 @@ |
| #include "sigchain.h" |
| #include "argv-array.h" |
| |
| +#if defined(__native_client__) |
| +# include <spawn.h> |
| +# include "compat/nacl.c" |
| +#endif |
| + |
| #ifndef SHELL_PATH |
| # define SHELL_PATH "/bin/sh" |
| #endif |
| @@ -91,6 +96,36 @@ static inline void dup_devnull(int to) |
| } |
| #endif |
| |
| +#ifdef GIT_WINDOWS_NATIVE |
| +static int open_devnull(int write) |
| +{ |
| + if (write) { |
| + return open("/dev/null", O_WRONLY); |
| + } else { |
| + return open("/dev/null", O_RDONLY); |
| + } |
| +} |
| +#endif |
| + |
| +#if defined(__native_client__) |
| +static int open_devnull(int write) |
| +{ |
| + int p[2]; |
| + if (pipe(p) < 0) { |
| + die_errno(_("create null pipe")); |
| + } |
| + if (write) { |
| + // NOTE: Don't close read side of write pipe, |
| + // as it will error out with EPIPE. |
| + // This leaks data into the pipe for the life of the process. |
| + return p[1]; |
| + } else { |
| + close(p[1]); |
| + return p[0]; |
| + } |
| +} |
| +#endif |
| + |
| static char *locate_in_PATH(const char *file) |
| { |
| const char *p = getenv("PATH"); |
| @@ -241,7 +276,6 @@ static int wait_or_whine(pid_t pid, const char *argv0) |
| int status, code = -1; |
| pid_t waiting; |
| int failed_errno = 0; |
| - |
| while ((waiting = waitpid(pid, &status, 0)) < 0 && errno == EINTR) |
| ; /* nothing */ |
| |
| @@ -351,7 +385,7 @@ fail_pipe: |
| trace_argv_printf(cmd->argv, "trace: run_command:"); |
| fflush(NULL); |
| |
| -#ifndef GIT_WINDOWS_NATIVE |
| +#if !defined(GIT_WINDOWS_NATIVE) && !defined(__native_client__) |
| { |
| int notify_pipe[2]; |
| if (pipe(notify_pipe)) |
| @@ -466,21 +500,21 @@ fail_pipe: |
| const char **sargv = cmd->argv; |
| |
| if (cmd->no_stdin) |
| - fhin = open("/dev/null", O_RDWR); |
| + fhin = open_devnull(0); |
| else if (need_in) |
| fhin = dup(fdin[0]); |
| else if (cmd->in) |
| fhin = dup(cmd->in); |
| |
| if (cmd->no_stderr) |
| - fherr = open("/dev/null", O_RDWR); |
| + fherr = open_devnull(1); |
| else if (need_err) |
| fherr = dup(fderr[1]); |
| else if (cmd->err > 2) |
| fherr = dup(cmd->err); |
| |
| if (cmd->no_stdout) |
| - fhout = open("/dev/null", O_RDWR); |
| + fhout = open_devnull(1); |
| else if (cmd->stdout_to_stderr) |
| fhout = dup(fherr); |
| else if (need_out) |
| @@ -493,8 +527,39 @@ fail_pipe: |
| else if (cmd->use_shell) |
| cmd->argv = prepare_shell_cmd(cmd->argv); |
| |
| +#if defined(__native_client__) |
| + char **alt_env = make_augmented_environ(cmd->env); |
| + cmd->pid = vfork(); |
| + if (cmd->pid == 0) { |
| + if (fhin != 0) { |
| + if (dup2(fhin, 0) < 0) { |
| + error("cannot dup2 fhin"); |
| + } |
| + close(fhin); |
| + } |
| + if (fhout != 1) { |
| + if (dup2(fhout, 1) < 0) { |
| + error("cannot dup2 fhout"); |
| + } |
| + close(fhout); |
| + } |
| + if (fherr != 2) { |
| + if (dup2(fherr, 2) < 0) { |
| + error("cannot dup2 fherr"); |
| + } |
| + close(fherr); |
| + } |
| + int i; |
| + for (i = 3; i < 100; ++i) close(i); |
| + if (execve(cmd->argv[0], cmd->argv, alt_env) < 0) { |
| + error("execv failed"); |
| + } |
| + } |
| + free_environ(alt_env); |
| +#else |
| cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env, |
| cmd->dir, fhin, fhout, fherr); |
| +#endif |
| failed_errno = errno; |
| if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT)) |
| error("cannot spawn %s: %s", cmd->argv[0], strerror(errno)); |
| @@ -697,6 +762,7 @@ int start_async(struct async *async) |
| |
| if (need_in) |
| proc_in = fdin[0]; |
| + // TODO(bradnelson): Figure out of this is might be a bug? |
| else if (async->in) |
| proc_in = async->in; |
| else |
| @@ -704,6 +770,7 @@ int start_async(struct async *async) |
| |
| if (need_out) |
| proc_out = fdout[1]; |
| + // TODO(bradnelson): Figure out of this is might be a bug? |
| else if (async->out) |
| proc_out = async->out; |
| else |
| @@ -751,7 +818,6 @@ int start_async(struct async *async) |
| set_die_routine(die_async); |
| set_die_is_recursing_routine(async_die_is_recursing); |
| } |
| - |
| if (proc_in >= 0) |
| set_cloexec(proc_in); |
| if (proc_out >= 0) |
| diff --git a/sha1_file.c b/sha1_file.c |
| --- a/sha1_file.c |
| +++ b/sha1_file.c |
| @@ -872,6 +872,9 @@ void free_pack_by_name(const char *pack_name) |
| |
| static unsigned int get_max_fd_limit(void) |
| { |
| +#if defined(__native_client__) |
| + return 100; |
| +#endif |
| #ifdef RLIMIT_NOFILE |
| { |
| struct rlimit lim; |