1#include "test-tool.h"
2#include "git-compat-util.h"
3#include "strbuf.h"
4
5#ifdef GIT_WINDOWS_NATIVE
6static const char *usage_string = "<pipe-filename>";
7
8#define TEST_BUFSIZE (4096)
9
10int cmd__windows_named_pipe(int argc, const char **argv)
11{
12 const char *filename;
13 struct strbuf pathname = STRBUF_INIT;
14 int err;
15 HANDLE h;
16 BOOL connected;
17 char buf[TEST_BUFSIZE + 1];
18
19 if (argc < 2)
20 goto print_usage;
21 filename = argv[1];
22 if (strchr(filename, '/') || strchr(filename, '\\'))
23 goto print_usage;
24 strbuf_addf(&pathname, "//./pipe/%s", filename);
25
26 /*
27 * Create a single instance of the server side of the named pipe.
28 * This will allow exactly one client instance to connect to it.
29 */
30 h = CreateNamedPipeA(
31 pathname.buf,
32 PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
33 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
34 PIPE_UNLIMITED_INSTANCES,
35 TEST_BUFSIZE, TEST_BUFSIZE, 0, NULL);
36 if (h == INVALID_HANDLE_VALUE) {
37 err = err_win_to_posix(GetLastError());
38 fprintf(stderr, "CreateNamedPipe failed: %s\n",
39 strerror(err));
40 return err;
41 }
42
43 connected = ConnectNamedPipe(h, NULL)
44 ? TRUE
45 : (GetLastError() == ERROR_PIPE_CONNECTED);
46 if (!connected) {
47 err = err_win_to_posix(GetLastError());
48 fprintf(stderr, "ConnectNamedPipe failed: %s\n",
49 strerror(err));
50 CloseHandle(h);
51 return err;
52 }
53
54 while (1) {
55 DWORD nbr;
56 BOOL success = ReadFile(h, buf, TEST_BUFSIZE, &nbr, NULL);
57 if (!success || nbr == 0)
58 break;
59 buf[nbr] = 0;
60
61 write(1, buf, nbr);
62 }
63
64 DisconnectNamedPipe(h);
65 CloseHandle(h);
66 return 0;
67
68print_usage:
69 fprintf(stderr, "usage: %s %s\n", argv[0], usage_string);
70 return 1;
71}
72#endif