summaryrefslogtreecommitdiff
path: root/src/portable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/portable.cpp')
-rw-r--r--src/portable.cpp401
1 files changed, 401 insertions, 0 deletions
diff --git a/src/portable.cpp b/src/portable.cpp
new file mode 100644
index 0000000..7a78131
--- /dev/null
+++ b/src/portable.cpp
@@ -0,0 +1,401 @@
+#include <stdlib.h>
+#include <ctype.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef UNICODE
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+extern char **environ;
+#endif
+
+#include <qglobal.h>
+#include <qdatetime.h>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define popen _popen
+#define pclose _pclose
+#endif
+
+#include "portable.h"
+#ifndef NODEBUG
+#include "debug.h"
+#endif
+//#include "doxygen.h"
+
+static double g_sysElapsedTime;
+static QTime g_time;
+
+int portable_system(const char *command,const char *args,bool commandHasConsole)
+{
+
+ if (command==0) return 1;
+
+ QCString fullCmd=command;
+ fullCmd=fullCmd.stripWhiteSpace();
+ if (fullCmd.at(0)!='"' && fullCmd.find(' ')!=-1)
+ {
+ // add quotes around command as it contains spaces and is not quoted already
+ fullCmd="\""+fullCmd+"\"";
+ }
+ fullCmd += " ";
+ fullCmd += args;
+#ifndef NODEBUG
+ Debug::print(Debug::ExtCmd,0,"Executing external command `%s`\n",fullCmd.data());
+#endif
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ commandHasConsole=commandHasConsole;
+ /*! taken from the system() manpage on my Linux box */
+ int pid,status=0;
+
+#ifdef _OS_SOLARIS // for Solaris we use vfork since it is more memory efficient
+
+ // on Solaris fork() duplicates the memory usage
+ // so we use vfork instead
+
+ // spawn shell
+ if ((pid=vfork())<0)
+ {
+ status=-1;
+ }
+ else if (pid==0)
+ {
+ execl("/bin/sh","sh","-c",fullCmd.data(),(char*)0);
+ _exit(127);
+ }
+ else
+ {
+ while (waitpid(pid,&status,0 )<0)
+ {
+ if (errno!=EINTR)
+ {
+ status=-1;
+ break;
+ }
+ }
+ }
+ return status;
+
+#else // Other Unices just use fork
+
+ pid = fork();
+ if (pid==-1) return -1;
+ if (pid==0)
+ {
+ const char * argv[4];
+ argv[0] = "sh";
+ argv[1] = "-c";
+ argv[2] = fullCmd.data();
+ argv[3] = 0;
+ execve("/bin/sh",(char * const *)argv,environ);
+ exit(127);
+ }
+ for (;;)
+ {
+ if (waitpid(pid,&status,0)==-1)
+ {
+ if (errno!=EINTR) return -1;
+ }
+ else
+ {
+ if (WIFEXITED(status))
+ {
+ return WEXITSTATUS(status);
+ }
+ else
+ {
+ return status;
+ }
+ }
+ }
+#endif // !_OS_SOLARIS
+
+#else // Win32 specific
+ if (commandHasConsole)
+ {
+ return system(fullCmd);
+ }
+ else
+ {
+ // gswin32 is a GUI api which will pop up a window and run
+ // asynchronously. To prevent both, we use ShellExecuteEx and
+ // WaitForSingleObject (thanks to Robert Golias for the code)
+
+ SHELLEXECUTEINFO sInfo = {
+ sizeof(SHELLEXECUTEINFO), /* structure size */
+ SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI, /* tell us the process
+ * handle so we can wait till it's done |
+ * do not display msg box if error
+ */
+ NULL, /* window handle */
+ NULL, /* action to perform: open */
+ command, /* file to execute */
+ args, /* argument list */
+ NULL, /* use current working dir */
+ SW_HIDE, /* minimize on start-up */
+ 0, /* application instance handle */
+ NULL, /* ignored: id list */
+ NULL, /* ignored: class name */
+ NULL, /* ignored: key class */
+ 0, /* ignored: hot key */
+ NULL, /* ignored: icon */
+ NULL /* resulting application handle */
+ };
+ if (!ShellExecuteEx(&sInfo))
+ {
+ return -1;
+ }
+ else if (sInfo.hProcess) /* executable was launched, wait for it to finish */
+ {
+ WaitForSingleObject(sInfo.hProcess,INFINITE);
+ CloseHandle(sInfo.hProcess);
+ }
+ }
+ return 0;
+#endif
+
+}
+
+uint portable_pid()
+{
+ uint pid;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ pid = (uint)getpid();
+#else
+ pid = (uint)GetCurrentProcessId();
+#endif
+ return pid;
+}
+
+static char **last_environ;
+
+void portable_setenv(const char *name,const char *value)
+{
+ if (value==0) value="";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ SetEnvironmentVariable(name,value);
+#else
+ register char **ep = 0;
+ register size_t size;
+ const size_t namelen=strlen(name);
+ const size_t vallen=strlen(value) + 1;
+
+ size = 0;
+ if (environ!=0)
+ {
+ for (ep = environ; *ep; ++ep)
+ {
+ if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+ break;
+ else
+ ++size;
+ }
+ }
+
+ if (environ==0 || *ep==0) /* add new string */
+ {
+ char **new_environ;
+ if (environ == last_environ && environ!=0)
+ {
+ // We allocated this space; we can extend it.
+ new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *));
+ }
+ else
+ {
+ new_environ = (char **) malloc ((size + 2) * sizeof (char *));
+ }
+
+ if (new_environ==0) // no more memory
+ {
+ return;
+ }
+
+ new_environ[size] = (char *)malloc (namelen + 1 + vallen);
+ if (new_environ[size]==0)
+ {
+ free (new_environ);
+ return;
+ }
+
+ if (environ != last_environ)
+ {
+ memcpy ((char *) new_environ, environ, size * sizeof (char *));
+ }
+
+ memcpy(new_environ[size], name, namelen);
+ new_environ[size][namelen] = '=';
+ memcpy(&new_environ[size][namelen + 1], value, vallen);
+ new_environ[size + 1] = 0;
+ last_environ = environ = new_environ;
+ }
+ else /* replace existing string */
+ {
+ size_t len = strlen (*ep);
+ if (len + 1 < namelen + 1 + vallen)
+ {
+ /* The existing string is too short; malloc a new one. */
+ char *newString = (char *)malloc(namelen + 1 + vallen);
+ if (newString==0)
+ {
+ return;
+ }
+ *ep = newString;
+ }
+ memcpy(*ep, name, namelen);
+ (*ep)[namelen] = '=';
+ memcpy(&(*ep)[namelen + 1], value, vallen);
+ }
+
+#endif
+}
+
+void portable_unsetenv(const char *variable)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ SetEnvironmentVariable(variable,0);
+#else
+ /* Some systems don't have unsetenv(), so we do it ourselves */
+ size_t len;
+ char **ep;
+
+ if (variable == NULL || *variable == '\0' || strchr (variable, '=') != NULL)
+ {
+ return; // not properly formatted
+ }
+
+ len = strlen(variable);
+
+ ep = environ;
+ while (*ep != NULL)
+ {
+ if (!strncmp(*ep, variable, len) && (*ep)[len]=='=')
+ {
+ /* Found it. Remove this pointer by moving later ones back. */
+ char **dp = ep;
+ do dp[0] = dp[1]; while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ }
+ else
+ {
+ ++ep;
+ }
+ }
+#endif
+}
+
+const char *portable_getenv(const char *variable)
+{
+ return getenv(variable);
+}
+
+portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return _fseeki64(f,offset,whence);
+#else
+ return fseeko(f,offset,whence);
+#endif
+}
+
+portable_off_t portable_ftell(FILE *f)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return _ftelli64(f);
+#else
+ return ftello(f);
+#endif
+}
+
+FILE *portable_fopen(const char *fileName,const char *mode)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ QString fn(fileName);
+ QString m(mode);
+ return _wfopen((wchar_t*)fn.ucs2(),(wchar_t*)m.ucs2());
+#else
+ return fopen(fileName,mode);
+#endif
+}
+
+char portable_pathSeparator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return '\\';
+#else
+ return '/';
+#endif
+}
+
+char portable_pathListSeparator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return ';';
+#else
+ return ':';
+#endif
+}
+
+const char *portable_ghostScriptCommand()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return "gswin32c.exe";
+#else
+ return "gs";
+#endif
+}
+
+const char *portable_commandExtension()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return ".exe";
+#else
+ return "";
+#endif
+}
+
+bool portable_fileSystemIsCaseSensitive()
+{
+#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__)
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+
+FILE * portable_popen(const char *name,const char *type)
+{
+ return popen(name,type);
+}
+
+int portable_pclose(FILE *stream)
+{
+ return pclose(stream);
+}
+
+void portable_sysTimerStart()
+{
+ g_time.start();
+}
+
+void portable_sysTimerStop()
+{
+ g_sysElapsedTime+=((double)g_time.elapsed())/1000.0;
+}
+
+double portable_getSysElapsedTime()
+{
+ return g_sysElapsedTime;
+}
+
+void portable_sleep(int ms)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(ms);
+#else
+ usleep(1000*ms);
+#endif
+}