Merge branch 'work/pt/for-junio' of git://repo.or.cz/git/mingw/4msysgit
* 'work/pt/for-junio' of git://repo.or.cz/git/mingw/4msysgit: Add MinGW-specific execv() override. Fix Windows-specific macro redefinition warning. Fix 'clone' failure at DOS root directory. mingw: do not crash on open(NULL, ...) git-am: fix detection of absolute paths for windows Side-step MSYS-specific path "corruption" leading to t5560 failure. Side-step sed line-ending "corruption" leading to t6038 failure. Skip 'git archive --remote' test on msysGit Do not strip CR when grepping HTTP headers. Skip t1300.70 and 71 on msysGit. merge-octopus: Work around environment issue on Windows MinGW: Report errors when failing to launch the html browser. MinGW: fix stat() and lstat() implementations for handling symlinks MinGW: Add missing file mode bit defines MinGW: Use pid_t more consequently, introduce uid_t for greater compatibility
This commit is contained in:
commit
931c103320
@ -108,10 +108,14 @@ const char *make_nonrelative_path(const char *path)
|
||||
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
|
||||
die("Too long path: %.*s", 60, path);
|
||||
} else {
|
||||
size_t len;
|
||||
const char *fmt;
|
||||
const char *cwd = get_pwd_cwd();
|
||||
if (!cwd)
|
||||
die_errno("Cannot determine the current working directory");
|
||||
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
|
||||
len = strlen(cwd);
|
||||
fmt = (len > 0 && is_dir_sep(cwd[len-1])) ? "%s%s" : "%s/%s";
|
||||
if (snprintf(buf, PATH_MAX, fmt, cwd, path) >= PATH_MAX)
|
||||
die("Too long path: %.*s", 60, path);
|
||||
}
|
||||
return buf;
|
||||
|
@ -127,7 +127,7 @@ int mingw_open (const char *filename, int oflags, ...)
|
||||
mode = va_arg(args, int);
|
||||
va_end(args);
|
||||
|
||||
if (!strcmp(filename, "/dev/null"))
|
||||
if (filename && !strcmp(filename, "/dev/null"))
|
||||
filename = "nul";
|
||||
|
||||
fd = open(filename, oflags, mode);
|
||||
@ -160,7 +160,7 @@ ssize_t mingw_write(int fd, const void *buf, size_t count)
|
||||
#undef fopen
|
||||
FILE *mingw_fopen (const char *filename, const char *otype)
|
||||
{
|
||||
if (!strcmp(filename, "/dev/null"))
|
||||
if (filename && !strcmp(filename, "/dev/null"))
|
||||
filename = "nul";
|
||||
return fopen(filename, otype);
|
||||
}
|
||||
@ -192,8 +192,11 @@ static inline time_t filetime_to_time_t(const FILETIME *ft)
|
||||
/* We keep the do_lstat code in a separate function to avoid recursion.
|
||||
* When a path ends with a slash, the stat will fail with ENOENT. In
|
||||
* this case, we strip the trailing slashes and stat again.
|
||||
*
|
||||
* If follow is true then act like stat() and report on the link
|
||||
* target. Otherwise report on the link itself.
|
||||
*/
|
||||
static int do_lstat(const char *file_name, struct stat *buf)
|
||||
static int do_lstat(int follow, const char *file_name, struct stat *buf)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA fdata;
|
||||
|
||||
@ -209,6 +212,25 @@ static int do_lstat(const char *file_name, struct stat *buf)
|
||||
buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
|
||||
buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
|
||||
buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
WIN32_FIND_DATAA findbuf;
|
||||
HANDLE handle = FindFirstFileA(file_name, &findbuf);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
|
||||
if (follow) {
|
||||
char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||
buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
||||
} else {
|
||||
buf->st_mode = S_IFLNK;
|
||||
}
|
||||
buf->st_mode |= S_IREAD;
|
||||
if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
@ -220,12 +242,12 @@ static int do_lstat(const char *file_name, struct stat *buf)
|
||||
* complete. Note that Git stat()s are redirected to mingw_lstat()
|
||||
* too, since Windows doesn't really handle symlinks that well.
|
||||
*/
|
||||
int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
|
||||
{
|
||||
int namelen;
|
||||
static char alt_name[PATH_MAX];
|
||||
|
||||
if (!do_lstat(file_name, buf))
|
||||
if (!do_lstat(follow, file_name, buf))
|
||||
return 0;
|
||||
|
||||
/* if file_name ended in a '/', Windows returned ENOENT;
|
||||
@ -244,7 +266,16 @@ int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
|
||||
memcpy(alt_name, file_name, namelen);
|
||||
alt_name[namelen] = 0;
|
||||
return do_lstat(alt_name, buf);
|
||||
return do_lstat(follow, alt_name, buf);
|
||||
}
|
||||
|
||||
int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
{
|
||||
return do_stat_internal(0, file_name, buf);
|
||||
}
|
||||
int mingw_stat(const char *file_name, struct stat *buf)
|
||||
{
|
||||
return do_stat_internal(1, file_name, buf);
|
||||
}
|
||||
|
||||
#undef fstat
|
||||
@ -873,6 +904,11 @@ void mingw_execvp(const char *cmd, char *const *argv)
|
||||
free_path_split(path);
|
||||
}
|
||||
|
||||
void mingw_execv(const char *cmd, char *const *argv)
|
||||
{
|
||||
mingw_execve(cmd, argv, environ);
|
||||
}
|
||||
|
||||
static char **copy_environ(void)
|
||||
{
|
||||
char **env;
|
||||
@ -1386,6 +1422,7 @@ void mingw_open_html(const char *unixpath)
|
||||
const char *, const char *, const char *, INT);
|
||||
T ShellExecute;
|
||||
HMODULE shell32;
|
||||
int r;
|
||||
|
||||
shell32 = LoadLibrary("shell32.dll");
|
||||
if (!shell32)
|
||||
@ -1395,9 +1432,12 @@ void mingw_open_html(const char *unixpath)
|
||||
die("cannot run browser");
|
||||
|
||||
printf("Launching default browser to display HTML ...\n");
|
||||
ShellExecute(NULL, "open", htmlpath, NULL, "\\", 0);
|
||||
|
||||
r = (int)ShellExecute(NULL, "open", htmlpath, NULL, "\\", SW_SHOWNORMAL);
|
||||
FreeLibrary(shell32);
|
||||
/* see the MSDN documentation referring to the result codes here */
|
||||
if (r <= 32) {
|
||||
die("failed to launch browser for %.*s", MAX_PATH, unixpath);
|
||||
}
|
||||
}
|
||||
|
||||
int link(const char *oldpath, const char *newpath)
|
||||
|
@ -6,17 +6,30 @@
|
||||
*/
|
||||
|
||||
typedef int pid_t;
|
||||
typedef int uid_t;
|
||||
#define hstrerror strerror
|
||||
|
||||
#define S_IFLNK 0120000 /* Symbolic link */
|
||||
#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
|
||||
#define S_ISSOCK(x) 0
|
||||
|
||||
#ifndef _STAT_H_
|
||||
#define S_IRUSR 0
|
||||
#define S_IWUSR 0
|
||||
#define S_IXUSR 0
|
||||
#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||
#endif
|
||||
#define S_IRGRP 0
|
||||
#define S_IWGRP 0
|
||||
#define S_IXGRP 0
|
||||
#define S_ISGID 0
|
||||
#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
|
||||
#define S_IROTH 0
|
||||
#define S_IWOTH 0
|
||||
#define S_IXOTH 0
|
||||
#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
|
||||
#define S_ISUID 0
|
||||
#define S_ISGID 0
|
||||
#define S_ISVTX 0
|
||||
|
||||
#define WIFEXITED(x) 1
|
||||
#define WIFSIGNALED(x) 0
|
||||
@ -65,6 +78,12 @@ struct itimerval {
|
||||
};
|
||||
#define ITIMER_REAL 0
|
||||
|
||||
/*
|
||||
* sanitize preprocessor namespace polluted by Windows headers defining
|
||||
* macros which collide with git local versions
|
||||
*/
|
||||
#undef HELP_COMMAND /* from winuser.h */
|
||||
|
||||
/*
|
||||
* trivial stubs
|
||||
*/
|
||||
@ -75,17 +94,17 @@ static inline int symlink(const char *oldpath, const char *newpath)
|
||||
{ errno = ENOSYS; return -1; }
|
||||
static inline int fchmod(int fildes, mode_t mode)
|
||||
{ errno = ENOSYS; return -1; }
|
||||
static inline int fork(void)
|
||||
static inline pid_t fork(void)
|
||||
{ errno = ENOSYS; return -1; }
|
||||
static inline unsigned int alarm(unsigned int seconds)
|
||||
{ return 0; }
|
||||
static inline int fsync(int fd)
|
||||
{ return _commit(fd); }
|
||||
static inline int getppid(void)
|
||||
static inline pid_t getppid(void)
|
||||
{ return 1; }
|
||||
static inline void sync(void)
|
||||
{}
|
||||
static inline int getuid()
|
||||
static inline uid_t getuid(void)
|
||||
{ return 1; }
|
||||
static inline struct passwd *getpwnam(const char *name)
|
||||
{ return NULL; }
|
||||
@ -117,7 +136,7 @@ static inline int mingw_unlink(const char *pathname)
|
||||
}
|
||||
#define unlink mingw_unlink
|
||||
|
||||
static inline int waitpid(pid_t pid, int *status, unsigned options)
|
||||
static inline pid_t waitpid(pid_t pid, int *status, unsigned options)
|
||||
{
|
||||
if (options == 0)
|
||||
return _cwait(status, pid, 0);
|
||||
@ -158,7 +177,7 @@ int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
struct tm *localtime_r(const time_t *timep, struct tm *result);
|
||||
int getpagesize(void); /* defined in MinGW's libgcc.a */
|
||||
struct passwd *getpwuid(int uid);
|
||||
struct passwd *getpwuid(uid_t uid);
|
||||
int setitimer(int type, struct itimerval *in, struct itimerval *out);
|
||||
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
|
||||
int link(const char *oldpath, const char *newpath);
|
||||
@ -222,10 +241,11 @@ int mingw_getpagesize(void);
|
||||
#ifndef ALREADY_DECLARED_STAT_FUNCS
|
||||
#define stat _stati64
|
||||
int mingw_lstat(const char *file_name, struct stat *buf);
|
||||
int mingw_stat(const char *file_name, struct stat *buf);
|
||||
int mingw_fstat(int fd, struct stat *buf);
|
||||
#define fstat mingw_fstat
|
||||
#define lstat mingw_lstat
|
||||
#define _stati64(x,y) mingw_lstat(x,y)
|
||||
#define _stati64(x,y) mingw_stat(x,y)
|
||||
#endif
|
||||
|
||||
int mingw_utime(const char *file_name, const struct utimbuf *times);
|
||||
@ -236,6 +256,8 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
|
||||
int fhin, int fhout, int fherr);
|
||||
void mingw_execvp(const char *cmd, char *const *argv);
|
||||
#define execvp mingw_execvp
|
||||
void mingw_execv(const char *cmd, char *const *argv);
|
||||
#define execv mingw_execv
|
||||
|
||||
static inline unsigned int git_ntohl(unsigned int x)
|
||||
{ return (unsigned int)ntohl(x); }
|
||||
|
12
git-am.sh
12
git-am.sh
@ -444,12 +444,12 @@ else
|
||||
set x
|
||||
first=
|
||||
}
|
||||
case "$arg" in
|
||||
/*)
|
||||
set "$@" "$arg" ;;
|
||||
*)
|
||||
set "$@" "$prefix$arg" ;;
|
||||
esac
|
||||
if is_absolute_path "$arg"
|
||||
then
|
||||
set "$@" "$arg"
|
||||
else
|
||||
set "$@" "$prefix$arg"
|
||||
fi
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
@ -61,6 +61,11 @@ do
|
||||
esac
|
||||
|
||||
eval pretty_name=\${GITHEAD_$SHA1:-$SHA1}
|
||||
if test "$SHA1" = "$pretty_name"
|
||||
then
|
||||
SHA1_UP="$(echo "$SHA1" | tr a-z A-Z)"
|
||||
eval pretty_name=\${GITHEAD_$SHA1_UP:-$pretty_name}
|
||||
fi
|
||||
common=$(git merge-base --all $SHA1 $MRC) ||
|
||||
die "Unable to find common commit with $pretty_name"
|
||||
|
||||
|
@ -209,5 +209,20 @@ case $(uname -s) in
|
||||
find () {
|
||||
/usr/bin/find "$@"
|
||||
}
|
||||
is_absolute_path () {
|
||||
case "$1" in
|
||||
[/\\]* | [A-Za-z]:*)
|
||||
return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
*)
|
||||
is_absolute_path () {
|
||||
case "$1" in
|
||||
/*)
|
||||
return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
esac
|
||||
|
@ -701,13 +701,13 @@ cat >expect <<\EOF
|
||||
trailingtilde = foo~
|
||||
EOF
|
||||
|
||||
test_expect_success 'set --path' '
|
||||
test_expect_success NOT_MINGW 'set --path' '
|
||||
git config --path path.home "~/" &&
|
||||
git config --path path.normal "/dev/null" &&
|
||||
git config --path path.trailingtilde "foo~" &&
|
||||
test_cmp expect .git/config'
|
||||
|
||||
if test "${HOME+set}"
|
||||
if test_have_prereq NOT_MINGW && test "${HOME+set}"
|
||||
then
|
||||
test_set_prereq HOMEVAR
|
||||
fi
|
||||
@ -730,7 +730,7 @@ cat >expect <<\EOF
|
||||
foo~
|
||||
EOF
|
||||
|
||||
test_expect_success 'get --path copes with unset $HOME' '
|
||||
test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '
|
||||
(
|
||||
unset HOME;
|
||||
test_must_fail git config --get --path path.home \
|
||||
|
@ -94,7 +94,7 @@ test_expect_success 'git archive with --output' \
|
||||
'git archive --output=b4.tar HEAD &&
|
||||
test_cmp b.tar b4.tar'
|
||||
|
||||
test_expect_success 'git archive --remote' \
|
||||
test_expect_success NOT_MINGW 'git archive --remote' \
|
||||
'git archive --remote=. HEAD >b5.tar &&
|
||||
test_cmp b.tar b5.tar'
|
||||
|
||||
|
@ -4,14 +4,9 @@ test_description='test automatic tag following'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
case $(uname -s) in
|
||||
*MINGW*)
|
||||
if !test_have_prereq NOT_MINGW; then
|
||||
say "GIT_DEBUG_SEND_PACK not supported - skipping tests"
|
||||
;;
|
||||
*)
|
||||
test_set_prereq NOT_MINGW
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# End state of the repository:
|
||||
#
|
||||
|
@ -5,11 +5,12 @@ test_description='test git-http-backend-noserver'
|
||||
|
||||
HTTPD_DOCUMENT_ROOT_PATH="$TRASH_DIRECTORY"
|
||||
|
||||
test_have_prereq MINGW && export GREP_OPTIONS=-U
|
||||
|
||||
run_backend() {
|
||||
echo "$2" |
|
||||
QUERY_STRING="${1#*\?}" \
|
||||
GIT_PROJECT_ROOT="$HTTPD_DOCUMENT_ROOT_PATH" \
|
||||
PATH_INFO="${1%%\?*}" \
|
||||
PATH_TRANSLATED="$HTTPD_DOCUMENT_ROOT_PATH/${1%%\?*}" \
|
||||
git http-backend >act.out 2>act.err
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,8 @@ test_description='CRLF merge conflict across text=auto change
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_have_prereq MINGW && SED_OPTIONS=-b
|
||||
|
||||
test_expect_success setup '
|
||||
git config core.autocrlf false &&
|
||||
|
||||
@ -60,7 +62,7 @@ test_expect_success setup '
|
||||
|
||||
test_expect_success 'set up fuzz_conflict() helper' '
|
||||
fuzz_conflict() {
|
||||
sed -e "s/^\([<>=]......\) .*/\1/" "$@"
|
||||
sed $SED_OPTIONS -e "s/^\([<>=]......\) .*/\1/" "$@"
|
||||
}
|
||||
'
|
||||
|
||||
|
@ -970,11 +970,13 @@ case $(uname -s) in
|
||||
# no POSIX permissions
|
||||
# backslashes in pathspec are converted to '/'
|
||||
# exec does not inherit the PID
|
||||
test_set_prereq MINGW
|
||||
;;
|
||||
*)
|
||||
test_set_prereq POSIXPERM
|
||||
test_set_prereq BSLASHPSPEC
|
||||
test_set_prereq EXECKEEPSPID
|
||||
test_set_prereq NOT_MINGW
|
||||
;;
|
||||
esac
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user