Skip to content

Commit

Permalink
Merge branch 'bw/forking-and-threading'
Browse files Browse the repository at this point in the history
The "run-command" API implementation has been made more robust
against dead-locking in a threaded environment.

* bw/forking-and-threading:
  usage.c: drop set_error_handle()
  run-command: restrict PATH search to executable files
  run-command: expose is_executable function
  run-command: block signals between fork and execve
  run-command: add note about forking and threading
  run-command: handle dup2 and close errors in child
  run-command: eliminate calls to error handling functions in child
  run-command: don't die in child when duping /dev/null
  run-command: prepare child environment before forking
  string-list: add string_list_remove function
  run-command: use the async-signal-safe execv instead of execvp
  run-command: prepare command before forking
  t0061: run_command executes scripts without a #! line
  t5550: use write_script to generate post-update hook
  • Loading branch information
gitster committed May 30, 2017
2 parents 140921c + e3f43ce commit 7d5e13f
Show file tree
Hide file tree
Showing 9 changed files with 449 additions and 134 deletions.
1 change: 0 additions & 1 deletion git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,6 @@ extern void (*get_error_routine(void))(const char *err, va_list params);
extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
extern void (*get_warn_routine(void))(const char *warn, va_list params);
extern void set_die_is_recursing_routine(int (*routine)(void));
extern void set_error_handle(FILE *);

extern int starts_with(const char *str, const char *prefix);

Expand Down
43 changes: 1 addition & 42 deletions help.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "cache.h"
#include "builtin.h"
#include "exec_cmd.h"
#include "run-command.h"
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
Expand Down Expand Up @@ -96,48 +97,6 @@ static void pretty_print_cmdnames(struct cmdnames *cmds, unsigned int colopts)
string_list_clear(&list, 0);
}

static int is_executable(const char *name)
{
struct stat st;

if (stat(name, &st) || /* stat, not lstat */
!S_ISREG(st.st_mode))
return 0;

#if defined(GIT_WINDOWS_NATIVE)
/*
* On Windows there is no executable bit. The file extension
* indicates whether it can be run as an executable, and Git
* has special-handling to detect scripts and launch them
* through the indicated script interpreter. We test for the
* file extension first because virus scanners may make
* it quite expensive to open many files.
*/
if (ends_with(name, ".exe"))
return S_IXUSR;

{
/*
* Now that we know it does not have an executable extension,
* peek into the file instead.
*/
char buf[3] = { 0 };
int n;
int fd = open(name, O_RDONLY);
st.st_mode &= ~S_IXUSR;
if (fd >= 0) {
n = read(fd, buf, 2);
if (n == 2)
/* look for a she-bang */
if (!strcmp(buf, "#!"))
st.st_mode |= S_IXUSR;
close(fd);
}
}
#endif
return st.st_mode & S_IXUSR;
}

static void list_commands_in_dir(struct cmdnames *cmds,
const char *path,
const char *prefix)
Expand Down
Loading

0 comments on commit 7d5e13f

Please sign in to comment.