37 #include <sys/types.h> 40 # include <sys/wait.h> 53 split_words(
const string &text, vector<string> &words,
char ws =
' ')
56 if (i < text.length() && text[0] == ws) {
57 i = text.find_first_not_of(ws, i);
59 while (i < text.length()) {
60 size_t j = text.find_first_of(ws, i);
61 words.push_back(text.substr(i, j - i));
62 i = text.find_first_not_of(ws, j);
68 double timeout_,
bool writable,
int flags)
70 timeout_, get_progcontext(progname, args), writable,
73 LOGCALL_CTOR(DB,
"ProgClient", progname | args | timeout_ | writable | flags);
79 LOGCALL_STATIC(DB,
string,
"ProgClient::get_progcontext", progname | args);
80 RETURN(
"remote:prog(" + progname +
" " + args +
")");
94 #if defined HAVE_SOCKETPAIR && defined HAVE_FORK 100 if (socketpair(PF_UNIX, SOCK_STREAM|
SOCK_CLOEXEC, 0, sv) < 0) {
109 vector<string> argvec;
111 const char **new_argv =
new const char *[argvec.size() + 2];
132 #if defined F_SETFD && defined FD_CLOEXEC 142 (void)fcntl(sv[1], F_SETFD, 0);
158 int stderrfd =
open(
"/dev/null", O_WRONLY);
159 if (stderrfd == -1) {
168 new_argv[0] = progname.c_str();
169 for (vector<string>::size_type i = 0; i < argvec.size(); ++i) {
170 new_argv[i + 1] = argvec[i].c_str();
172 new_argv[argvec.size() + 1] = 0;
173 execvp(progname.c_str(),
const_cast<char *
const *
>(new_argv));
183 #elif defined __WIN32__ 184 static unsigned int pipecount = 0;
186 sprintf(pipename,
"\\\\.\\pipe\\xapian-remote-%lx-%lx-%x",
187 static_cast<unsigned long>(GetCurrentProcessId()),
188 static_cast<unsigned long>(GetCurrentThreadId()), pipecount++);
190 HANDLE hPipe = CreateNamedPipe(pipename,
191 PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
193 1, 4096, 4096, NMPWAIT_USE_DEFAULT_WAIT,
196 if (hPipe == INVALID_HANDLE_VALUE) {
199 -
int(GetLastError()));
202 HANDLE hClient = CreateFile(pipename,
203 GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
204 FILE_FLAG_OVERLAPPED, NULL);
206 if (hClient == INVALID_HANDLE_VALUE) {
209 -
int(GetLastError()));
212 if (!ConnectNamedPipe(hPipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED) {
215 -
int(GetLastError()));
219 SetHandleInformation(hClient, HANDLE_FLAG_INHERIT, 1);
222 PROCESS_INFORMATION procinfo;
223 memset(&procinfo, 0,
sizeof(PROCESS_INFORMATION));
225 STARTUPINFO startupinfo;
226 memset(&startupinfo, 0,
sizeof(STARTUPINFO));
227 startupinfo.cb =
sizeof(STARTUPINFO);
228 startupinfo.hStdError = hClient;
229 startupinfo.hStdOutput = hClient;
230 startupinfo.hStdInput = hClient;
231 startupinfo.dwFlags |= STARTF_USESTDHANDLES;
233 string cmdline{progname};
238 BOOL ok = CreateProcess(progname.c_str(), &cmdline[0], 0, 0, TRUE, 0, 0, 0,
239 &startupinfo, &procinfo);
243 -
int(GetLastError()));
246 CloseHandle(hClient);
247 CloseHandle(procinfo.hThread);
248 child = procinfo.hProcess;
261 waitpid(
child, 0, 0);
263 WaitForSingleObject(
child, INFINITE);
void close()
Close the database.
#define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS)
include <sys/socket.h> with portability workarounds.
Implementation of closefrom() function.
WritableDatabase open()
Construct a WritableDatabase object for a new, empty InMemory database.
void do_close()
Close the socket.
Hierarchy of classes which Xapian can throw as exceptions.
ProgClient(const ProgClient &)
Don't allow copying.
pid_t child
Process id of the child process.
static void split_words(const string &text, vector< string > &words, char ws=' ')
Split a string into a vector of strings, using a given separator character (default space) ...
static std::string get_progcontext(const std::string &progname, const std::string &args)
Generate context string for Xapian::Error exception objects.
RemoteDatabase is the baseclass for remote database implementations.
Implementation of RemoteDatabase using a spawned server.
#define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS)
Indicates a problem communicating with a remote database.
include <fcntl.h>, but working around broken platforms.
static int run_program(const std::string &progname, const std::string &args, pid_t &child)
Start the child process.