NamedPipe class splitted into NAmedPipe and NamedPipeListener; nxapush switched to...
[public/netxms.git] / src / libnetxms / nxproc_win32.cpp
CommitLineData
b6883988
VK
1/*
2** NetXMS - Network Management System
3** NetXMS Foundation Library
4** Copyright (C) 2003-2017 Victor Kirhenshtein
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation; either version 3 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
20** File: nxproc_unix.cpp
21**
22**/
23
24#include "libnetxms.h"
25#include <nxproc.h>
26
27/**
28 * Create listener end for named pipe
29 */
30NamedPipeListener *NamedPipeListener::create(const TCHAR *name, NamedPipeRequestHandler reqHandler, void *userArg)
31{
32 mode_t prevMask = 0;
33
34 int s = socket(AF_UNIX, SOCK_STREAM, 0);
35 if (s == INVALID_SOCKET)
36 {
37 nxlog_debug(2, _T("NamedPipeListener(%s): socket() call failed (%s)"), name, _tcserror(errno));
38 return NULL;
39 }
40
41 struct sockaddr_un addrLocal;
42 addrLocal.sun_family = AF_UNIX;
43#ifdef UNICODE
44 sprintf(addrLocal.sun_path, "/tmp/.%S", name);
45#else
46 sprintf(addrLocal.sun_path, "/tmp/.%s", name);
47#endif
48 unlink(addrLocal.sun_path);
49 prevMask = umask(S_IWGRP | S_IWOTH);
50 if (bind(s, (struct sockaddr *)&addrLocal, SUN_LEN(&addrLocal)) == -1)
51 {
52 nxlog_debug(2, _T("NamedPipeListener(%s): bind failed (%s)"), name, _tcserror(errno));
53 umask(prevMask);
54 goto failure;
55 }
56 umask(prevMask);
57
58 if (listen(s, 5) == -1)
59 {
60 nxlog_debug(2, _T("NamedPipeListener(%s): listen() call failed (%s)"), name, _tcserror(errno));
61 goto failure;
62 }
63
64 return new NamedPipeListener(name, s, reqHandler, userArg);
65
66failure:
67 close(s);
68 unlink(addrLocal.sun_path);
69 return NULL;
70}
71
72/**
73 * Pipe destructor
74 */
75NamedPipeListener::~NamedPipeListener()
76{
77 CloseHandle(m_handle);
78 stop();
79}
80
81/**
82 * Named pipe server thread
83 */
84void NamedPipeListener::serverThread()
85{
86 nxlog_debug(2, _T("NamedPipeListener(%s): waiting for connection"), m_name);
87 while(!m_stop)
88 {
89 }
90}
91
92/**
93 * Pipe destructor
94 */
95NamedPipe::~NamedPipe()
96{
97 CloseHandle(m_handle);
98 MutexDestroy(m_writeLock);
99}
100
101/**
102 * Create client end for named pipe
103 */
104NamedPipe *NamedPipe::connect(const TCHAR *name, UINT32 timeout)
105{
106 TCHAR path[MAX_PATH];
107 _sntprintf(path, MAX_PATH, _T("\\\\.\\pipe\\%s"), name);
108
109reconnect:
110 HANDLE h = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
111 if (h == INVALID_HANDLE_VALUE)
112 {
113 if (GetLastError() == ERROR_PIPE_BUSY)
114 {
115 if (WaitNamedPipe(path, timeout))
116 goto reconnect;
117 }
118 return NULL;
119 }
120
121 DWORD pipeMode = PIPE_READMODE_MESSAGE;
122 SetNamedPipeHandleState(h, &pipeMode, NULL, NULL);
123 return new NamedPipe(name, h, false);
124}
125
126/**
127 * Write to pipe
128 */
129bool NamedPipe::write(const void *data, size_t size)
130{
131 DWORD bytes;
132 if (!WriteFile(s_handle, data, size, &bytes, NULL))
133 return false;
134 return bytes == (DWORD)size;
135}