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.