2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2018 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
26 #else /* !HAVE_WIN32 */
28 # include <sys/stat.h>
34 #endif /* HAVE_WIN32 */
38 #include <sys/types.h>
41 #include "namedpipe.h"
44 # define Dmsg(level, ...) printf(__VA_ARGS__ )
49 void namedpipe_init(NamedPipe *self)
51 self->fd = INVALID_HANDLE_VALUE;
55 void namedpipe_free(NamedPipe *self)
57 if (self->fd != INVALID_HANDLE_VALUE) {
58 CloseHandle(self->fd);
59 self->fd = INVALID_HANDLE_VALUE;
64 int namedpipe_create(NamedPipe *self, const char *path, mode_t mode)
67 self->fd = CreateNamedPipeA(
69 PIPE_ACCESS_DUPLEX, // read/write access
70 PIPE_TYPE_MESSAGE | // message type pipe
71 PIPE_READMODE_MESSAGE | // message-read mode
72 PIPE_WAIT, // blocking mode
73 PIPE_UNLIMITED_INSTANCES, // max. instances
74 BUFSIZE, // output buffer size
75 BUFSIZE, // input buffer size
77 NULL); // default security attribute
79 if (self->fd == INVALID_HANDLE_VALUE) {
80 Dmsg(10, "CreateNamedPipe failed, ERR=%d.\n", (int)GetLastError());
87 int namedpipe_open(NamedPipe *self, const char *path, mode_t mode)
89 bool fConnected=false;
92 if (self->fd != INVALID_HANDLE_VALUE) { /* server mode */
94 fConnected = ConnectNamedPipe(self->fd, NULL) ?
95 TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
97 } else { /* client mode */
99 /* Need to wait for creation */
102 self->fd = CreateFileA(
104 GENERIC_WRITE | GENERIC_READ,
106 NULL, // default security attributes
107 OPEN_EXISTING, // opens existing pipe
108 0, // default attributes
109 NULL); // no template file
111 // Break if the pipe handle is valid.
112 if (self->fd != INVALID_HANDLE_VALUE) {
116 /* Wait a little bit for the other side to create the fifo */
117 if (GetLastError() == ERROR_FILE_NOT_FOUND) {
118 Dmsg(10, "File not found, ERR=%d.\n", (int)GetLastError());
123 // Exit if an error other than ERROR_PIPE_BUSY occurs.
124 if (GetLastError() != ERROR_PIPE_BUSY) {
125 Dmsg(10, "CreateFile failed, ERR=%d.\n",
126 (int)GetLastError());
130 // All pipe instances are busy, so wait for 20 seconds.
131 if (!WaitNamedPipeA(path, 20000)) {
132 Dmsg(10, "WaitNamedPipe failed, ERR=%d.\n",
133 (int)GetLastError());
139 DWORD dwMode = PIPE_READMODE_MESSAGE;
141 fConnected = SetNamedPipeHandleState(
142 self->fd, // pipe handle
143 &dwMode, // new pipe mode
144 NULL, // don't set maximum bytes
145 NULL); // don't set maximum time
148 Dmsg(10, "SetNamedPipeHandleState failed, ERR=%d.\n",
149 (int)GetLastError());
154 if (mode & O_WRONLY || mode & O_APPEND) {
157 } else if (mode & O_RDONLY) {
160 self->ifd = _open_osfhandle((intptr_t)self->fd, m);
167 #else /* !HAVE_WIN32 */
169 void namedpipe_init(NamedPipe *self)
176 void namedpipe_free(NamedPipe *self)
178 if (self->fd != -1) {
190 int namedpipe_create(NamedPipe *self, const char *path, mode_t mode)
192 self->name = (char *)malloc(strlen(path) + 1);
193 strcpy(self->name, path);
195 if (mkfifo(path, mode) < 0 && errno != EEXIST) {
202 int namedpipe_open(NamedPipe *self, const char *path, mode_t mode)
204 self->ifd = self->fd = open(path, mode);
208 #endif /* HAVE_WIN32 */
215 #define BUF "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
216 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
217 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
218 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
219 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
220 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
221 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
222 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
223 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
225 int main(int argc, char **argv)
229 char buf[65*1024], file[128];
234 printf("Usage: %s client|server pipe file\n", argv[0]);
240 if (strcmp(argv[1], "server") == 0) {
242 if (namedpipe_create(&p, argv[2], 0600) < 0) {
250 printf("Trying to open %s mode=%d\n", argv[2], mode);
251 fd = namedpipe_open(&p, argv[2], mode);
254 printf("Unable to open pipe\n");
258 if (strcmp(argv[1], "server") == 0) {
259 if (write(fd, BUF, strlen(BUF)+1) != strlen(BUF)+1) {
260 printf("Unable to write data\n");
264 if (write(fd, BUF, strlen(BUF)+1) != strlen(BUF)+1) {
265 printf("Unable to write data\n");
269 fp = fopen(argv[3], "rb");
271 printf("Unable to open %s for reading\n", argv[3]);
275 fseek(fp, 0, SEEK_END);
277 fseek(fp, 0, SEEK_SET);
279 snprintf(buf, sizeof(buf), "%.10d\n", m);
280 write(fd, buf, strlen(buf)+1);
282 while (m > 0 && !feof(fp)) {
283 n = fread(buf, 1, sizeof(buf), fp);
284 Dmsg(000, "read %d from file\n", n);
285 if (write(fd, buf, n) != n) {
286 printf("Unable to write data from file\n");
291 Dmsg(000, "EOF found\n");
295 if ((n = read(fd, buf, sizeof(buf))) != strlen(BUF)+1) {
296 Dmsg(000, "read failed (%d != %d), ERR=%d.\n", n,
297 (int)strlen(BUF)+1, errno);
300 if (read(fd, buf, sizeof(buf)) != strlen(BUF)+1) {
301 Dmsg(000, "read failed, ERR=%d.\n", errno);
305 printf("buf=[%s]\n", buf);
307 snprintf(file, sizeof(file), "%s.out", argv[3]);
308 fp = fopen(file, "wb");
310 printf("Unable to open %s for writing\n", buf);
314 if ((n = read(fd, buf, sizeof(buf))) != 12) {
315 Dmsg(000, "read failed (%d != %d), ERR=%d.\n", n, 12, errno);
320 Dmsg(000, "will read %d from fifo\n", m);
323 n = read(fd, buf, sizeof(buf));
324 Dmsg(000, "Got %d bytes\n", n);
325 if ((o = fwrite(buf, n, 1, fp)) != 1) {
326 Dmsg(000, "write to file failed (%d != %d) ERR=%d.\n", o, n, errno);