#include "wx/stream.h"
#ifdef HAVE_STATFS
- #include <sys/vfs.h>
+# ifdef __BSD__
+# include <sys/param.h>
+# include <sys/mount.h>
+# else
+# include <sys/vfs.h>
+# endif
#endif // HAVE_STATFS
+#ifdef HAVE_STATVFS
+ #include <sys/statvfs.h>
+
+ #define statfs statvfs
+#endif // HAVE_STATVFS
+
#if wxUSE_GUI
#include "wx/unix/execute.h"
#endif
int err = kill((pid_t)pid, (int)sig);
if ( rc )
{
- switch ( err )
+ switch ( errno )
{
case 0:
*rc = wxKILL_OK;
#define WXEXECUTE_NARGS 127
-long wxExecute( const wxString& command, bool sync, wxProcess *process )
+long wxExecute( const wxString& command, int flags, wxProcess *process )
{
wxCHECK_MSG( !command.IsEmpty(), 0, wxT("can't exec empty command") );
argv[argc] = NULL;
// do execute the command
- long lRc = wxExecute(argv, sync, process);
+ long lRc = wxExecute(argv, flags, process);
// clean up
argc = 0;
bool wxShell(const wxString& command)
{
- return wxExecute(wxMakeShellCommand(command), TRUE /* sync */) == 0;
+ return wxExecute(wxMakeShellCommand(command), wxEXEC_SYNC) == 0;
}
bool wxShell(const wxString& command, wxArrayString& output)
void wxHandleProcessTermination(wxEndProcessData *proc_data)
{
- int pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid);
-
- // waitpid is POSIX so should be available everywhere, however on older
- // systems wait() might be used instead in a loop (until the right pid
- // terminates)
- int status = 0;
- int rc;
-
- // wait for child termination and if waitpid() was interrupted, try again
- do
+ // notify user about termination if required
+ if ( proc_data->process )
{
- rc = waitpid(pid, &status, 0);
+ proc_data->process->OnTerminate(proc_data->pid, proc_data->exitcode);
}
- while ( rc == -1 && errno == EINTR );
- if (rc == -1)
- {
- // JACS: this could happen if the process was terminated and waitpid called,
- // so commenting out for now.
- //wxLogSysError(_("Waiting for subprocess termination failed (return code = -1)"));
- }
- else if (! (WIFEXITED(status)))
+ // clean up
+ if ( proc_data->pid > 0 )
{
- wxLogSysError(_("Waiting for subprocess termination failed (WIFEXITED returned zero)"));
-
- /* AFAIK, this can only happen if something went wrong within
- wxGTK, i.e. due to a race condition or some serious bug.
- After having fixed the order of statements in
- GTK_EndProcessDetector(). (KB)
- */
+ delete proc_data;
}
- else if (WIFSIGNALED(status))
+ else
{
- wxLogSysError(_("Waiting for subprocess termination failed (signal not caught)"));
-
- /* AFAIK, this can only happen if something went wrong within
- wxGTK, i.e. due to a race condition or some serious bug.
- After having fixed the order of statements in
- GTK_EndProcessDetector(). (KB)
- */
- }
- // else
- {
- // notify user about termination if required
- if (proc_data->process)
- {
- proc_data->process->OnTerminate(proc_data->pid,
- WEXITSTATUS(status));
- }
- // clean up
- if ( proc_data->pid > 0 )
- {
- delete proc_data;
- }
- else
- {
- // wxExecute() will know about it
- proc_data->exitcode = status;
-
- proc_data->pid = 0;
- }
+ // let wxExecute() know that the process has terminated
+ proc_data->pid = 0;
}
}
#endif // wxUSE_STREAMS
long wxExecute(wxChar **argv,
- bool sync,
+ int flags,
wxProcess *process)
{
// for the sync execution, we return -1 to indicate failure, but for async
//
// we define this as a macro, not a variable, to avoid compiler warnings
// about "ERROR_RETURN_CODE value may be clobbered by fork()"
- #define ERROR_RETURN_CODE ((sync) ? -1 : 0)
+ #define ERROR_RETURN_CODE ((flags & wxEXEC_SYNC) ? -1 : 0)
wxCHECK_MSG( *argv, ERROR_RETURN_CODE, wxT("can't exec empty command") );
// input/output which might block the process or irritate the user. If
// one wants proper IO for the subprocess, the right thing to do is to
// start an xterm executing it.
- if ( !sync )
+ if ( !(flags & wxEXEC_SYNC) )
{
for ( int fd = 0; fd < FD_SETSIZE; fd++ )
{
if ( fd != STDERR_FILENO )
close(fd);
}
+
+#ifndef __VMS
+ if ( flags & wxEXEC_MAKE_GROUP_LEADER )
+ {
+ // Set process group to child process' pid. Then killing -pid
+ // of the parent will kill the process and all of its children.
+ setsid();
+ }
+#endif
}
// redirect stdio, stdout and stderr
#if wxUSE_GUI && !defined(__WXMICROWIN__)
wxEndProcessData *data = new wxEndProcessData;
- if ( sync )
+ if ( flags & wxEXEC_SYNC )
{
// we may have process for capturing the program output, but it's
// not used in wxEndProcessData in the case of sync execution
return pid;
}
#else // !wxUSE_GUI
- wxASSERT_MSG( sync, wxT("async execution not supported yet") );
+
+ wxASSERT_MSG( flags & wxEXEC_SYNC,
+ wxT("async execution not supported yet") );
int exitcode = 0;
if ( waitpid(pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) )
return FALSE;
}
+#ifndef __WXMAC__
wxString wxGetOsDescription()
{
#ifndef WXWIN_OS_DESCRIPTION
return WXWIN_OS_DESCRIPTION;
#endif
}
+#endif
// this function returns the GUI toolkit version in GUI programs, but OS
// version in non-GUI ones
bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree)
{
-#ifdef HAVE_STATFS
-
+#if defined(HAVE_STATFS) || defined(HAVE_STATVFS)
+ // the case to "char *" is needed for AIX 4.3
struct statfs fs;
- if ( statfs(path, &fs) != 0 )
+ if ( statfs((char *)path.fn_str(), &fs) != 0 )
{
wxLogSysError("Failed to get file system statistics");
return FALSE;
}
+ // under Solaris we might have to use fs.f_frsize instead as I think it
+ // may be a multiple of the block size in general (TODO)
+
if ( pTotal )
{
*pTotal = wxLongLong(fs.f_blocks) * fs.f_bsize;
bool wxSetEnv(const wxString& variable, const wxChar *value)
{
#if defined(HAVE_SETENV)
- return setenv(variable.mb_str(), value ? wxString(value).mb_str().data()
- : NULL, 1 /* overwrite */) == 0;
+ return setenv(variable.mb_str(),
+ value ? (const char *)wxString(value).mb_str()
+ : NULL,
+ 1 /* overwrite */) == 0;
#elif defined(HAVE_PUTENV)
wxString s = variable;
if ( value )
#include <signal.h>
-static void wxFatalSignalHandler(wxTYPE_SA_HANDLER)
+extern "C" void wxFatalSignalHandler(wxTYPE_SA_HANDLER)
{
if ( wxTheApp )
{
// error and debug output routines (deprecated, use wxLog)
// ----------------------------------------------------------------------------
+#if WXWIN_COMPATIBILITY_2_2
+
void wxDebugMsg( const char *format, ... )
{
va_list ap;
exit(3); // the same exit code as for abort()
}
+#endif // WXWIN_COMPATIBILITY_2_2
+