Fix piping to TortoiseGitUDiff by checking for ERROR_BROKEN_PIPE and treating that...
[TortoiseGit.git] / src / TortoisePlink / Windows / local-proxy.c
blobe70f60cfce2d6326ce1eeee822fe8e30e1c06470
1 /*
2 * local-proxy.c: Windows implementation of platform_new_connection(),
3 * supporting an OpenSSH-like proxy command via the handle-io.c
4 * mechanism.
5 */
7 #include <stdio.h>
8 #include <assert.h>
10 #include "tree234.h"
11 #include "putty.h"
12 #include "network.h"
13 #include "proxy/proxy.h"
15 char *platform_setup_local_proxy(Socket *socket, const char *cmd)
17 HANDLE us_to_cmd, cmd_from_us;
18 HANDLE us_from_cmd, cmd_to_us;
19 HANDLE us_from_cmd_err, cmd_err_to_us;
20 SECURITY_ATTRIBUTES sa;
21 STARTUPINFO si;
22 PROCESS_INFORMATION pi;
25 * Create the pipes to the proxy command, and spawn the proxy
26 * command process.
28 sa.nLength = sizeof(sa);
29 sa.lpSecurityDescriptor = NULL; /* default */
30 sa.bInheritHandle = true;
31 if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
32 return dupprintf("Unable to create pipes for proxy command: %s",
33 win_strerror(GetLastError()));
36 if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
37 CloseHandle(us_from_cmd);
38 CloseHandle(cmd_to_us);
39 return dupprintf("Unable to create pipes for proxy command: %s",
40 win_strerror(GetLastError()));
43 if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
44 CloseHandle(us_from_cmd);
45 CloseHandle(cmd_to_us);
46 CloseHandle(us_to_cmd);
47 CloseHandle(cmd_from_us);
48 return dupprintf("Unable to create pipes for proxy command: %s",
49 win_strerror(GetLastError()));
52 SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
53 SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
54 if (us_from_cmd_err != NULL)
55 SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);
57 si.cb = sizeof(si);
58 si.lpReserved = NULL;
59 si.lpDesktop = NULL;
60 si.lpTitle = NULL;
61 si.dwFlags = STARTF_USESTDHANDLES;
62 si.cbReserved2 = 0;
63 si.lpReserved2 = NULL;
64 si.hStdInput = cmd_from_us;
65 si.hStdOutput = cmd_to_us;
66 si.hStdError = cmd_err_to_us;
67 char *cmd_mutable = dupstr(cmd); /* CreateProcess needs non-const char * */
68 CreateProcess(NULL, cmd_mutable, NULL, NULL, true,
69 CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
70 NULL, NULL, &si, &pi);
71 sfree(cmd_mutable);
72 CloseHandle(pi.hProcess);
73 CloseHandle(pi.hThread);
75 CloseHandle(cmd_from_us);
76 CloseHandle(cmd_to_us);
78 if (cmd_err_to_us != NULL)
79 CloseHandle(cmd_err_to_us);
81 setup_handle_socket(socket, us_to_cmd, us_from_cmd, us_from_cmd_err,
82 false);
84 return NULL;
87 Socket *platform_new_connection(SockAddr *addr, const char *hostname,
88 int port, bool privport,
89 bool oobinline, bool nodelay, bool keepalive,
90 Plug *plug, Conf *conf, Interactor *itr)
92 if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
93 return NULL;
95 DeferredSocketOpener *opener = local_proxy_opener(
96 addr, port, plug, conf, itr);
97 Socket *socket = make_deferred_handle_socket(opener, addr, port, plug);
98 local_proxy_opener_set_socket(opener, socket);
99 return socket;
102 Socket *platform_start_subprocess(const char *cmd, Plug *plug,
103 const char *prefix)
105 Socket *socket = make_deferred_handle_socket(
106 null_deferred_socket_opener(),
107 sk_nonamelookup("<local command>"), 0, plug);
108 char *err = platform_setup_local_proxy(socket, cmd);
109 handle_socket_set_psb_prefix(socket, prefix);
111 if (err) {
112 sk_close(socket);
113 socket = new_error_socket_fmt(plug, "%s", err);
114 sfree(err);
117 return socket;