Merge branch 'jl/maint-submodule-gitfile-awareness'
authorJunio C Hamano <gitster@pobox.com>
Sun, 11 Apr 2010 20:54:28 +0000 (13:54 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 11 Apr 2010 20:54:28 +0000 (13:54 -0700)
* jl/maint-submodule-gitfile-awareness:
Windows: start_command: Support non-NULL dir in struct child_process

1  2 
compat/mingw.c
compat/mingw.h
run-command.c
diff --combined compat/mingw.c
index 30716903f5c3072588ddaae71f557f14d7806fde,754b5340b087841aaa7601c784c8ca9f15ed64a6..f90a114b021d32c2ee1976bf51a82e87a81ea1cb
@@@ -140,22 -140,6 +140,22 @@@ int mingw_open (const char *filename, i
        return fd;
  }
  
 +#undef fopen
 +FILE *mingw_fopen (const char *filename, const char *otype)
 +{
 +      if (!strcmp(filename, "/dev/null"))
 +              filename = "nul";
 +      return fopen(filename, otype);
 +}
 +
 +#undef freopen
 +FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
 +{
 +      if (filename && !strcmp(filename, "/dev/null"))
 +              filename = "nul";
 +      return freopen(filename, otype, stream);
 +}
 +
  /*
   * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
   * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
@@@ -275,17 -259,8 +275,17 @@@ int mingw_utime (const char *file_name
        int fh, rc;
  
        /* must have write permission */
 -      if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0)
 -              return -1;
 +      DWORD attrs = GetFileAttributes(file_name);
 +      if (attrs != INVALID_FILE_ATTRIBUTES &&
 +          (attrs & FILE_ATTRIBUTE_READONLY)) {
 +              /* ignore errors here; open() will report them */
 +              SetFileAttributes(file_name, attrs & ~FILE_ATTRIBUTE_READONLY);
 +      }
 +
 +      if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) {
 +              rc = -1;
 +              goto revert_attrs;
 +      }
  
        time_t_to_filetime(times->modtime, &mft);
        time_t_to_filetime(times->actime, &aft);
        } else
                rc = 0;
        close(fh);
 +
 +revert_attrs:
 +      if (attrs != INVALID_FILE_ATTRIBUTES &&
 +          (attrs & FILE_ATTRIBUTE_READONLY)) {
 +              /* ignore errors again */
 +              SetFileAttributes(file_name, attrs);
 +      }
        return rc;
  }
  
@@@ -650,6 -618,7 +650,7 @@@ static int env_compare(const void *a, c
  }
  
  static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
+                             const char *dir,
                              int prepend_cmd, int fhin, int fhout, int fherr)
  {
        STARTUPINFO si;
  
        memset(&pi, 0, sizeof(pi));
        ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags,
-               env ? envblk.buf : NULL, NULL, &si, &pi);
+               env ? envblk.buf : NULL, dir, &si, &pi);
  
        if (env)
                strbuf_release(&envblk);
  static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
                           int prepend_cmd)
  {
-       return mingw_spawnve_fd(cmd, argv, env, prepend_cmd, 0, 1, 2);
+       return mingw_spawnve_fd(cmd, argv, env, NULL, prepend_cmd, 0, 1, 2);
  }
  
  pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+                    const char *dir,
                     int fhin, int fhout, int fherr)
  {
        pid_t pid;
                                pid = -1;
                        }
                        else {
-                               pid = mingw_spawnve_fd(iprog, argv, env, 1,
+                               pid = mingw_spawnve_fd(iprog, argv, env, dir, 1,
                                                       fhin, fhout, fherr);
                                free(iprog);
                        }
                        argv[0] = argv0;
                }
                else
-                       pid = mingw_spawnve_fd(prog, argv, env, 0,
+                       pid = mingw_spawnve_fd(prog, argv, env, dir, 0,
                                               fhin, fhout, fherr);
                free(prog);
        }
diff --combined compat/mingw.h
index e81e752ed2716ac9fb4a6847f97db84764694b4c,e0a6abac510610f5779e8df68fab2ad8424ce8c4..7c2ab64cb4eb7532c2495383ab0e7eefb329bcf9
@@@ -170,12 -170,6 +170,12 @@@ int link(const char *oldpath, const cha
  int mingw_open (const char *filename, int oflags, ...);
  #define open mingw_open
  
 +FILE *mingw_fopen (const char *filename, const char *otype);
 +#define fopen mingw_fopen
 +
 +FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
 +#define freopen mingw_freopen
 +
  char *mingw_getcwd(char *pointer, int len);
  #define getcwd mingw_getcwd
  
@@@ -229,6 -223,7 +229,7 @@@ int mingw_utime(const char *file_name, 
  #define utime mingw_utime
  
  pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+                    const char *dir,
                     int fhin, int fhout, int fherr);
  void mingw_execvp(const char *cmd, char *const *argv);
  #define execvp mingw_execvp
diff --combined run-command.c
index c8d53795ec3ae9b8b0a73b3d6900c1a1f212d2c2,db30cd5fe29b9d9af11860da316ac1f45e290593..eb5c57562909c1e505c2a7688bad6dbeea4b96a0
@@@ -67,21 -67,19 +67,21 @@@ static int child_notifier = -1
  
  static void notify_parent(void)
  {
 -      write(child_notifier, "", 1);
 +      ssize_t unused;
 +      unused = write(child_notifier, "", 1);
  }
  
  static NORETURN void die_child(const char *err, va_list params)
  {
        char msg[4096];
 +      ssize_t unused;
        int len = vsnprintf(msg, sizeof(msg), err, params);
        if (len > sizeof(msg))
                len = sizeof(msg);
  
 -      write(child_err, "fatal: ", 7);
 -      write(child_err, msg, len);
 -      write(child_err, "\n", 1);
 +      unused = write(child_err, "fatal: ", 7);
 +      unused = write(child_err, msg, len);
 +      unused = write(child_err, "\n", 1);
        exit(128);
  }
  
@@@ -235,9 -233,6 +235,9 @@@ fail_pipe
                else if (need_err) {
                        dup2(fderr[1], 2);
                        close_pair(fderr);
 +              } else if (cmd->err > 1) {
 +                      dup2(cmd->err, 2);
 +                      close(cmd->err);
                }
  
                if (cmd->no_stdout)
                fherr = open("/dev/null", O_RDWR);
        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);
        else if (cmd->out > 1)
                fhout = dup(cmd->out);
  
-       if (cmd->dir)
-               die("chdir in start_command() not implemented");
        if (cmd->env)
                env = make_augmented_environ(cmd->env);
  
                cmd->argv = prepare_shell_cmd(cmd->argv);
        }
  
-       cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env,
+       cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir,
                                  fhin, fhout, fherr);
        failed_errno = errno;
        if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
  
        if (need_err)
                close(fderr[1]);
 +      else if (cmd->err)
 +              close(cmd->err);
  
        return 0;
  }
@@@ -453,51 -442,17 +451,51 @@@ int run_command_v_opt_cd_env(const cha
  static unsigned __stdcall run_thread(void *data)
  {
        struct async *async = data;
 -      return async->proc(async->fd_for_proc, async->data);
 +      return async->proc(async->proc_in, async->proc_out, async->data);
  }
  #endif
  
  int start_async(struct async *async)
  {
 -      int pipe_out[2];
 +      int need_in, need_out;
 +      int fdin[2], fdout[2];
 +      int proc_in, proc_out;
  
 -      if (pipe(pipe_out) < 0)
 -              return error("cannot create pipe: %s", strerror(errno));
 -      async->out = pipe_out[0];
 +      need_in = async->in < 0;
 +      if (need_in) {
 +              if (pipe(fdin) < 0) {
 +                      if (async->out > 0)
 +                              close(async->out);
 +                      return error("cannot create pipe: %s", strerror(errno));
 +              }
 +              async->in = fdin[1];
 +      }
 +
 +      need_out = async->out < 0;
 +      if (need_out) {
 +              if (pipe(fdout) < 0) {
 +                      if (need_in)
 +                              close_pair(fdin);
 +                      else if (async->in)
 +                              close(async->in);
 +                      return error("cannot create pipe: %s", strerror(errno));
 +              }
 +              async->out = fdout[0];
 +      }
 +
 +      if (need_in)
 +              proc_in = fdin[0];
 +      else if (async->in)
 +              proc_in = async->in;
 +      else
 +              proc_in = -1;
 +
 +      if (need_out)
 +              proc_out = fdout[1];
 +      else if (async->out)
 +              proc_out = async->out;
 +      else
 +              proc_out = -1;
  
  #ifndef WIN32
        /* Flush stdio before fork() to avoid cloning buffers */
        async->pid = fork();
        if (async->pid < 0) {
                error("fork (async) failed: %s", strerror(errno));
 -              close_pair(pipe_out);
 -              return -1;
 +              goto error;
        }
        if (!async->pid) {
 -              close(pipe_out[0]);
 -              exit(!!async->proc(pipe_out[1], async->data));
 +              if (need_in)
 +                      close(fdin[1]);
 +              if (need_out)
 +                      close(fdout[0]);
 +              exit(!!async->proc(proc_in, proc_out, async->data));
        }
 -      close(pipe_out[1]);
 +
 +      if (need_in)
 +              close(fdin[0]);
 +      else if (async->in)
 +              close(async->in);
 +
 +      if (need_out)
 +              close(fdout[1]);
 +      else if (async->out)
 +              close(async->out);
  #else
 -      async->fd_for_proc = pipe_out[1];
 +      async->proc_in = proc_in;
 +      async->proc_out = proc_out;
        async->tid = (HANDLE) _beginthreadex(NULL, 0, run_thread, async, 0, NULL);
        if (!async->tid) {
                error("cannot create thread: %s", strerror(errno));
 -              close_pair(pipe_out);
 -              return -1;
 +              goto error;
        }
  #endif
        return 0;
 +
 +error:
 +      if (need_in)
 +              close_pair(fdin);
 +      else if (async->in)
 +              close(async->in);
 +
 +      if (need_out)
 +              close_pair(fdout);
 +      else if (async->out)
 +              close(async->out);
 +      return -1;
  }
  
  int finish_async(struct async *async)