26 struct sockaddr* ai_addr;
33 #include <arpa/inet.h>
34 #include <netinet/in.h>
36 #include <semaphore.h>
41 #include <sys/socket.h>
43 #include <sys/prctl.h>
55 #include "config_auto.h"
58 #ifndef GRAPHICS_DISABLED
77 proc.append(executable);
80 std::cout <<
"Starting " << proc << std::endl;
82 STARTUPINFO start_info;
83 PROCESS_INFORMATION proc_info;
84 GetStartupInfo(&start_info);
86 CREATE_NO_WINDOW | DETACHED_PROCESS,
NULL,
NULL,
87 &start_info, &proc_info))
96 prctl(PR_SET_PDEATHSIG, 2, 0, 0, 0);
98 char* mutable_args = strdup(args);
100 for (
int i = 0; mutable_args[i]; ++i) {
101 if (mutable_args[i] ==
' ') {
105 char** argv =
new char*[argc + 2];
106 argv[0] = strdup(executable);
107 argv[1] = mutable_args;
109 bool inquote =
false;
110 for (
int i = 0; mutable_args[i]; ++i) {
111 if (!inquote && mutable_args[i] ==
' ') {
112 mutable_args[i] =
'\0';
113 argv[argc++] = mutable_args + i + 1;
114 }
else if (mutable_args[i] ==
'"') {
116 mutable_args[i] =
' ';
120 execvp(executable, argv);
127 semaphore_ = CreateSemaphore(0, 0, 10, 0);
128 #elif defined(__APPLE__)
130 snprintf(name,
sizeof(name),
"%d", random());
132 semaphore_ = sem_open(name, O_CREAT , S_IWUSR, 0);
133 if (semaphore_ == SEM_FAILED) {
137 sem_init(&semaphore_, 0, 0);
143 ReleaseSemaphore(semaphore_, 1,
NULL);
144 #elif defined(__APPLE__)
145 sem_post(semaphore_);
147 sem_post(&semaphore_);
153 WaitForSingleObject(semaphore_, INFINITE);
154 #elif defined(__APPLE__)
155 sem_wait(semaphore_);
157 sem_wait(&semaphore_);
163 mutex_ = CreateMutex(0,
FALSE, 0);
165 pthread_mutex_init(&mutex_,
NULL);
171 WaitForSingleObject(mutex_, INFINITE);
173 pthread_mutex_lock(&mutex_);
179 ReleaseMutex(mutex_);
181 pthread_mutex_unlock(&mutex_);
189 LPTHREAD_START_ROUTINE f = (LPTHREAD_START_ROUTINE) func;
191 HANDLE newthread = CreateThread(
200 pthread_create(&helper,
NULL, func, arg);
207 msg_buffer_out_.append(msg);
214 while (msg_buffer_out_.size() > 0) {
215 int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
216 msg_buffer_out_.erase(0, i);
225 #if defined(_WIN32) || defined(__CYGWIN__)
226 if (has_content) { result = strtok (
NULL,
"\n"); }
232 if (result !=
NULL) {
return result;
247 FD_SET(stream_, &readfds);
249 int i = select(stream_+1, &readfds,
NULL,
NULL, &tv);
252 if (i == 0) {
return NULL; }
258 if (i <= 0) {
return NULL; }
259 msg_buffer_in_[i] =
'\0';
262 return strtok(msg_buffer_in_,
"\n");
265 return strtok_r(msg_buffer_in_,
"\n", &buffer_ptr_);
273 closesocket(stream_);
281 static const char* ScrollViewProg() {
283 const char* prog =
"java -Xms512m -Xmx1024m";
285 const char* prog =
"sh";
292 static std::string ScrollViewCommand(std::string scrollview_path) {
299 const char* cmd_template =
"-Djava.library.path=%s -cp %s/ScrollView.jar;"
300 "%s/piccolo2d-core-3.0.jar:%s/piccolo2d-extras-3.0.jar"
301 " com.google.scrollview.ScrollView";
303 const char* cmd_template =
"-c \"trap 'kill %%1' 0 1 2 ; java "
304 "-Xms1024m -Xmx2048m -Djava.library.path=%s -cp %s/ScrollView.jar:"
305 "%s/piccolo2d-core-3.0.jar:%s/piccolo2d-extras-3.0.jar"
306 " com.google.scrollview.ScrollView"
309 int cmdlen = strlen(cmd_template) + 4*strlen(scrollview_path.c_str()) + 1;
310 char* cmd =
new char[cmdlen];
311 const char* sv_path = scrollview_path.c_str();
312 snprintf(cmd, cmdlen, cmd_template, sv_path, sv_path, sv_path, sv_path);
313 std::string command(cmd);
320 static void FreeAddrInfo(
struct addrinfo* addr_info) {
321 #if defined(__linux__)
322 freeaddrinfo(addr_info);
324 delete addr_info->ai_addr;
331 #if !defined(__linux__)
332 static int GetAddrInfoNonLinux(
const char* hostname,
int port,
333 struct addrinfo** addr_info) {
335 struct sockaddr_in* address;
336 *addr_info =
new struct addrinfo;
337 memset(*addr_info, 0,
sizeof(
struct addrinfo));
338 address =
new struct sockaddr_in;
339 memset(address, 0,
sizeof(
struct sockaddr_in));
341 (*addr_info)->ai_addr = (
struct sockaddr*) address;
342 (*addr_info)->ai_addrlen =
sizeof(
struct sockaddr);
343 (*addr_info)->ai_family = AF_INET;
344 (*addr_info)->ai_socktype = SOCK_STREAM;
346 struct hostent *
name;
349 WSAStartup(MAKEWORD(1, 1), &wsaData);
350 name = gethostbyname(hostname);
352 name = gethostbyname(hostname);
356 FreeAddrInfo(*addr_info);
362 address->sin_family = name->h_addrtype;
363 memcpy((
char *) &address->sin_addr.s_addr,
364 name->h_addr_list[0], name->h_length);
365 address->sin_port = htons(port);
373 static int GetAddrInfo(
const char* hostname,
int port,
374 struct addrinfo** address) {
375 #if defined(__linux__)
377 snprintf(port_str, 40,
"%d", port);
378 return getaddrinfo(hostname, port_str,
NULL, address);
380 return GetAddrInfoNonLinux(hostname, port, address);
389 msg_buffer_in_[0] =
'\0';
394 struct addrinfo *addr_info =
NULL;
396 if (GetAddrInfo(hostname, port, &addr_info) != 0) {
397 std::cerr <<
"Error resolving name for ScrollView host "
398 << std::string(hostname) <<
":" << port << std::endl;
401 stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
402 addr_info->ai_protocol);
405 if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
406 const char* scrollview_path = getenv(
"SCROLLVIEW_PATH");
407 if (scrollview_path ==
NULL) {
408 #ifdef SCROLLVIEW_PATH
410 #define _XSTR(a) _STR(a)
411 scrollview_path = _XSTR(SCROLLVIEW_PATH);
415 scrollview_path =
".";
418 const char *prog = ScrollViewProg();
419 std::string command = ScrollViewCommand(scrollview_path);
425 stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
426 addr_info->ai_protocol);
428 while (connect(stream_, addr_info->ai_addr,
429 addr_info->ai_addrlen) < 0) {
430 std::cout <<
"ScrollView: Waiting for server...\n";
437 stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
438 addr_info->ai_protocol);
441 FreeAddrInfo(addr_info);
445 delete[] msg_buffer_in_;
449 #endif // GRAPHICS_DISABLED
void Lock()
Locks on a mutex.
char * strtok_r(char *s1, const char *s2, char **lasts)
void Close()
Close the connection to the server.
void Flush()
Flush the buffer.
static void StartProcess(const char *executable, const char *args)
Starts a new process.
SVMutex()
Sets up a new mutex.
SVSemaphore()
Sets up a semaphore.
void Send(const char *msg)
Put a message in the messagebuffer to the server and try to send it.
static void ExitThread()
Signals a thread to exit.
void Wait()
Wait on a semaphore.
void Signal()
Signal a semaphore.
static void StartThread(void *(*func)(void *), void *arg)
Create new thread.
void Unlock()
Unlocks on a mutex.
SVNetwork(const char *hostname, int port)
Set up a connection to hostname on port.