5wchar_t *get_git_branch(
const wchar_t *git_dir_arg,
6 size_t git_dir_arg_len,
7 const wchar_t *work_tree_arg,
8 size_t work_tree_arg_len) {
9 char *result = malloc(255);
10 wchar_t *cmd, *w_result;
11 cmd = w_result =
nullptr;
15 memset(result, 0, 255);
16 HANDLE pipe_read, pipe_write;
17 SECURITY_ATTRIBUTES sa_attr = {.lpSecurityDescriptor =
nullptr,
20 .nLength =
sizeof(SECURITY_ATTRIBUTES)};
22 if (!CreatePipe(&pipe_read, &pipe_write, &sa_attr, 0)) {
25 STARTUPINFO si = {.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES,
26 .hStdOutput = pipe_write,
27 .hStdError = pipe_write,
28 .wShowWindow = SW_HIDE};
29 PROCESS_INFORMATION pi = {0};
30 size_t cmd_len = git_dir_arg_len + work_tree_arg_len + 30;
31 cmd = calloc(cmd_len, WL);
33 CloseHandle(pipe_write);
34 CloseHandle(pipe_read);
37 wmemset(cmd, L
'\0', cmd_len);
39 cmd, cmd_len, TEXT(
"git.exe %ls %ls branch --show-current"), git_dir_arg, work_tree_arg);
40 cmd[cmd_len - 1] = L
'\0';
41 bool ret = CreateProcess(
42 nullptr, cmd,
nullptr,
nullptr,
true, CREATE_NO_WINDOW,
nullptr,
nullptr, &si, &pi);
44 CloseHandle(pipe_write);
45 CloseHandle(pipe_read);
48 bool proc_ended =
false;
49 for (; !proc_ended;) {
51 proc_ended = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;
56 memset(buf, L
'\0', 255);
59 if (!PeekNamedPipe(pipe_read,
nullptr, 0,
nullptr, &avail,
nullptr) || !avail ||
60 !ReadFile(pipe_read, buf, min(
sizeof(buf) - 1, avail), &read,
nullptr) || !read) {
63 buf[min(
sizeof(buf) - 1, avail)] = L
'\0';
65 strncat(result, buf, proc_ended ? avail - 1 : avail);
69 CloseHandle(pipe_write);
70 CloseHandle(pipe_read);
71 CloseHandle(pi.hProcess);
72 CloseHandle(pi.hThread);
73 size_t res_len = strlen(result);
74 int w_len = MultiByteToWideChar(CP_UTF8, 0, result, (
int)res_len,
nullptr, 0);
75 w_result = calloc((
size_t)w_len + 1, WL);
79 MultiByteToWideChar(CP_UTF8, 0, result, (
int)res_len, w_result, w_len);
80 w_result[w_len] = L
'\0';