29 #include <string_view>
34 #include <sys/types.h>
38 # include <sys/wait.h>
59 LOGCALL_STATIC(DB, RETURN_TYPE(pair<int, string>),
"ProgClient::run_program", progname | args |
Literal(
"[&child]"));
61 string context{
"remote:prog("};
67 #if defined HAVE_SOCKETPAIR && defined HAVE_FORK
74 if (socketpair(PF_UNIX, SOCK_STREAM|
SOCK_CLOEXEC, 0, fds) < 0) {
79 string progname_string{progname};
86 string args_buf{args};
88 argv.push_back(&progname_string[0]);
89 if (!args_buf.empty()) {
91 argv.push_back(&args_buf[0]);
92 for (
char& ch : args_buf) {
96 if (&ch == argv.back()) argv.pop_back();
98 argv.push_back(&ch + 1);
102 if (&args_buf.back() == argv.back()) argv.pop_back();
104 argv.push_back(
nullptr);
120 RETURN({fds[0], context});
132 int dup_to_first = 0;
137 dup2(fds[1], dup_to_first);
144 dup2(dup_to_first, dup_to_first ^ 1);
147 int devnull =
open(
"/dev/null", O_WRONLY);
151 }
else if (
rare(devnull != 2)) {
158 execvp(progname_string.c_str(), argv.data());
162 #elif defined __WIN32__
163 LARGE_INTEGER counter;
167 QueryPerformanceCounter(&counter);
169 snprintf(pipename,
sizeof(pipename),
170 "\\\\.\\pipe\\xapian-remote-%lx-%lx_%" PRIx64,
171 static_cast<unsigned long>(GetCurrentProcessId()),
172 static_cast<unsigned long>(GetCurrentThreadId()),
173 static_cast<unsigned long long>(counter.QuadPart));
174 pipename[
sizeof(pipename) - 1] =
'\0';
176 HANDLE hPipe = CreateNamedPipe(pipename,
177 PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
179 1, 4096, 4096, NMPWAIT_USE_DEFAULT_WAIT,
182 if (hPipe == INVALID_HANDLE_VALUE) {
185 -
int(GetLastError()));
188 HANDLE hClient = CreateFile(pipename,
189 GENERIC_READ|GENERIC_WRITE, 0, NULL,
191 FILE_FLAG_OVERLAPPED, NULL);
193 if (hClient == INVALID_HANDLE_VALUE) {
196 -
int(GetLastError()));
199 if (!ConnectNamedPipe(hPipe, NULL) &&
200 GetLastError() != ERROR_PIPE_CONNECTED) {
203 -
int(GetLastError()));
207 SetHandleInformation(hClient, HANDLE_FLAG_INHERIT, 1);
210 PROCESS_INFORMATION procinfo;
211 memset(&procinfo, 0,
sizeof(PROCESS_INFORMATION));
213 STARTUPINFO startupinfo;
214 memset(&startupinfo, 0,
sizeof(STARTUPINFO));
215 startupinfo.cb =
sizeof(STARTUPINFO);
216 startupinfo.hStdError = hClient;
217 startupinfo.hStdOutput = hClient;
218 startupinfo.hStdInput = hClient;
219 startupinfo.dwFlags |= STARTF_USESTDHANDLES;
222 string progname_string{progname};
224 string cmdline{progname};
229 BOOL ok = CreateProcess(progname_string.c_str(), &cmdline[0],
231 &startupinfo, &procinfo);
235 -
int(GetLastError()));
238 CloseHandle(hClient);
239 CloseHandle(procinfo.hThread);
240 child = procinfo.hProcess;
241 RETURN({_open_osfhandle(intptr_t(hPipe), O_RDWR|
O_BINARY), context});
244 # error ProgClient needs porting to this platform
258 waitpid(child, 0, 0);
260 WaitForSingleObject(child, INFINITE);
static std::pair< int, std::string > run_program(std::string_view progname, std::string_view args, pid_t &child)
Start the child process.
Indicates a problem communicating with a remote database.
Implementation of closefrom() function.
#define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS)
Hierarchy of classes which Xapian can throw as exceptions.
Database open(std::string_view host, unsigned int port, unsigned timeout=10000, unsigned connect_timeout=10000)
Construct a Database object for read-only access to a remote database accessed via a TCP connection.
Implementation of RemoteDatabase using a spawned server.
include <fcntl.h>, but working around broken platforms.
include <sys/socket.h> with portability workarounds.
<unistd.h>, but with compat.