X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/220a0f42d4a71fcd1576b750a707d37d33225be4..41895a05eae22da85e8c659f9492d2312a63af13:/src/gtk/utilsgtk.cpp diff --git a/src/gtk/utilsgtk.cpp b/src/gtk/utilsgtk.cpp index 9f16f5c0d1..a55812182a 100644 --- a/src/gtk/utilsgtk.cpp +++ b/src/gtk/utilsgtk.cpp @@ -43,14 +43,26 @@ #include #endif -#ifdef __SOLARIS__ -// somehow missing from sys/wait.h but in the system's docs -extern "C" -{ - pid_t wait4(pid_t pid, int *statusp, int options, struct rusage - *rusage); -} -#endif +// many versions of Unices have this function, but it is not defined in system +// headers - please add your system here if it is the case for your OS. +// SunOS (and Solaris) and DG-UX are like this. +#if defined(__SOLARIS__) || defined(__osf__) + extern "C" + { + pid_t wait4(pid_t pid, int *statusp, int options, + struct rusage *rusage); + } + + #define wxWait4(pid, stat, flags, rusage) wait4(pid, stat, flags, rusage) +#elif defined(__sgi) || defined(__HPUX__) + // no wait4() at all on these systems + // TODO verify whether wait3() really works in this situation + #define wxWait4(pid, stat, flags, rusage) wait3(stat, flags, rusage) +#else + // other Unices: assume have wait4(), although it's not standard (but + // Linux and FreeBSD do have it) + #define wxWait4(pid, stat, flags, rusage) wait4(pid, stat, flags, rusage) +#endif // wait4() //------------------------------------------------------------------------ // misc. @@ -252,10 +264,14 @@ bool wxDirExists( const wxString& dir ) // subprocess routines //------------------------------------------------------------------------ +// if pid > 0, the execution is async and the data is freed in +// GTK_EndProcessDetector, if pid < 0, the execution is synchronous and the +// caller (wxExecute) frees the data struct wxEndProcessData { gint pid, tag; wxProcess *process; + int exitcode; }; static void GTK_EndProcessDetector(gpointer data, gint source, @@ -266,18 +282,8 @@ static void GTK_EndProcessDetector(gpointer data, gint source, pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid); - /* wait4 is not part of any standard, use at own risk - * not sure what wait4 does, but wait3 seems to be closest, whats a digit ;-) - * --- offer@sgi.com */ - // VZ: wait4() will be woken up by a signal, not wait3 - so it's quite - // different (also, wait3() waits for any child, wait4() only for this - // one) - int status = -1; -#if !defined(__sgi) - wait4(proc_data->pid, &status, 0, (rusage *) NULL); -#else - wait3(&status, 0, (rusage *) NULL); -#endif + int status = 0; + wxWait4(pid, &status, 0, (rusage *) NULL); close(source); gdk_input_remove(proc_data->tag); @@ -286,9 +292,16 @@ static void GTK_EndProcessDetector(gpointer data, gint source, proc_data->process->OnTerminate(proc_data->pid, status); if (proc_data->pid > 0) + { delete proc_data; + } else + { + // wxExecute() will know about it + proc_data->exitcode = status; + proc_data->pid = 0; + } } long wxExecute( char **argv, bool sync, wxProcess *process ) @@ -356,25 +369,34 @@ long wxExecute( char **argv, bool sync, wxProcess *process ) close(end_proc_detect[1]); // close writing side data->tag = gdk_input_add(end_proc_detect[0], GDK_INPUT_READ, GTK_EndProcessDetector, (gpointer)data); - data->pid = pid; - if (!sync) + if ( sync ) { - data->process = process; - } - else - { - data->process = process; - data->pid = -(data->pid); + wxASSERT_MSG( !process, "wxProcess param ignored for sync exec" ); + data->process = NULL; + + // sync execution: indicate it by negating the pid + data->pid = -pid; + // it will be set to 0 from GTK_EndProcessDetector while (data->pid != 0) wxYield(); + int exitcode = data->exitcode; + delete data; + + return exitcode; } + else + { + // async execution, nothing special to do - caller will be + // notified about the process terminationif process != NULL, data + // will be deleted in GTK_EndProcessDetector + data->process = process; + data->pid = pid; - // @@@ our return value indicates success even if execvp() in the child - // failed! - return pid; + return pid; + } } }