3 #if defined(_WIN32) && !defined(__CYGWIN__)
10 #include <sys/types.h>
13 extern char **environ;
17 #include <qdatetime.h>
19 #if defined(_MSC_VER) || defined(__BORLANDC__)
21 #define pclose _pclose
28 //#include "doxygen.h"
30 static double g_sysElapsedTime;
33 int portable_system(const char *command,const char *args,bool commandHasConsole)
36 if (command==0) return 1;
38 QCString fullCmd=command;
39 fullCmd=fullCmd.stripWhiteSpace();
40 if (fullCmd.at(0)!='"' && fullCmd.find(' ')!=-1)
42 // add quotes around command as it contains spaces and is not quoted already
43 fullCmd="\""+fullCmd+"\"";
48 Debug::print(Debug::ExtCmd,0,"Executing external command `%s`\n",fullCmd.data());
51 #if !defined(_WIN32) || defined(__CYGWIN__)
52 (void)commandHasConsole;
53 /*! taken from the system() manpage on my Linux box */
56 #ifdef _OS_SOLARIS // for Solaris we use vfork since it is more memory efficient
58 // on Solaris fork() duplicates the memory usage
59 // so we use vfork instead
68 execl("/bin/sh","sh","-c",fullCmd.data(),(char*)0);
73 while (waitpid(pid,&status,0 )<0)
84 #else // Other Unices just use fork
87 if (pid==-1) return -1;
93 argv[2] = fullCmd.data();
95 execve("/bin/sh",(char * const *)argv,environ);
100 if (waitpid(pid,&status,0)==-1)
102 if (errno!=EINTR) return -1;
106 if (WIFEXITED(status))
108 return WEXITSTATUS(status);
116 #endif // !_OS_SOLARIS
118 #else // Win32 specific
119 if (commandHasConsole)
121 return system(fullCmd);
125 // Because ShellExecuteEx can delegate execution to Shell extensions
126 // (data sources, context menu handlers, verb implementations) that
127 // are activated using Component Object Model (COM), COM should be
128 // initialized before ShellExecuteEx is called. Some Shell extensions
129 // require the COM single-threaded apartment (STA) type.
130 // For that case COM is initialized as follows
131 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
133 // gswin32 is a GUI api which will pop up a window and run
134 // asynchronously. To prevent both, we use ShellExecuteEx and
135 // WaitForSingleObject (thanks to Robert Golias for the code)
137 SHELLEXECUTEINFO sInfo = {
138 sizeof(SHELLEXECUTEINFO), /* structure size */
139 SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI, /* tell us the process
140 * handle so we can wait till it's done |
141 * do not display msg box if error
143 NULL, /* window handle */
144 NULL, /* action to perform: open */
145 command, /* file to execute */
146 args, /* argument list */
147 NULL, /* use current working dir */
148 SW_HIDE, /* minimize on start-up */
149 0, /* application instance handle */
150 NULL, /* ignored: id list */
151 NULL, /* ignored: class name */
152 NULL, /* ignored: key class */
153 0, /* ignored: hot key */
154 NULL, /* ignored: icon */
155 NULL /* resulting application handle */
157 if (!ShellExecuteEx(&sInfo))
161 else if (sInfo.hProcess) /* executable was launched, wait for it to finish */
163 WaitForSingleObject(sInfo.hProcess,INFINITE);
164 CloseHandle(sInfo.hProcess);
175 #if !defined(_WIN32) || defined(__CYGWIN__)
176 pid = (uint)getpid();
178 pid = (uint)GetCurrentProcessId();
183 static char **last_environ;
185 void portable_setenv(const char *name,const char *value)
187 if (value==0) value="";
188 #if defined(_WIN32) && !defined(__CYGWIN__)
189 SetEnvironmentVariable(name,value);
191 register char **ep = 0;
192 register size_t size;
193 const size_t namelen=strlen(name);
194 const size_t vallen=strlen(value) + 1;
199 for (ep = environ; *ep; ++ep)
201 if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
208 if (environ==0 || *ep==0) /* add new string */
211 if (environ == last_environ && environ!=0)
213 // We allocated this space; we can extend it.
214 new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *));
218 new_environ = (char **) malloc ((size + 2) * sizeof (char *));
221 if (new_environ==0) // no more memory
226 new_environ[size] = (char *)malloc (namelen + 1 + vallen);
227 if (new_environ[size]==0)
233 if (environ != last_environ)
235 memcpy ((char *) new_environ, environ, size * sizeof (char *));
238 memcpy(new_environ[size], name, namelen);
239 new_environ[size][namelen] = '=';
240 memcpy(&new_environ[size][namelen + 1], value, vallen);
241 new_environ[size + 1] = 0;
242 last_environ = environ = new_environ;
244 else /* replace existing string */
246 size_t len = strlen (*ep);
247 if (len + 1 < namelen + 1 + vallen)
249 /* The existing string is too short; malloc a new one. */
250 char *newString = (char *)malloc(namelen + 1 + vallen);
257 memcpy(*ep, name, namelen);
258 (*ep)[namelen] = '=';
259 memcpy(&(*ep)[namelen + 1], value, vallen);
265 void portable_unsetenv(const char *variable)
267 #if defined(_WIN32) && !defined(__CYGWIN__)
268 SetEnvironmentVariable(variable,0);
270 /* Some systems don't have unsetenv(), so we do it ourselves */
274 if (variable == NULL || *variable == '\0' || strchr (variable, '=') != NULL)
276 return; // not properly formatted
279 len = strlen(variable);
284 if (!strncmp(*ep, variable, len) && (*ep)[len]=='=')
286 /* Found it. Remove this pointer by moving later ones back. */
288 do dp[0] = dp[1]; while (*dp++);
289 /* Continue the loop in case NAME appears again. */
299 const char *portable_getenv(const char *variable)
301 return getenv(variable);
304 portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
306 #if defined(_WIN32) && !defined(__CYGWIN__)
307 return _fseeki64(f,offset,whence);
309 return fseeko(f,offset,whence);
313 portable_off_t portable_ftell(FILE *f)
315 #if defined(_WIN32) && !defined(__CYGWIN__)
322 FILE *portable_fopen(const char *fileName,const char *mode)
324 #if defined(_WIN32) && !defined(__CYGWIN__)
325 QString fn(fileName);
327 return _wfopen((wchar_t*)fn.ucs2(),(wchar_t*)m.ucs2());
329 return fopen(fileName,mode);
333 char portable_pathSeparator()
335 #if defined(_WIN32) && !defined(__CYGWIN__)
342 char portable_pathListSeparator()
344 #if defined(_WIN32) && !defined(__CYGWIN__)
351 const char *portable_ghostScriptCommand()
353 #if defined(_WIN32) && !defined(__CYGWIN__)
354 return "gswin32c.exe";
360 const char *portable_commandExtension()
362 #if defined(_WIN32) && !defined(__CYGWIN__)
369 bool portable_fileSystemIsCaseSensitive()
371 #if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__)
378 FILE * portable_popen(const char *name,const char *type)
380 return popen(name,type);
383 int portable_pclose(FILE *stream)
385 return pclose(stream);
388 void portable_sysTimerStart()
393 void portable_sysTimerStop()
395 g_sysElapsedTime+=((double)g_time.elapsed())/1000.0;
398 double portable_getSysElapsedTime()
400 return g_sysElapsedTime;
403 void portable_sleep(int ms)
405 #if defined(_WIN32) && !defined(__CYGWIN__)