Orb/Doxygen/src/portable.cpp
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 #include <stdlib.h>
       
     2 #include <ctype.h>
       
     3 #if defined(_WIN32) && !defined(__CYGWIN__)
       
     4 #undef UNICODE
       
     5 #include <windows.h>
       
     6 #else
       
     7 #include <unistd.h>
       
     8 #include <stdlib.h>
       
     9 #include <sys/types.h>
       
    10 #include <sys/wait.h>
       
    11 #include <errno.h>
       
    12 extern char **environ;
       
    13 #endif
       
    14 
       
    15 #include <qglobal.h>
       
    16 #include <qdatetime.h>
       
    17 
       
    18 #if defined(_MSC_VER) || defined(__BORLANDC__)
       
    19 #define popen _popen
       
    20 #define pclose _pclose
       
    21 #endif
       
    22 
       
    23 #include "portable.h"
       
    24 #ifndef NODEBUG
       
    25 #include "debug.h"
       
    26 #endif
       
    27 //#include "doxygen.h"
       
    28 
       
    29 static double  sysElapsedTime;
       
    30 
       
    31 int  portable_system(const char *command,const char *args,bool commandHasConsole)
       
    32 {
       
    33   QTime time;
       
    34   time.start();
       
    35 
       
    36   if (command==0) return 1;
       
    37 
       
    38   QCString fullCmd=command;
       
    39   fullCmd=fullCmd.stripWhiteSpace();
       
    40   if (fullCmd.at(0)!='"' && fullCmd.find(' ')!=-1)
       
    41   {
       
    42     // add quotes around command as it contains spaces and is not quoted already
       
    43     fullCmd="\""+fullCmd+"\"";
       
    44   }
       
    45   fullCmd += " ";
       
    46   fullCmd += args;
       
    47 #ifndef NODEBUG
       
    48   Debug::print(Debug::ExtCmd,0,"Executing external command `%s`\n",fullCmd.data());
       
    49 #endif
       
    50 
       
    51 #if !defined(_WIN32) || defined(__CYGWIN__)
       
    52   commandHasConsole=commandHasConsole;
       
    53   /*! taken from the system() manpage on my Linux box */
       
    54   int pid,status=0;
       
    55 
       
    56 #ifdef _OS_SOLARIS // for Solaris we use vfork since it is more memory efficient
       
    57 
       
    58   // on Solaris fork() duplicates the memory usage
       
    59   // so we use vfork instead
       
    60   
       
    61   // spawn shell
       
    62   if ((pid=vfork())<0)
       
    63   {
       
    64     status=-1;
       
    65   }
       
    66   else if (pid==0)
       
    67   {
       
    68      execl("/bin/sh","sh","-c",fullCmd.data(),(char*)0);
       
    69      _exit(127);
       
    70   }
       
    71   else
       
    72   {
       
    73     while (waitpid(pid,&status,0 )<0)
       
    74     {
       
    75       if (errno!=EINTR)
       
    76       {
       
    77         status=-1;
       
    78         break;
       
    79       }
       
    80     }
       
    81   }
       
    82   sysElapsedTime+=((double)time.elapsed())/1000.0;
       
    83   return status;
       
    84 
       
    85 #else  // Other Unices just use fork
       
    86 
       
    87   pid = fork();
       
    88   if (pid==-1) return -1;
       
    89   if (pid==0)
       
    90   {
       
    91     const char * argv[4];
       
    92     argv[0] = "sh";
       
    93     argv[1] = "-c";
       
    94     argv[2] = fullCmd.data();
       
    95     argv[3] = 0;
       
    96     execve("/bin/sh",(char * const *)argv,environ);
       
    97     exit(127);
       
    98   }
       
    99   for (;;)
       
   100   {
       
   101     if (waitpid(pid,&status,0)==-1)
       
   102     {
       
   103       if (errno!=EINTR) return -1;
       
   104     }
       
   105     else
       
   106     {
       
   107       sysElapsedTime+=((double)time.elapsed())/1000.0;
       
   108       if (WIFEXITED(status))
       
   109       {
       
   110         return WEXITSTATUS(status);
       
   111       }
       
   112       else
       
   113       {
       
   114         return status;
       
   115       }
       
   116     }
       
   117   }
       
   118 #endif // !_OS_SOLARIS
       
   119 
       
   120 #else // Win32 specific
       
   121   if (commandHasConsole)
       
   122   {
       
   123     return system(fullCmd);
       
   124   }
       
   125   else
       
   126   {
       
   127     // gswin32 is a GUI api which will pop up a window and run
       
   128     // asynchronously. To prevent both, we use ShellExecuteEx and
       
   129     // WaitForSingleObject (thanks to Robert Golias for the code)
       
   130 
       
   131     SHELLEXECUTEINFO sInfo = {
       
   132       sizeof(SHELLEXECUTEINFO),   /* structure size */
       
   133       SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI,  /* tell us the process
       
   134                                                        *  handle so we can wait till it's done | 
       
   135                                                        *  do not display msg box if error 
       
   136                                                        */
       
   137       NULL,                       /* window handle */
       
   138       NULL,                       /* action to perform: open */
       
   139       command,                    /* file to execute */
       
   140       args,                       /* argument list */ 
       
   141       NULL,                       /* use current working dir */
       
   142       SW_HIDE,                    /* minimize on start-up */
       
   143       0,                          /* application instance handle */
       
   144       NULL,                       /* ignored: id list */
       
   145       NULL,                       /* ignored: class name */
       
   146       NULL,                       /* ignored: key class */
       
   147       0,                          /* ignored: hot key */
       
   148       NULL,                       /* ignored: icon */
       
   149       NULL                        /* resulting application handle */
       
   150     };
       
   151     if (!ShellExecuteEx(&sInfo))
       
   152     {
       
   153       return -1;
       
   154     }
       
   155     else if (sInfo.hProcess)      /* executable was launched, wait for it to finish */
       
   156     {
       
   157       WaitForSingleObject(sInfo.hProcess,INFINITE); 
       
   158       CloseHandle(sInfo.hProcess);
       
   159     }
       
   160   }
       
   161   sysElapsedTime+=((double)time.elapsed())/1000.0;
       
   162   return 0;
       
   163 #endif
       
   164 
       
   165 }
       
   166 
       
   167 uint portable_pid()
       
   168 {
       
   169   uint pid;
       
   170 #if !defined(_WIN32) || defined(__CYGWIN__)
       
   171   pid = (uint)getpid();
       
   172 #else
       
   173   pid = (uint)GetCurrentProcessId();
       
   174 #endif
       
   175   return pid;
       
   176 }
       
   177 
       
   178 static char **last_environ;
       
   179 
       
   180 void portable_setenv(const char *name,const char *value)
       
   181 {
       
   182 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   183     SetEnvironmentVariable(name,value);
       
   184 #else
       
   185     register char **ep = 0;
       
   186     register size_t size;
       
   187     const size_t namelen=strlen(name);
       
   188     const size_t vallen=strlen(value) + 1;
       
   189 
       
   190     size = 0;
       
   191     if (environ!=0)
       
   192     {
       
   193       for (ep = environ; *ep; ++ep)
       
   194       {
       
   195         if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
       
   196           break;
       
   197         else
       
   198           ++size;
       
   199       }
       
   200     }
       
   201 
       
   202     if (environ==0 || *ep==0) /* add new string */
       
   203     {
       
   204       char **new_environ;
       
   205       if (environ == last_environ && environ!=0)
       
   206       {
       
   207         // We allocated this space; we can extend it. 
       
   208         new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *));
       
   209       }
       
   210       else
       
   211       {
       
   212         new_environ = (char **) malloc ((size + 2) * sizeof (char *));
       
   213       }
       
   214 
       
   215       if (new_environ==0) // no more memory 
       
   216       {
       
   217         return;
       
   218       }
       
   219 
       
   220       new_environ[size] = (char *)malloc (namelen + 1 + vallen);
       
   221       if (new_environ[size]==0)
       
   222       {
       
   223         free (new_environ);
       
   224         return;
       
   225       }
       
   226 
       
   227       if (environ != last_environ)
       
   228       {
       
   229         memcpy ((char *) new_environ, environ, size * sizeof (char *));
       
   230       }
       
   231 
       
   232       memcpy(new_environ[size], name, namelen);
       
   233       new_environ[size][namelen] = '=';
       
   234       memcpy(&new_environ[size][namelen + 1], value, vallen);
       
   235       new_environ[size + 1] = 0;
       
   236       last_environ = environ = new_environ;
       
   237     }
       
   238     else /* replace existing string */
       
   239     {
       
   240       size_t len = strlen (*ep);
       
   241       if (len + 1 < namelen + 1 + vallen)
       
   242       {
       
   243         /* The existing string is too short; malloc a new one.  */
       
   244         char *newString = (char *)malloc(namelen + 1 + vallen);
       
   245         if (newString==0)
       
   246         {
       
   247           return;
       
   248         }
       
   249         *ep = newString;
       
   250       }
       
   251       memcpy(*ep, name, namelen);
       
   252       (*ep)[namelen] = '=';
       
   253       memcpy(&(*ep)[namelen + 1], value, vallen);
       
   254     }
       
   255 
       
   256 #endif
       
   257 }
       
   258 
       
   259 void portable_unsetenv(const char *variable)
       
   260 {
       
   261 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   262     SetEnvironmentVariable(variable,0);
       
   263 #else
       
   264     /* Some systems don't have unsetenv(), so we do it ourselves */
       
   265     size_t len;
       
   266     char **ep;
       
   267 
       
   268     if (variable == NULL || *variable == '\0' || strchr (variable, '=') != NULL)
       
   269     {
       
   270       return; // not properly formatted
       
   271     }
       
   272 
       
   273     len = strlen(variable);
       
   274 
       
   275     ep = environ;
       
   276     while (*ep != NULL)
       
   277     {
       
   278       if (!strncmp(*ep, variable, len) && (*ep)[len]=='=')
       
   279       {
       
   280         /* Found it.  Remove this pointer by moving later ones back.  */
       
   281         char **dp = ep;
       
   282         do dp[0] = dp[1]; while (*dp++);
       
   283         /* Continue the loop in case NAME appears again.  */
       
   284       }
       
   285       else
       
   286       {
       
   287         ++ep;
       
   288       }
       
   289     }
       
   290 #endif
       
   291 }
       
   292 
       
   293 const char *portable_getenv(const char *variable)
       
   294 {
       
   295   return getenv(variable);
       
   296 }
       
   297 
       
   298 portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
       
   299 {
       
   300 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   301   return _fseeki64(f,offset,whence);
       
   302 #else
       
   303   return fseeko(f,offset,whence);
       
   304 #endif
       
   305 }
       
   306 
       
   307 portable_off_t portable_ftell(FILE *f)
       
   308 {
       
   309 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   310   return _ftelli64(f);
       
   311 #else
       
   312   return ftello(f);
       
   313 #endif
       
   314 }
       
   315 
       
   316 char  portable_pathSeparator()
       
   317 {
       
   318 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   319   return '\\';
       
   320 #else
       
   321   return '/';
       
   322 #endif
       
   323 }
       
   324 
       
   325 char  portable_pathListSeparator()
       
   326 {
       
   327 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   328   return ';';
       
   329 #else
       
   330   return ':';
       
   331 #endif
       
   332 }
       
   333 
       
   334 const char *portable_ghostScriptCommand()
       
   335 {
       
   336 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   337     return "gswin32c.exe";
       
   338 #else
       
   339     return "gs";
       
   340 #endif
       
   341 }
       
   342 
       
   343 const char *portable_commandExtension()
       
   344 {
       
   345 #if defined(_WIN32) && !defined(__CYGWIN__)
       
   346     return ".exe";
       
   347 #else
       
   348     return "";
       
   349 #endif
       
   350 }
       
   351 
       
   352 bool portable_fileSystemIsCaseSensitive()
       
   353 {
       
   354 #if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__)
       
   355   return FALSE;
       
   356 #else
       
   357   return TRUE;
       
   358 #endif
       
   359 }
       
   360 
       
   361 FILE * portable_popen(const char *name,const char *type)
       
   362 {
       
   363   return popen(name,type);
       
   364 }
       
   365 
       
   366 int portable_pclose(FILE *stream)
       
   367 {
       
   368   return pclose(stream);
       
   369 }
       
   370 
       
   371 double portable_getSysElapsedTime()
       
   372 {
       
   373   return sysElapsedTime;
       
   374 }
       
   375