Skip to content

Commit c12f07a

Browse files
dschoGit for Windows Build Agent
authored andcommitted
Merge branch 'busybox-w32'
Signed-off-by: Johannes Schindelin <[email protected]>
2 parents b45efbb + 877e467 commit c12f07a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+442
-191
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*.perl eol=lf diff=perl
55
*.pl eof=lf diff=perl
66
*.pm eol=lf diff=perl
7+
*.png binary
78
*.py eol=lf diff=python
89
*.bat eol=crlf
910
CODE_OF_CONDUCT.md -whitespace

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ TEST_BUILTINS_OBJS += test-bloom.o
789789
TEST_BUILTINS_OBJS += test-bundle-uri.o
790790
TEST_BUILTINS_OBJS += test-cache-tree.o
791791
TEST_BUILTINS_OBJS += test-chmtime.o
792+
TEST_BUILTINS_OBJS += test-cmp.o
792793
TEST_BUILTINS_OBJS += test-config.o
793794
TEST_BUILTINS_OBJS += test-crontab.o
794795
TEST_BUILTINS_OBJS += test-csprng.o
@@ -811,6 +812,7 @@ TEST_BUILTINS_OBJS += test-hash-speed.o
811812
TEST_BUILTINS_OBJS += test-hash.o
812813
TEST_BUILTINS_OBJS += test-hashmap.o
813814
TEST_BUILTINS_OBJS += test-hexdump.o
815+
TEST_BUILTINS_OBJS += test-iconv.o
814816
TEST_BUILTINS_OBJS += test-index-version.o
815817
TEST_BUILTINS_OBJS += test-json-writer.o
816818
TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o

compat/mingw.c

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <sspi.h>
1616
#include "win32/fscache.h"
1717
#include "../attr.h"
18+
#include "../string-list.h"
1819

1920
#define HCAST(type, handle) ((type)(intptr_t)handle)
2021

@@ -1642,6 +1643,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
16421643
return NULL;
16431644
}
16441645

1646+
static char *path_lookup(const char *cmd, int exe_only);
1647+
1648+
static char *is_busybox_applet(const char *cmd)
1649+
{
1650+
static struct string_list applets = STRING_LIST_INIT_DUP;
1651+
static char *busybox_path;
1652+
static int busybox_path_initialized;
1653+
1654+
/* Avoid infinite loop */
1655+
if (!strncasecmp(cmd, "busybox", 7) &&
1656+
(!cmd[7] || !strcasecmp(cmd + 7, ".exe")))
1657+
return NULL;
1658+
1659+
if (!busybox_path_initialized) {
1660+
busybox_path = path_lookup("busybox.exe", 1);
1661+
busybox_path_initialized = 1;
1662+
}
1663+
1664+
/* Assume that sh is compiled in... */
1665+
if (!busybox_path || !strcasecmp(cmd, "sh"))
1666+
return xstrdup_or_null(busybox_path);
1667+
1668+
if (!applets.nr) {
1669+
struct child_process cp = CHILD_PROCESS_INIT;
1670+
struct strbuf buf = STRBUF_INIT;
1671+
char *p;
1672+
1673+
strvec_pushl(&cp.args, busybox_path, "--help", NULL);
1674+
1675+
if (capture_command(&cp, &buf, 2048)) {
1676+
string_list_append(&applets, "");
1677+
return NULL;
1678+
}
1679+
1680+
/* parse output */
1681+
p = strstr(buf.buf, "Currently defined functions:\n");
1682+
if (!p) {
1683+
warning("Could not parse output of busybox --help");
1684+
string_list_append(&applets, "");
1685+
return NULL;
1686+
}
1687+
p = strchrnul(p, '\n');
1688+
for (;;) {
1689+
size_t len;
1690+
1691+
p += strspn(p, "\n\t ,");
1692+
len = strcspn(p, "\n\t ,");
1693+
if (!len)
1694+
break;
1695+
p[len] = '\0';
1696+
string_list_insert(&applets, p);
1697+
p = p + len + 1;
1698+
}
1699+
}
1700+
1701+
return string_list_has_string(&applets, cmd) ?
1702+
xstrdup(busybox_path) : NULL;
1703+
}
1704+
16451705
/*
16461706
* Determines the absolute path of cmd using the split path in path.
16471707
* If cmd contains a slash or backslash, no lookup is performed.
@@ -1670,6 +1730,9 @@ static char *path_lookup(const char *cmd, int exe_only)
16701730
path = sep + 1;
16711731
}
16721732

1733+
if (!prog && !isexe)
1734+
prog = is_busybox_applet(cmd);
1735+
16731736
return prog;
16741737
}
16751738

@@ -1869,8 +1932,8 @@ static int is_msys2_sh(const char *cmd)
18691932
}
18701933

18711934
static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaenv,
1872-
const char *dir,
1873-
int prepend_cmd, int fhin, int fhout, int fherr)
1935+
const char *dir, const char *prepend_cmd,
1936+
int fhin, int fhout, int fherr)
18741937
{
18751938
static int restrict_handle_inheritance = -1;
18761939
STARTUPINFOEXW si;
@@ -1961,9 +2024,9 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
19612024
/* concatenate argv, quoting args as we go */
19622025
strbuf_init(&args, 0);
19632026
if (prepend_cmd) {
1964-
char *quoted = (char *)quote_arg(cmd);
2027+
char *quoted = (char *)quote_arg(prepend_cmd);
19652028
strbuf_addstr(&args, quoted);
1966-
if (quoted != cmd)
2029+
if (quoted != prepend_cmd)
19672030
free(quoted);
19682031
}
19692032
for (; *argv; argv++) {
@@ -2122,7 +2185,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
21222185
return (pid_t)pi.dwProcessId;
21232186
}
21242187

2125-
static pid_t mingw_spawnv(const char *cmd, const char **argv, int prepend_cmd)
2188+
static pid_t mingw_spawnv(const char *cmd, const char **argv,
2189+
const char *prepend_cmd)
21262190
{
21272191
return mingw_spawnve_fd(cmd, argv, NULL, NULL, prepend_cmd, 0, 1, 2);
21282192
}
@@ -2150,14 +2214,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
21502214
pid = -1;
21512215
}
21522216
else {
2153-
pid = mingw_spawnve_fd(iprog, argv, deltaenv, dir, 1,
2217+
pid = mingw_spawnve_fd(iprog, argv, deltaenv, dir, interpr,
21542218
fhin, fhout, fherr);
21552219
free(iprog);
21562220
}
21572221
argv[0] = argv0;
21582222
}
21592223
else
2160-
pid = mingw_spawnve_fd(prog, argv, deltaenv, dir, 0,
2224+
pid = mingw_spawnve_fd(prog, argv, deltaenv, dir, NULL,
21612225
fhin, fhout, fherr);
21622226
free(prog);
21632227
}
@@ -2185,7 +2249,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
21852249
argv2[0] = (char *)cmd; /* full path to the script file */
21862250
COPY_ARRAY(&argv2[1], &argv[1], argc);
21872251
exec_id = trace2_exec(prog, argv2);
2188-
pid = mingw_spawnv(prog, argv2, 1);
2252+
pid = mingw_spawnv(prog, argv2, interpr);
21892253
if (pid >= 0) {
21902254
int status;
21912255
if (waitpid(pid, &status, 0) < 0)
@@ -2209,7 +2273,7 @@ int mingw_execv(const char *cmd, char *const *argv)
22092273
int exec_id;
22102274

22112275
exec_id = trace2_exec(cmd, (const char **)argv);
2212-
pid = mingw_spawnv(cmd, (const char **)argv, 0);
2276+
pid = mingw_spawnv(cmd, (const char **)argv, NULL);
22132277
if (pid < 0) {
22142278
trace2_exec_result(exec_id, -1);
22152279
return -1;

config.mak.uname

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,62 @@ else
740740
NO_PYTHON = YesPlease
741741
endif
742742
endif
743+
ifeq (i686,$(uname_M))
744+
MINGW_PREFIX := mingw32
745+
endif
746+
ifeq (x86_64,$(uname_M))
747+
MINGW_PREFIX := mingw64
748+
endif
749+
750+
DESTDIR_WINDOWS = $(shell cygpath -aw '$(DESTDIR_SQ)')
751+
DESTDIR_MIXED = $(shell cygpath -am '$(DESTDIR_SQ)')
752+
install-mingit-test-artifacts:
753+
install -m755 -d '$(DESTDIR_SQ)/usr/bin'
754+
printf '%s\n%s\n' >'$(DESTDIR_SQ)/usr/bin/perl' \
755+
"#!/mingw64/bin/busybox sh" \
756+
"exec \"$(shell cygpath -am /usr/bin/perl.exe)\" \"\$$@\""
757+
758+
install -m755 -d '$(DESTDIR_SQ)'
759+
printf '%s%s\n%s\n%s\n%s\n%s\n' >'$(DESTDIR_SQ)/init.bat' \
760+
"PATH=$(DESTDIR_WINDOWS)\\$(MINGW_PREFIX)\\bin;" \
761+
"C:\\WINDOWS;C:\\WINDOWS\\system32" \
762+
"@set GIT_TEST_INSTALLED=$(DESTDIR_MIXED)/$(MINGW_PREFIX)/bin" \
763+
"@`echo "$(DESTDIR_WINDOWS)" | sed 's/:.*/:/'`" \
764+
"@cd `echo "$(DESTDIR_WINDOWS)" | sed 's/^.://'`\\test-git\\t" \
765+
"@echo Now, run 'helper\\test-run-command testsuite'"
766+
767+
install -m755 -d '$(DESTDIR_SQ)/test-git'
768+
sed 's/^\(NO_PERL\|NO_PYTHON\)=.*/\1=YesPlease/' \
769+
<GIT-BUILD-OPTIONS >'$(DESTDIR_SQ)/test-git/GIT-BUILD-OPTIONS'
770+
771+
install -m755 -d '$(DESTDIR_SQ)/test-git/t/helper'
772+
install -m755 $(TEST_PROGRAMS) '$(DESTDIR_SQ)/test-git/t/helper'
773+
(cd t && $(TAR) cf - t[0-9][0-9][0-9][0-9] lib-diff) | \
774+
(cd '$(DESTDIR_SQ)/test-git/t' && $(TAR) xf -)
775+
install -m755 t/t556x_common t/*.sh '$(DESTDIR_SQ)/test-git/t'
776+
777+
install -m755 -d '$(DESTDIR_SQ)/test-git/templates'
778+
(cd templates && $(TAR) cf - blt) | \
779+
(cd '$(DESTDIR_SQ)/test-git/templates' && $(TAR) xf -)
780+
781+
# po/build/locale for t0200
782+
install -m755 -d '$(DESTDIR_SQ)/test-git/po/build/locale'
783+
(cd po/build/locale && $(TAR) cf - .) | \
784+
(cd '$(DESTDIR_SQ)/test-git/po/build/locale' && $(TAR) xf -)
785+
786+
# git-daemon.exe for t5802, git-http-backend.exe for t5560
787+
install -m755 -d '$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
788+
install -m755 git-daemon.exe git-http-backend.exe \
789+
'$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
790+
791+
# git-upload-archive (dashed) for t5000
792+
install -m755 -d '$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
793+
install -m755 git-upload-archive.exe '$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
794+
795+
# git-difftool--helper for t7800
796+
install -m755 -d '$(DESTDIR_SQ)/$(MINGW_PREFIX)/libexec/git-core'
797+
install -m755 git-difftool--helper \
798+
'$(DESTDIR_SQ)/$(MINGW_PREFIX)/libexec/git-core'
743799
endif
744800
ifeq ($(uname_S),QNX)
745801
COMPAT_CFLAGS += -DSA_RESTART=0

git-sh-setup.sh

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,30 @@ create_virtual_base() {
292292
# Platform specific tweaks to work around some commands
293293
case $(uname -s) in
294294
*MINGW*)
295-
# Windows has its own (incompatible) sort and find
296-
sort () {
297-
/usr/bin/sort "$@"
298-
}
299-
find () {
300-
/usr/bin/find "$@"
301-
}
302-
# git sees Windows-style pwd
303-
pwd () {
304-
builtin pwd -W
305-
}
295+
if test -x /usr/bin/sort
296+
then
297+
# Windows has its own (incompatible) sort; override
298+
sort () {
299+
/usr/bin/sort "$@"
300+
}
301+
fi
302+
if test -x /usr/bin/find
303+
then
304+
# Windows has its own (incompatible) find; override
305+
find () {
306+
/usr/bin/find "$@"
307+
}
308+
fi
309+
# On Windows, Git wants Windows paths. But /usr/bin/pwd spits out
310+
# Unix-style paths. At least in Bash, we have a builtin pwd that
311+
# understands the -W option to force "mixed" paths, i.e. with drive
312+
# prefix but still with forward slashes. Let's use that, if available.
313+
if type builtin >/dev/null 2>&1
314+
then
315+
pwd () {
316+
builtin pwd -W
317+
}
318+
fi
306319
is_absolute_path () {
307320
case "$1" in
308321
[/\\]* | [A-Za-z]:*)

t/helper/test-cmp.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "test-tool.h"
2+
#include "git-compat-util.h"
3+
#include "strbuf.h"
4+
#include "gettext.h"
5+
#include "parse-options.h"
6+
#include "run-command.h"
7+
8+
#ifdef WIN32
9+
#define NO_SUCH_DIR "\\\\.\\GLOBALROOT\\invalid"
10+
#else
11+
#define NO_SUCH_DIR "/dev/null"
12+
#endif
13+
14+
static int run_diff(const char *path1, const char *path2)
15+
{
16+
struct child_process cmd = CHILD_PROCESS_INIT;
17+
18+
cmd.git_cmd = 1;
19+
cmd.no_stdin = 1;
20+
strvec_pushl(&cmd.args, "diff", "--no-index", path1, path2, NULL);
21+
strvec_pushl(&cmd.env, "GIT_PAGER=cat", "GIT_DIR=" NO_SUCH_DIR,
22+
"HOME=" NO_SUCH_DIR, NULL);
23+
return run_command(&cmd);
24+
}
25+
26+
int cmd__cmp(int argc, const char **argv)
27+
{
28+
FILE *f0, *f1;
29+
struct strbuf b0 = STRBUF_INIT, b1 = STRBUF_INIT;
30+
31+
if (argc != 3)
32+
die("Require exactly 2 arguments, got %d", argc);
33+
34+
if (!(f0 = !strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r")))
35+
return error_errno("could not open '%s'", argv[1]);
36+
if (!(f1 = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"))) {
37+
fclose(f0);
38+
return error_errno("could not open '%s'", argv[2]);
39+
}
40+
41+
for (;;) {
42+
int r0 = strbuf_getline(&b0, f0);
43+
int r1 = strbuf_getline(&b1, f1);
44+
45+
if (r0 == EOF) {
46+
fclose(f0);
47+
fclose(f1);
48+
strbuf_release(&b0);
49+
strbuf_release(&b1);
50+
if (r1 == EOF)
51+
return 0;
52+
cmp_failed:
53+
if (!run_diff(argv[1], argv[2]))
54+
die("Huh? 'diff --no-index %s %s' succeeded",
55+
argv[1], argv[2]);
56+
return 1;
57+
}
58+
if (r1 == EOF || strbuf_cmp(&b0, &b1)) {
59+
fclose(f0);
60+
fclose(f1);
61+
strbuf_release(&b0);
62+
strbuf_release(&b1);
63+
goto cmp_failed;
64+
}
65+
}
66+
}

t/helper/test-iconv.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "test-tool.h"
2+
#include "git-compat-util.h"
3+
#include "strbuf.h"
4+
#include "gettext.h"
5+
#include "parse-options.h"
6+
#include "utf8.h"
7+
8+
int cmd__iconv(int argc, const char **argv)
9+
{
10+
struct strbuf buf = STRBUF_INIT;
11+
char *from = NULL, *to = NULL, *p;
12+
size_t len;
13+
int ret = 0;
14+
const char * const iconv_usage[] = {
15+
N_("test-helper --iconv [<options>]"),
16+
NULL
17+
};
18+
struct option options[] = {
19+
OPT_STRING('f', "from-code", &from, "encoding", "from"),
20+
OPT_STRING('t', "to-code", &to, "encoding", "to"),
21+
OPT_END()
22+
};
23+
24+
argc = parse_options(argc, argv, NULL, options,
25+
iconv_usage, 0);
26+
27+
if (argc > 1 || !from || !to)
28+
usage_with_options(iconv_usage, options);
29+
30+
if (!argc) {
31+
if (strbuf_read(&buf, 0, 2048) < 0)
32+
die_errno("Could not read from stdin");
33+
} else if (strbuf_read_file(&buf, argv[0], 2048) < 0)
34+
die_errno("Could not read from '%s'", argv[0]);
35+
36+
p = reencode_string_len(buf.buf, buf.len, to, from, &len);
37+
if (!p)
38+
die_errno("Could not reencode");
39+
if (write(1, p, len) < 0)
40+
ret = !!error_errno("Could not write %"PRIuMAX" bytes",
41+
(uintmax_t)len);
42+
43+
strbuf_release(&buf);
44+
free(p);
45+
46+
return ret;
47+
}

0 commit comments

Comments
 (0)