Merge branch 'jk/close-duped-fd-before-unlock-for-bundle'
[git] / t / helper / test-windows-named-pipe.c
1 #include "test-tool.h"
2 #include "git-compat-util.h"
3 #include "strbuf.h"
4
5 #ifdef GIT_WINDOWS_NATIVE
6 static const char *usage_string = "<pipe-filename>";
7
8 #define TEST_BUFSIZE (4096)
9
10 int 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
68 print_usage:
69         fprintf(stderr, "usage: %s %s\n", argv[0], usage_string);
70         return 1;
71 }
72 #endif