git

Форк
0
/
headless.c 
115 строк · 3.2 Кб
1
/*
2
 * headless Git - run Git without opening a console window on Windows
3
 */
4

5
#define STRICT
6
#define WIN32_LEAN_AND_MEAN
7
#define UNICODE
8
#define _UNICODE
9
#include <windows.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <wchar.h>
13

14
/*
15
 * If `dir` contains the path to a Git exec directory, extend `PATH` to
16
 * include the corresponding `bin/` directory (which is where all those
17
 * `.dll` files needed by `git.exe` are, on Windows).
18
 */
19
static int extend_path(wchar_t *dir, size_t dir_len)
20
{
21
	const wchar_t *suffix = L"\\libexec\\git-core";
22
	size_t suffix_len = wcslen(suffix);
23
	wchar_t *env;
24
	DWORD len;
25

26
	if (dir_len < suffix_len)
27
		return 0;
28

29
	dir_len -= suffix_len;
30
	if (memcmp(dir + dir_len, suffix, suffix_len * sizeof(wchar_t)))
31
		return 0;
32

33
	len = GetEnvironmentVariableW(L"PATH", NULL, 0);
34
	if (!len)
35
		return 0;
36

37
	env = _alloca((dir_len + 5 + len) * sizeof(wchar_t));
38
	wcsncpy(env, dir, dir_len);
39
	wcscpy(env + dir_len, L"\\bin;");
40
	if (!GetEnvironmentVariableW(L"PATH", env + dir_len + 5, len))
41
		return 0;
42

43
	SetEnvironmentVariableW(L"PATH", env);
44
	return 1;
45
}
46

47
int WINAPI wWinMain(_In_ HINSTANCE instance,
48
		    _In_opt_ HINSTANCE previous_instance,
49
		    _In_ LPWSTR command_line, _In_ int show)
50
{
51
	wchar_t git_command_line[32768];
52
	size_t size = sizeof(git_command_line) / sizeof(wchar_t);
53
	const wchar_t *needs_quotes = L"";
54
	int slash = 0, i;
55

56
	STARTUPINFO startup_info = {
57
		.cb = sizeof(STARTUPINFO),
58
		.dwFlags = STARTF_USESHOWWINDOW,
59
		.wShowWindow = SW_HIDE,
60
	};
61
	PROCESS_INFORMATION process_info = { 0 };
62
	DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT |
63
		CREATE_NEW_CONSOLE | CREATE_NO_WINDOW;
64
	DWORD exit_code;
65

66
	/* First, determine the full path of argv[0] */
67
	for (i = 0; _wpgmptr[i]; i++)
68
		if (_wpgmptr[i] == L' ')
69
			needs_quotes = L"\"";
70
		else if (_wpgmptr[i] == L'\\')
71
			slash = i;
72

73
	if (slash >= size - 11)
74
		return 127; /* Too long path */
75

76
	/* If it is in Git's exec path, add the bin/ directory to the PATH */
77
	extend_path(_wpgmptr, slash);
78

79
	/* Then, add the full path of `git.exe` as argv[0] */
80
	i = swprintf_s(git_command_line, size, L"%ls%.*ls\\git.exe%ls",
81
		       needs_quotes, slash, _wpgmptr, needs_quotes);
82
	if (i < 0)
83
		return 127; /* Too long path */
84

85
	if (*command_line) {
86
		/* Now, append the command-line arguments */
87
		i = swprintf_s(git_command_line + i, size - i,
88
			       L" %ls", command_line);
89
		if (i < 0)
90
			return 127;
91
	}
92

93
	startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
94
	startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
95
	startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
96

97
	if (!CreateProcess(NULL, /* infer argv[0] from the command line */
98
			   git_command_line, /* modified command line */
99
			   NULL, /* inherit process handles? */
100
			   NULL, /* inherit thread handles? */
101
			   FALSE, /* handles inheritable? */
102
			   creation_flags,
103
			   NULL, /* use this process' environment */
104
			   NULL, /* use this process' working directory */
105
			   &startup_info, &process_info))
106
		return 129; /* could not start */
107
	WaitForSingleObject(process_info.hProcess, INFINITE);
108
	if (!GetExitCodeProcess(process_info.hProcess, &exit_code))
109
		exit_code = 130; /* Could not determine exit code? */
110

111
	CloseHandle(process_info.hProcess);
112
	CloseHandle(process_info.hThread);
113

114
	return (int)exit_code;
115
}
116

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.