Beispiel #1
0
int main(void) 
{
   char buf[1024];
   while(fgets(buf, sizeof(buf), stdin))
   {
      String s(buf); s = s.Trim();

      Queue<String> q;
      if (ExpandFilePathWildCards(s, q) == B_NO_ERROR)
      {
         printf("File path [%s] expanded to " UINT32_FORMAT_SPEC" paths:\n", s(), q.GetNumItems());
         for (uint32 i=0; i<q.GetNumItems(); i++) printf("   - [%s]\n", q[i]());
      }
      else printf("Error, couldn't expand file path [%s]\n", s());
      printf("\n\n");
   }
   return 0;
}
Beispiel #2
0
void PrintToStream(const Queue<int> & q)
{
   printf("Queue state is:\n");
   for (uint32 i=0; i<q.GetNumItems(); i++)
   {
/*
      int val;
      TEST(q.GetItemAt(i, val));    
      printf(UINT32_FORMAT_SPEC" -> %i\n",i,val);
*/
      printf(UINT32_FORMAT_SPEC" -> %i\n",i,q[i]);
   }
}
Beispiel #3
0
   virtual void InternalThreadEntry()
   {
      char buf[128]; muscleSprintf(buf, "TestThread-%p", this);
      const String prefix = buf;
      Queue<TestItemRef> q;
      bool keepGoing = 1;
      uint32 counter = 0;
      while(keepGoing)
      {
         uint32 x = rand() % 10000;
         while(q.GetNumItems() < x) 
         {
            TestItemRef tRef(_pool.ObtainObject());
            if (tRef())
            {
               char buf[128]; muscleSprintf(buf, "-" UINT32_FORMAT_SPEC, ++counter);
               tRef()->SetName(prefix+buf);
               q.AddTail(tRef);
            }
            else WARN_OUT_OF_MEMORY; 
         }
         while(q.GetNumItems() > x) q.RemoveTail();

         // Check to make sure no other threads are overwriting our objects
         for (uint32 i=0; i<q.GetNumItems(); i++) 
         {
            if (q[i]()->GetName().StartsWith(prefix) == false)
            {
               printf("ERROR, thread %p expected prefix [%s], saw [%s] at position " INT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC "\n", this, prefix(), q[i]()->GetName()(), i, q.GetNumItems());
               ExitWithoutCleanup(10);
            }
         }
 
         // Check to see if the main thread wants us to exit yet
         MessageRef r;
         while(WaitForNextMessageFromOwner(r, 0) >= 0) if (r() == NULL) keepGoing = false;
      }
   }
String UnparseArgs(const Queue<String> & args, uint32 startIdx, uint32 endIdx)
{
   String ret;
   endIdx = muscleMin(endIdx, args.GetNumItems());
   for (uint32 i=startIdx; i<endIdx; i++)
   {
      String subRet = args[i];
      subRet.Replace("\"", "\\\"");
      if (subRet.IndexOf(' ') >= 0) subRet = subRet.Append("\"").Prepend("\"");
      if (ret.HasChars()) ret += ' ';
      ret += subRet;
   }
   return ret;
}
String HexBytesToString(const Queue<uint8> & bytes)
{
   const uint32 numBytes = bytes.GetNumItems();

   String ret;
   if (ret.Prealloc(numBytes*3) == B_NO_ERROR)
   {
      for (uint32 i=0; i<numBytes; i++)
      {
         if (i > 0) ret += ' ';
         char b[32]; muscleSprintf(b, "%02x", bytes[i]);
         ret += b;
      }
   }
   return ret;
}
Beispiel #6
0
// This program accepts a directory name as the argument, and will find and print all LogTime()
// calls in and underneath that directory, along with their source-code-location keys. (e.g. "FB72")
int main(int argc, char ** argv) 
{
   CompleteSetupSystem css;

   if (argc < 2)
   {
      printf("Usage:  printsourcelocations dirname\n");
      return 10;
   }

   Directory d(argv[1]);
   if (d.IsValid() == false)
   {
      printf("[%s] is not a valid directory path.\n", argv[1]);
      return 10;
   }

   Queue<String> codes;
   DoSearch(argv[1], codes);
   codes.Sort();
   for (uint32 i=0; i<codes.GetNumItems(); i++) printf("%s\n", codes[i]());

   return 0;
}
Beispiel #7
0
// This program exercises the Queue class.
int main(void) 
{
   CompleteSetupSystem css;  // needed for string-count stats

#ifdef TEST_SWAP_METHOD
   while(1)
   {
      char qs1[512]; printf("Enter q1: "); fflush(stdout); if (fgets(qs1, sizeof(qs1), stdin) == NULL) qs1[0] = '\0';
      char qs2[512]; printf("Enter q2: "); fflush(stdout); if (fgets(qs2, sizeof(qs2), stdin) == NULL) qs2[0] = '\0';

      Queue<int> q1, q2;      
      StringTokenizer t1(qs1), t2(qs2);
      const char * s;
      while((s = t1()) != NULL) q1.AddTail(atoi(s));
      while((s = t2()) != NULL) q2.AddTail(atoi(s));
      printf("T1Before="); PrintToStream(q1);
      printf("T2Before="); PrintToStream(q2);
      q1.SwapContents(q2);
      printf("T1After="); PrintToStream(q1);
      printf("T2After="); PrintToStream(q2);
   }
#endif

#ifdef MUSCLE_USE_CPLUSPLUS11
   {
      Queue<int> q {1,2,3,4,5};
      if (q.GetNumItems() != 5) {printf("Oh no, initialize list constructor didn't work!\n"); exit(10);}
      q = {6,7,8,9,10,11};
      if (q.GetNumItems() != 6) {printf("Oh no, initialize list assignment operator didn't work!\n"); exit(10);}
   }
#endif

   // Test muscleSwap()
   {
      Queue<String> q1, q2;
      q1.AddTail("q1");
      q2.AddTail("q2");
      muscleSwap(q1, q2);
      if ((q1.GetNumItems() != 1)||(q2.GetNumItems() != 1)||(q1[0] != "q2")||(q2[0] != "q1"))
      {
         printf("Oh no, muscleSwap is broken for Message objects!\n");
         exit(10);
      }
      printf("muscleSwap() worked!\n");
   }


   const int testSize = 15;
   Queue<int> q;

   int vars[] = {5,6,7,8,9,10,11,12,13,14,15};

   printf("ADDTAIL TEST\n");
   {
      for (int i=0; i<testSize; i++) 
      {
         TEST(q.AddTail(i));
         printf("len=" UINT32_FORMAT_SPEC"/" UINT32_FORMAT_SPEC"\n", q.GetNumItems(), q.GetNumAllocatedItemSlots());
      }
   } 

   printf("AddTail array\n");
   q.AddTailMulti(vars, ARRAYITEMS(vars));
   PrintToStream(q);

   printf("AddHead array\n");
   q.AddHeadMulti(vars, ARRAYITEMS(vars));
   PrintToStream(q);

   printf("REPLACEITEMAT TEST\n");
   {
      for (int i=0; i<testSize; i++) 
      {
         TEST(q.ReplaceItemAt(i, i+10));
         PrintToStream(q);
      }
   } 

   printf("INSERTITEMAT TEST\n");
   {
      for (int i=0; i<testSize; i++) 
      {
         TEST(q.InsertItemAt(i,i));
         PrintToStream(q);
      }
   }

   printf("REMOVEITEMAT TEST\n");
   {
      for (int i=0; i<testSize; i++) 
      {
         TEST(q.RemoveItemAt(i));
         PrintToStream(q);
      }
   }

   // Check that C++11's move semantics aren't stealing values they shouldn't
   {
      Queue<String> q;
      String myStr = "Magic";
      q.AddTail(myStr);
      if (myStr != "Magic") 
      {
         printf("Error, AddTail() stole my string!\n");
         exit(10);
      }
   }

   printf("SORT TEST 1\n");
   {
      q.Clear();
      for (int i=0; i<testSize; i++)
      {
         int next = rand()%255;
         TEST(q.AddTail(next));
         printf("Added item %i = %i\n", i, q[i]);
      }
      printf("sorting ints...\n");
      q.Sort();
      for (int j=0; j<testSize; j++) printf("Now item %i = %i\n", j, q[j]);
   }

   printf("SORT TEST 2\n");
   {
      Queue<String> q2;
      for (int i=0; i<testSize; i++)
      {
         int next = rand()%255;
         char buf[64];
         sprintf(buf, "%i", next);
         TEST(q2.AddTail(buf));
         printf("Added item %i = %s\n", i, q2[i].Cstr());
      }
      printf("sorting strings...\n");
      q2.Sort();
      for (int j=0; j<testSize; j++) printf("Now item %i = %s\n", j, q2[j].Cstr());
   }

   printf("REMOVE DUPLICATES test\n");
   {
      Queue<int> q;
      const int vars[] = {9,2,3,5,8,3,5,6,6,7,2,3,4,6,8,9,3,5,6,4,3,2,1};
      if (q.AddTailMulti(vars, ARRAYITEMS(vars)) == B_NO_ERROR)
      {
         q.RemoveDuplicateItems(); 
         for (uint32 i=0; i<q.GetNumItems(); i++) printf("%u ", q[i]); printf("\n");
      }
   }

   {
      const uint32 NUM_ITEMS = 1000000;
      const uint32 NUM_RUNS  = 3;
      Queue<int> q; (void) q.EnsureSize(NUM_ITEMS, true);
      double tally = 0.0;
      for (uint32 t=0; t<NUM_RUNS; t++)
      {
         printf("SORT SPEED TEST ROUND " UINT32_FORMAT_SPEC"/" UINT32_FORMAT_SPEC":\n", t+1, NUM_RUNS);

         srand(0); for (uint32 i=0; i<NUM_ITEMS; i++) q[i] = rand();  // we want this to be repeatable, hence srand(0)
         
         uint64 startTime = GetRunTime64();
         q.Sort();
         uint64 elapsed = (GetRunTime64()-startTime);

         double itemsPerSecond = ((double)NUM_ITEMS*((double)MICROS_PER_SECOND))/(elapsed);
         printf("   It took " UINT64_FORMAT_SPEC" microseconds to sort " UINT32_FORMAT_SPEC" items, so we sorted %f items per second\n", elapsed, NUM_ITEMS, itemsPerSecond);
         tally += itemsPerSecond;
      }
      printf("GRAND AVERAGE ITEMS PER SECOND WAS %f items per second\n", tally/NUM_RUNS);
   }

   PrintAndClearStringCopyCounts("Before String Sort Tests");
   {
      const uint32 NUM_ITEMS = 1000000;
      const uint32 NUM_RUNS  = 3;
      Queue<String> q; (void) q.EnsureSize(NUM_ITEMS, true);
      double tally = 0.0;
      for (uint32 t=0; t<NUM_RUNS; t++)
      {
         printf("STRING SORT SPEED TEST ROUND " UINT32_FORMAT_SPEC"/" UINT32_FORMAT_SPEC":\n", t+1, NUM_RUNS);

         srand(0); for (uint32 i=0; i<NUM_ITEMS; i++) q[i] = String("FooBarBaz-%1").Arg(rand()).Pad(500);  // we want this to be repeatable, hence srand(0)
         
         uint64 startTime = GetRunTime64();
         q.Sort();
         uint64 elapsed = (GetRunTime64()-startTime);

         double itemsPerSecond = ((double)NUM_ITEMS*((double)MICROS_PER_SECOND))/(elapsed);
         printf("   It took " UINT64_FORMAT_SPEC" microseconds to sort " UINT32_FORMAT_SPEC" items, so we sorted %f items per second\n", elapsed, NUM_ITEMS, itemsPerSecond);
         tally += itemsPerSecond;
      }
      printf("STRING GRAND AVERAGE ITEMS PER SECOND WAS %f items per second\n", tally/NUM_RUNS);
   }
   PrintAndClearStringCopyCounts("After String Sort Tests");

   printf("REVERSE TEST\n");
   {
      q.Clear();
      for (int i=0; i<testSize; i++) TEST(q.AddTail(i));
      q.ReverseItemOrdering();
      for (int j=0; j<testSize; j++) printf("After reverse, %i->%i\n", j, q[j]);
   }

   printf("CONCAT TEST 1\n");
   {
      q.Clear();
      Queue<int> q2;
      for (int i=0; i<testSize; i++) 
      {
         TEST(q.AddTail(i));
         TEST(q2.AddTail(i+100));
      }
      q.AddTailMulti(q2);
      for (uint32 j=0; j<q.GetNumItems(); j++) printf("After concat, " UINT32_FORMAT_SPEC"->%i\n", j, q[j]);
   }

   printf("CONCAT TEST 2\n");
   {
      q.Clear();
      Queue<int> q2;
      for (int i=0; i<testSize; i++) 
      {
         TEST(q.AddTail(i));
         TEST(q2.AddTail(i+100));
      }
      q.AddHeadMulti(q2);
      for (uint32 j=0; j<q.GetNumItems(); j++) printf("After concat, " UINT32_FORMAT_SPEC"->%i\n", j, q[j]);
   }
   {
      printf("GetArrayPointer() test\n");
      uint32 len = 0;
      int * a;
      for (uint32 i=0; (a = q.GetArrayPointer(i, len)) != NULL; i++)
      {
         printf("SubArray " UINT32_FORMAT_SPEC": " UINT32_FORMAT_SPEC" items: ", i, len);
         for (uint32 j=0; j<len; j++) printf("%i, ", a[j]);
         printf("\n");
      }
   }

   printf("\nStress-testing Queue::Normalize()... this may take a minute\n");
   for (uint32 i=0; i<20000; i++)
   {
      Queue<int> q;
      int counter = 0;
      for (uint32 j=0; j<i; j++)
      {
         switch(rand()%6)
         {
            case 0:  case 1: q.AddTail(counter++); break;
            case 2:  case 3: q.AddHead(counter++); break;
            case 4:          q.RemoveHead();       break;
            case 5:          q.RemoveTail();       break;
         }
      }

      int * compareArray = new int[q.GetNumItems()];
      for (uint32 j=0; j<q.GetNumItems(); j++) compareArray[j] = q[j];
      q.Normalize();

      const int * a = q.HeadPointer();
      if (memcmp(compareArray, a, q.GetNumItems()*sizeof(int)))
      {
         printf("ERROR IN NORMALIZE!\n");
         for (uint32 i=0; i<q.GetNumItems(); i++) printf("   Expected %i, got %i (qi=%i at " UINT32_FORMAT_SPEC"/" UINT32_FORMAT_SPEC")\n", compareArray[i], a[i], q[i], i, q.GetNumItems());
         MCRASH("ERROR IN NORMALIZE!");
      }

      delete [] compareArray;
   }
   printf("Queue test complete.\n");

   return 0;
}
Beispiel #8
0
// This program is equivalent to the portableplaintext client, except
// that we communicate with a child process instead of a socket.
int main(int argc, char ** argv)
{
   CompleteSetupSystem css;

   if (argc < 3) PrintUsageAndExit();

   const uint32 numProcesses = atol(argv[1]);
   if (numProcesses == 0) PrintUsageAndExit();

   const char * cmd = argv[2];

   Hashtable<String,String> testEnvVars;
   (void) testEnvVars.Put("Peanut Butter", "Jelly");
   (void) testEnvVars.Put("Jelly", "Peanut Butter");
   (void) testEnvVars.Put("Oranges", "Grapes");

   Queue<DataIORef> refs;
   for (uint32 i=0; i<numProcesses; i++)
   {
      ChildProcessDataIO * dio = new ChildProcessDataIO(false);
      refs.AddTail(DataIORef(dio));
      printf("About To Launch child process #" UINT32_FORMAT_SPEC ":  [%s]\n", i+1, cmd); fflush(stdout);
      ConstSocketRef s = (dio->LaunchChildProcess(argc-2, ((const char **) argv)+2, ChildProcessLaunchFlags(MUSCLE_DEFAULT_CHILD_PROCESS_LAUNCH_FLAGS), NULL, &testEnvVars) == B_NO_ERROR) ? dio->GetReadSelectSocket() : ConstSocketRef();
      printf("Finished Launching child process #" UINT32_FORMAT_SPEC ":  [%s]\n", i+1, cmd); fflush(stdout);
      if (s() == NULL)
      {
         LogTime(MUSCLE_LOG_CRITICALERROR, "Error launching child process #" UINT32_FORMAT_SPEC " [%s]!\n", i+1, cmd);
         return 10;
      }
   }

   StdinDataIO stdinIO(false);
   PlainTextMessageIOGateway stdinGateway;
   QueueGatewayMessageReceiver stdinInputQueue;
   stdinGateway.SetDataIO(DataIORef(&stdinIO, false)); 

   SocketMultiplexer multiplexer;

   for (uint32 i=0; i<refs.GetNumItems(); i++)
   {
      printf("------------ CHILD PROCESS #" UINT32_FORMAT_SPEC " ------------------\n", i+1);
      PlainTextMessageIOGateway ioGateway;
      ioGateway.SetDataIO(refs[i]);
      ConstSocketRef readSock = refs[i]()->GetReadSelectSocket();
      QueueGatewayMessageReceiver ioInputQueue;
      while(1)
      {
         int readFD = readSock.GetFileDescriptor();
         multiplexer.RegisterSocketForReadReady(readFD);

         const int writeFD = ioGateway.HasBytesToOutput() ? refs[i]()->GetWriteSelectSocket().GetFileDescriptor() : -1;
         if (writeFD >= 0) multiplexer.RegisterSocketForWriteReady(writeFD);

         const int stdinFD = stdinIO.GetReadSelectSocket().GetFileDescriptor();
         multiplexer.RegisterSocketForReadReady(stdinFD);

         if (multiplexer.WaitForEvents() < 0) printf("testchildprocess: WaitForEvents() failed!\n");

         // First, deliver any lines of text from stdin to the child process
         if ((multiplexer.IsSocketReadyForRead(stdinFD))&&(stdinGateway.DoInput(ioGateway) < 0))
         {
            printf("Error reading from stdin, aborting!\n");
            break;
         }

         const bool reading    = multiplexer.IsSocketReadyForRead(readFD);
         const bool writing    = ((writeFD >= 0)&&(multiplexer.IsSocketReadyForWrite(writeFD)));
         const bool writeError = ((writing)&&(ioGateway.DoOutput() < 0));
         const bool readError  = ((reading)&&(ioGateway.DoInput(ioInputQueue) < 0));
         if ((readError)||(writeError))
         {
            printf("Connection closed, exiting.\n");
            break;
         }

         MessageRef incoming;
         while(ioInputQueue.RemoveHead(incoming) == B_NO_ERROR)
         {
            printf("Heard message from server:-----------------------------------\n");
            const char * inStr;
            for (int i=0; (incoming()->FindString(PR_NAME_TEXT_LINE, i, &inStr) == B_NO_ERROR); i++) printf("Line %i: [%s]\n", i, inStr);
           
            printf("-------------------------------------------------------------\n");
         }

         if ((reading == false)&&(writing == false)) break;

         multiplexer.RegisterSocketForReadReady(readFD);
         if (ioGateway.HasBytesToOutput()) multiplexer.RegisterSocketForWriteReady(writeFD);
      }

      if (ioGateway.HasBytesToOutput())
      {
         printf("Waiting for all pending messages to be sent...\n");
         while((ioGateway.HasBytesToOutput())&&(ioGateway.DoOutput() >= 0)) {printf ("."); fflush(stdout);}
      }
   }
   printf("\n\nBye!\n");
   return 0;
}
void HandleStandardDaemonArgs(const Message & args)
{
   TCHECKPOINT;

#ifndef WIN32
   if (args.HasName("disablestderr"))
   {
      LogTime(MUSCLE_LOG_INFO, "Suppressing all further output to stderr!\n");
      close(STDERR_FILENO);
   }
   if (args.HasName("disablestdout"))
   {
      LogTime(MUSCLE_LOG_INFO, "Suppressing all further output to stdout!\n");
      close(STDOUT_FILENO);
   }
#endif

   // Do this first, so that the stuff below will affect the right process.
   const char * n;
   if (args.FindString("daemon", &n) == B_NO_ERROR)
   {
      LogTime(MUSCLE_LOG_INFO, "Spawning off a daemon-child...\n");
      if (BecomeDaemonProcess(NULL, n[0] ? n : "/dev/null") != B_NO_ERROR)
      {
         LogTime(MUSCLE_LOG_CRITICALERROR, "Could not spawn daemon-child process!\n");
         ExitWithoutCleanup(10);
      }
   }

#ifdef WIN32
   const String * consoleStr = args.GetStringPointer("console");
   if (consoleStr) Win32AllocateStdioConsole(consoleStr->Cstr());
#endif

#ifdef MUSCLE_ENABLE_DEADLOCK_FINDER
   {
      const char * df = args.GetCstr("deadlockfinder");
      if (df) _enableDeadlockFinderPrints = ParseBool(df, true);
   }
#endif

   const char * value;
   if (args.FindString("displaylevel", &value) == B_NO_ERROR)
   {
      int ll = ParseLogLevelKeyword(value);
      if (ll >= 0) SetConsoleLogLevel(ll);
              else LogTime(MUSCLE_LOG_INFO, "Error, unknown display log level type [%s]\n", value);
   }

   if ((args.FindString("oldlogfilespattern", &value) == B_NO_ERROR)&&(*value != '\0')) SetOldLogFilesPattern(value);

   if ((args.FindString("maxlogfiles", &value) == B_NO_ERROR)||(args.FindString("maxnumlogfiles", &value) == B_NO_ERROR))
   {
      const uint32 maxNumFiles = (uint32) atol(value);
      if (maxNumFiles > 0) SetMaxNumLogFiles(maxNumFiles);
                      else LogTime(MUSCLE_LOG_ERROR, "Please specify a maxnumlogfiles value that is greater than zero.\n");
   }

   if (args.FindString("logfile", &value) == B_NO_ERROR)
   {
      SetFileLogName(value);
      if (GetFileLogLevel() == MUSCLE_LOG_NONE) SetFileLogLevel(MUSCLE_LOG_INFO); // no sense specifying a name and then not logging anything!
   }

   if (args.FindString("filelevel", &value) == B_NO_ERROR)
   {
      const int ll = ParseLogLevelKeyword(value);
      if (ll >= 0) SetFileLogLevel(ll);
              else LogTime(MUSCLE_LOG_INFO, "Error, unknown file log level type [%s]\n", value);
   }

   if (args.FindString("maxlogfilesize", &value) == B_NO_ERROR)
   {
      const uint32 maxSizeKB = (uint32) atol(value);
      if (maxSizeKB > 0) SetFileLogMaximumSize(maxSizeKB*1024);
                    else LogTime(MUSCLE_LOG_ERROR, "Please specify a maxlogfilesize in kilobytes, that is greater than zero.\n");
   }

   if ((args.HasName("compresslogfile"))||(args.HasName("compresslogfiles"))) SetFileLogCompressionEnabled(true);

   if (args.FindString("localhost", &value) == B_NO_ERROR)
   {
      const IPAddress ip = Inet_AtoN(value);
      if (ip != invalidIP)
      {
         char ipbuf[64]; Inet_NtoA(ip, ipbuf);
         LogTime(MUSCLE_LOG_INFO, "IP address [%s] will be used as the localhost address.\n", ipbuf);
         SetLocalHostIPOverride(ip);
      }
      else LogTime(MUSCLE_LOG_ERROR, "Error parsing localhost IP address [%s]!\n", value);
   }

   if (args.FindString("dnscache", &value) == B_NO_ERROR)
   {
      const uint64 micros = ParseHumanReadableTimeIntervalString(value);
      if (micros > 0)
      {
         uint32 maxCacheSize = 1024;
         if (args.FindString("dnscachesize", &value) == B_NO_ERROR) maxCacheSize = (uint32) atol(value);
         LogTime(MUSCLE_LOG_INFO, "Setting DNS cache parameters to " UINT32_FORMAT_SPEC " entries, expiration period is %s\n", maxCacheSize, GetHumanReadableTimeIntervalString(micros)());
         SetHostNameCacheSettings(maxCacheSize, micros);
      }
      else LogTime(MUSCLE_LOG_ERROR, "Unable to parse time interval string [%s] for dnscache argument!\n", value);
   }

   if ((args.HasName("debugcrashes"))||(args.HasName("debugcrash")))
   {
#if defined(__linux__) || defined(__APPLE__)
      LogTime(MUSCLE_LOG_INFO, "Enabling stack-trace printing when a crash occurs.\n");
      signal(SIGSEGV, CrashSignalHandler);
      signal(SIGBUS,  CrashSignalHandler);
      signal(SIGILL,  CrashSignalHandler);
      signal(SIGABRT, CrashSignalHandler);
      signal(SIGFPE,  CrashSignalHandler);
#elif MUSCLE_USE_MSVC_STACKWALKER
# ifndef MUSCLE_INLINE_LOGGING
      LogTime(MUSCLE_LOG_INFO, "Enabling stack-trace printing when a crash occurs.\n");
      SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) Win32FaultHandler);
# endif
#else
      LogTime(MUSCLE_LOG_ERROR, "Can't enable stack-trace printing when a crash occurs, that feature isn't supported on this platform!\n");
#endif
   }

#if defined(__linux__) || defined(__APPLE__)
   {
      const char * niceStr = NULL; (void) args.FindString("nice", &niceStr);
      const char * meanStr = NULL; (void) args.FindString("mean", &meanStr);

      const int32 niceLevel = niceStr ? ((strlen(niceStr) > 0) ? atoi(niceStr) : 5) : 0;
      const int32 meanLevel = meanStr ? ((strlen(meanStr) > 0) ? atoi(meanStr) : 5) : 0;
      const int32 effectiveLevel = niceLevel-meanLevel;

      if (effectiveLevel)
      {
         errno = 0;  // the only reliable way to check for an error here :^P
         const int ret = nice(effectiveLevel);  // I'm only looking at the return value to shut gcc 4.4.3 up
         if (errno != 0) LogTime(MUSCLE_LOG_WARNING, "Could not change process execution priority to " INT32_FORMAT_SPEC " (ret=%i).\n", effectiveLevel, ret);
                    else LogTime(MUSCLE_LOG_INFO, "Process is now %s (niceLevel=%i)\n", (effectiveLevel<0)?"mean":"nice", effectiveLevel);
      }
   }
#endif

#ifdef __linux__
   const char * priStr;
        if (args.FindString("realtime",      &priStr) == B_NO_ERROR) SetRealTimePriority(priStr, false);
   else if (args.FindString("realtime_rr",   &priStr) == B_NO_ERROR) SetRealTimePriority(priStr, false);
   else if (args.FindString("realtime_fifo", &priStr) == B_NO_ERROR) SetRealTimePriority(priStr, true);
#endif

#ifdef MUSCLE_CATCH_SIGNALS_BY_DEFAULT
# ifdef MUSCLE_AVOID_SIGNAL_HANDLING
#  error "MUSCLE_CATCH_SIGNALS_BY_DEFAULT and MUSCLE_AVOID_SIGNAL_HANDLING are mutually exclusive compiler flags... you can not specify both!"
# endif
   if (args.HasName("dontcatchsignals"))
   {
      _mainReflectServerCatchSignals = false;
      LogTime(MUSCLE_LOG_DEBUG, "Controlled shutdowns (via Control-C) disabled in the main thread.\n");
   }
#else
   if (args.HasName("catchsignals"))
   {
# ifdef MUSCLE_AVOID_SIGNAL_HANDLING
      LogTime(MUSCLE_LOG_ERROR, "Can not enable controlled shutdowns, MUSCLE_AVOID_SIGNAL_HANDLING was specified during compilation!\n");
# else
      _mainReflectServerCatchSignals = true;
      LogTime(MUSCLE_LOG_DEBUG, "Controlled shutdowns (via Control-C) enabled in the main thread.\n");
# endif
   }
#endif

   if (args.HasName("printnetworkinterfaces"))
   {
      Queue<NetworkInterfaceInfo> infos;
      if (GetNetworkInterfaceInfos(infos) == B_NO_ERROR)
      {
         printf("--- Network interfaces on this machine are as follows: ---\n");
         for (uint32 i=0; i<infos.GetNumItems(); i++) printf("  %s\n", infos[i].ToString()());
         printf("--- (end of list) ---\n");
      }
   }
}
Beispiel #10
0
// This program acts as a proxy to forward serial data to a TCP stream (and back)
int main(int argc, char ** argv) 
{
   CompleteSetupSystem css;

   Message args; (void) ParseArgs(argc, argv, args);
   (void) HandleStandardDaemonArgs(args);

   if (args.HasName("help"))
   {
      LogUsage();
      return 0;
   }

   uint16 port = 0;
   {
      const String * ps = args.GetStringPointer("port");
      if (ps) port = atoi(ps->Cstr());
   }
   if (port == 0) port = DEFAULT_PORT;
   
   String arg;
   if (args.FindString("serial", arg) == B_NO_ERROR)
   {
      const char * colon = strchr(arg(), ':');
      uint32 baudRate = colon ? atoi(colon+1) : 0; if (baudRate == 0) baudRate = 38400;
      String devName = arg.Substring(0, ":");
      Queue<String> devs;
      if (RS232DataIO::GetAvailableSerialPortNames(devs) == B_NO_ERROR)
      {
         String serName;
         for (int32 i=devs.GetNumItems()-1; i>=0; i--)
         {
            if (devs[i] == devName) 
            {
               serName = devs[i];
               break;
            }
         }
         if (serName.HasChars())
         {
            RS232DataIO serialIO(devName(), baudRate, false);
            if (serialIO.IsPortAvailable())
            {
               LogTime(MUSCLE_LOG_INFO, "Using serial port %s (baud rate " UINT32_FORMAT_SPEC ")\n", serName(), baudRate);

               ConstSocketRef serverSock = CreateAcceptingSocket(port, 1);
               if (serverSock())
               {
                  // Now we just wait here until a TCP connection comes along on our port...
                  bool keepGoing = true;
                  while(keepGoing)
                  {
                     LogTime(MUSCLE_LOG_INFO, "Awaiting incoming TCP connection on port %u...\n", port);
                     ConstSocketRef tcpSock = Accept(serverSock);
                     if (tcpSock())
                     {
                        LogTime(MUSCLE_LOG_INFO, "Beginning serial proxy session!\n");
                        TCPSocketDataIO networkIO(tcpSock, false);
                        keepGoing = (DoSession(networkIO, serialIO) == B_NO_ERROR);
                        LogTime(MUSCLE_LOG_INFO, "Serial proxy session ended%s!\n", keepGoing?", awaiting new connection":", aborting!");
                     }
                  }
               }
               else LogTime(MUSCLE_LOG_CRITICALERROR, "Unable to listen on TCP port %u\n", port);
            }
            else LogTime(MUSCLE_LOG_CRITICALERROR, "Unable to open serial device %s (baud rate " UINT32_FORMAT_SPEC ").\n", serName(), baudRate);
         }
         else 
         {
            LogTime(MUSCLE_LOG_CRITICALERROR, "Serial device %s not found.\n", devName());
            LogTime(MUSCLE_LOG_CRITICALERROR, "Available serial devices are:\n");
            for (uint32 i=0; i<devs.GetNumItems(); i++) LogTime(MUSCLE_LOG_CRITICALERROR, "   %s\n", devs[i]());
         }
      }
      else LogTime(MUSCLE_LOG_CRITICALERROR, "Could not get list of serial device names!\n");
   }
   else LogUsage();

   LogTime(MUSCLE_LOG_INFO, "serialproxy exiting!\n");
   return 0;
}