27 struct sockaddr* ai_addr;
34 #include <arpa/inet.h> 36 #include <netinet/in.h> 38 #include <semaphore.h> 42 #include <sys/select.h> 43 #include <sys/socket.h> 45 #include <sys/prctl.h> 57 #include "config_auto.h" 64 mutex_ = CreateMutex(0,
FALSE, 0);
66 pthread_mutex_init(&mutex_, NULL);
72 WaitForSingleObject(mutex_, INFINITE);
74 pthread_mutex_lock(&mutex_);
82 pthread_mutex_unlock(&mutex_);
89 LPTHREAD_START_ROUTINE f = (LPTHREAD_START_ROUTINE)func;
91 HANDLE newthread = CreateThread(NULL,
100 pthread_attr_init(&attr);
101 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
102 pthread_create(&helper, &attr, func, arg);
106 #ifndef GRAPHICS_DISABLED 122 proc.append(executable);
125 std::cout <<
"Starting " << proc << std::endl;
127 STARTUPINFO start_info;
128 PROCESS_INFORMATION proc_info;
129 GetStartupInfo(&start_info);
130 if (!CreateProcess(NULL, const_cast<char*>(proc.c_str()), NULL, NULL,
FALSE,
131 CREATE_NO_WINDOW | DETACHED_PROCESS, NULL, NULL,
132 &start_info, &proc_info))
141 prctl(PR_SET_PDEATHSIG, 2, 0, 0, 0);
143 char* mutable_args = strdup(args);
145 for (
int i = 0; mutable_args[i]; ++i) {
146 if (mutable_args[i] ==
' ') {
150 char** argv =
new char*[argc + 2];
151 argv[0] = strdup(executable);
152 argv[1] = mutable_args;
154 bool inquote =
false;
155 for (
int i = 0; mutable_args[i]; ++i) {
156 if (!inquote && mutable_args[i] ==
' ') {
157 mutable_args[i] =
'\0';
158 argv[argc++] = mutable_args + i + 1;
159 }
else if (mutable_args[i] ==
'"') {
161 mutable_args[i] =
' ';
165 execvp(executable, argv);
175 semaphore_ = CreateSemaphore(0, 0, 10, 0);
176 #elif defined(__APPLE__) 178 snprintf(name,
sizeof(name),
"%ld", random());
180 semaphore_ = sem_open(name, O_CREAT , S_IWUSR, 0);
181 if (semaphore_ == SEM_FAILED) {
185 sem_init(&semaphore_, 0, 0);
191 ReleaseSemaphore(semaphore_, 1, NULL);
192 #elif defined(__APPLE__) 193 sem_post(semaphore_);
195 sem_post(&semaphore_);
201 WaitForSingleObject(semaphore_, INFINITE);
202 #elif defined(__APPLE__) 203 sem_wait(semaphore_);
205 sem_wait(&semaphore_);
212 msg_buffer_out_.append(msg);
213 mutex_send_.Unlock();
219 while (!msg_buffer_out_.empty()) {
220 int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
221 msg_buffer_out_.erase(0, i);
223 mutex_send_.Unlock();
230 #if defined(_WIN32) || defined(__CYGWIN__) 231 if (has_content) { result = strtok (NULL,
"\n"); }
233 if (buffer_ptr_ != NULL) { result =
strtok_r(NULL,
"\n", &buffer_ptr_); }
237 if (result != NULL) {
return result;
252 FD_SET(stream_, &readfds);
254 int i = select(stream_+1, &readfds, NULL, NULL, &tv);
257 if (i == 0) {
return NULL; }
260 i = recv(stream_, msg_buffer_in_, kMaxMsgSize, 0);
263 if (i <= 0) {
return NULL; }
264 msg_buffer_in_[i] =
'\0';
267 return strtok(msg_buffer_in_,
"\n");
270 return strtok_r(msg_buffer_in_,
"\n", &buffer_ptr_);
278 closesocket(stream_);
286 static const char* ScrollViewProg() {
288 const char* prog =
"java -Xms512m -Xmx1024m";
290 const char* prog =
"sh";
297 static std::string ScrollViewCommand(std::string scrollview_path) {
304 const char* cmd_template =
"-Djava.library.path=%s -jar %s/ScrollView.jar";
307 const char* cmd_template =
308 "-c \"trap 'kill %%1' 0 1 2 ; java " 309 "-Xms1024m -Xmx2048m -jar %s/ScrollView.jar" 312 int cmdlen = strlen(cmd_template) + 4*strlen(scrollview_path.c_str()) + 1;
313 char* cmd =
new char[cmdlen];
314 const char* sv_path = scrollview_path.c_str();
315 snprintf(cmd, cmdlen, cmd_template, sv_path, sv_path, sv_path, sv_path);
316 std::string command(cmd);
323 static void FreeAddrInfo(
struct addrinfo* addr_info) {
324 #if defined(__linux__) 325 freeaddrinfo(addr_info);
327 delete addr_info->ai_addr;
334 #if !defined(__linux__) 335 static int GetAddrInfoNonLinux(
const char* hostname,
int port,
336 struct addrinfo** addr_info) {
338 struct sockaddr_in* address;
339 *addr_info =
new struct addrinfo;
340 memset(*addr_info, 0,
sizeof(
struct addrinfo));
341 address =
new struct sockaddr_in;
342 memset(address, 0,
sizeof(
struct sockaddr_in));
344 (*addr_info)->ai_addr = (
struct sockaddr*) address;
345 (*addr_info)->ai_addrlen =
sizeof(
struct sockaddr);
346 (*addr_info)->ai_family = AF_INET;
347 (*addr_info)->ai_socktype = SOCK_STREAM;
349 struct hostent *name;
352 WSAStartup(MAKEWORD(1, 1), &wsaData);
353 name = gethostbyname(hostname);
355 name = gethostbyname(hostname);
359 FreeAddrInfo(*addr_info);
365 address->sin_family = name->h_addrtype;
366 memcpy((
char *) &address->sin_addr.s_addr,
367 name->h_addr_list[0], name->h_length);
368 address->sin_port = htons(port);
376 static int GetAddrInfo(
const char* hostname,
int port,
377 struct addrinfo** address) {
378 #if defined(__linux__) 380 snprintf(port_str, 40,
"%d", port);
381 return getaddrinfo(hostname, port_str, NULL, address);
383 return GetAddrInfoNonLinux(hostname, port, address);
390 msg_buffer_in_ =
new char[kMaxMsgSize + 1];
391 msg_buffer_in_[0] =
'\0';
396 struct addrinfo *addr_info = NULL;
398 if (GetAddrInfo(hostname, port, &addr_info) != 0) {
399 std::cerr <<
"Error resolving name for ScrollView host " 400 << std::string(hostname) <<
":" << port << std::endl;
403 stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
404 addr_info->ai_protocol);
407 if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
408 const char* scrollview_path = getenv(
"SCROLLVIEW_PATH");
409 if (scrollview_path == NULL) {
410 #ifdef SCROLLVIEW_PATH 412 #define _XSTR(a) _STR(a) 413 scrollview_path = _XSTR(SCROLLVIEW_PATH);
417 scrollview_path =
".";
420 const char *prog = ScrollViewProg();
421 std::string command = ScrollViewCommand(scrollview_path);
428 stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
429 addr_info->ai_protocol);
431 while (connect(stream_, addr_info->ai_addr,
432 addr_info->ai_addrlen) < 0) {
433 std::cout <<
"ScrollView: Waiting for server...\n";
441 stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
442 addr_info->ai_protocol);
445 FreeAddrInfo(addr_info);
449 delete[] msg_buffer_in_;
452 #endif // GRAPHICS_DISABLED
static void StartProcess(const char *executable, const char *args)
Starts a new process.
char * strtok_r(char *s1, const char *s2, char **lasts)
void Unlock()
Unlocks on a mutex.
SVMutex()
Sets up a new mutex.
static void ExitThread()
Signals a thread to exit.
static void StartThread(void *(*func)(void *), void *arg)
Create new thread.
void Flush()
Flush the buffer.
SVNetwork(const char *hostname, int port)
Set up a connection to hostname on port.
void Wait()
Wait on a semaphore.
void Send(const char *msg)
Put a message in the messagebuffer to the server and try to send it.
SVSemaphore()
Sets up a semaphore.
void Lock()
Locks on a mutex.
void Close()
Close the connection to the server.
void Signal()
Signal a semaphore.