get rid of traits functions unnecessary now that wxExecute() works in both base and...
[wxWidgets.git] / src / unix / utilsunx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/utilsunx.cpp
3 // Purpose: generic Unix implementation of many wx functions
4 // Author: Vadim Zeitlin
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling, Vadim Zeitlin
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #include "wx/utils.h"
22
23 #define USE_PUTENV (!defined(HAVE_SETENV) && defined(HAVE_PUTENV))
24
25 #ifndef WX_PRECOMP
26 #include "wx/string.h"
27 #include "wx/intl.h"
28 #include "wx/log.h"
29 #include "wx/app.h"
30 #include "wx/wxcrtvararg.h"
31 #if USE_PUTENV
32 #include "wx/module.h"
33 #include "wx/hashmap.h"
34 #endif
35 #endif
36
37 #include "wx/apptrait.h"
38
39 #include "wx/process.h"
40 #include "wx/thread.h"
41
42 #include "wx/wfstream.h"
43
44 #include "wx/private/selectdispatcher.h"
45 #include "wx/private/fdiodispatcher.h"
46 #include "wx/unix/execute.h"
47 #include "wx/unix/private.h"
48
49 #ifdef wxHAS_GENERIC_PROCESS_CALLBACK
50 #include "wx/private/fdiodispatcher.h"
51 #endif
52
53 #include <pwd.h>
54 #include <sys/wait.h> // waitpid()
55
56 #ifdef HAVE_SYS_SELECT_H
57 # include <sys/select.h>
58 #endif
59
60 #define HAS_PIPE_INPUT_STREAM (wxUSE_STREAMS && wxUSE_FILE)
61
62 #if HAS_PIPE_INPUT_STREAM
63
64 // define this to let wxexec.cpp know that we know what we're doing
65 #define _WX_USED_BY_WXEXECUTE_
66 #include "../common/execcmn.cpp"
67
68 #endif // HAS_PIPE_INPUT_STREAM
69
70 #if defined(__MWERKS__) && defined(__MACH__)
71 #ifndef WXWIN_OS_DESCRIPTION
72 #define WXWIN_OS_DESCRIPTION "MacOS X"
73 #endif
74 #ifndef HAVE_NANOSLEEP
75 #define HAVE_NANOSLEEP
76 #endif
77 #ifndef HAVE_UNAME
78 #define HAVE_UNAME
79 #endif
80
81 // our configure test believes we can use sigaction() if the function is
82 // available but Metrowekrs with MSL run-time does have the function but
83 // doesn't have sigaction struct so finally we can't use it...
84 #ifdef __MSL__
85 #undef wxUSE_ON_FATAL_EXCEPTION
86 #define wxUSE_ON_FATAL_EXCEPTION 0
87 #endif
88 #endif
89
90 // not only the statfs syscall is called differently depending on platform, but
91 // one of its incarnations, statvfs(), takes different arguments under
92 // different platforms and even different versions of the same system (Solaris
93 // 7 and 8): if you want to test for this, don't forget that the problems only
94 // appear if the large files support is enabled
95 #ifdef HAVE_STATFS
96 #ifdef __BSD__
97 #include <sys/param.h>
98 #include <sys/mount.h>
99 #else // !__BSD__
100 #include <sys/vfs.h>
101 #endif // __BSD__/!__BSD__
102
103 #define wxStatfs statfs
104
105 #ifndef HAVE_STATFS_DECL
106 // some systems lack statfs() prototype in the system headers (AIX 4)
107 extern "C" int statfs(const char *path, struct statfs *buf);
108 #endif
109 #endif // HAVE_STATFS
110
111 #ifdef HAVE_STATVFS
112 #include <sys/statvfs.h>
113
114 #define wxStatfs statvfs
115 #endif // HAVE_STATVFS
116
117 #if defined(HAVE_STATFS) || defined(HAVE_STATVFS)
118 // WX_STATFS_T is detected by configure
119 #define wxStatfs_t WX_STATFS_T
120 #endif
121
122 // SGI signal.h defines signal handler arguments differently depending on
123 // whether _LANGUAGE_C_PLUS_PLUS is set or not - do set it
124 #if defined(__SGI__) && !defined(_LANGUAGE_C_PLUS_PLUS)
125 #define _LANGUAGE_C_PLUS_PLUS 1
126 #endif // SGI hack
127
128 #include <stdarg.h>
129 #include <dirent.h>
130 #include <string.h>
131 #include <sys/stat.h>
132 #include <sys/types.h>
133 #include <sys/wait.h>
134 #include <unistd.h>
135 #include <errno.h>
136 #include <netdb.h>
137 #include <signal.h>
138 #include <fcntl.h> // for O_WRONLY and friends
139 #include <time.h> // nanosleep() and/or usleep()
140 #include <ctype.h> // isspace()
141 #include <sys/time.h> // needed for FD_SETSIZE
142
143 #ifdef HAVE_UNAME
144 #include <sys/utsname.h> // for uname()
145 #endif // HAVE_UNAME
146
147 // Used by wxGetFreeMemory().
148 #ifdef __SGI__
149 #include <sys/sysmp.h>
150 #include <sys/sysinfo.h> // for SAGET and MINFO structures
151 #endif
152
153 // ----------------------------------------------------------------------------
154 // conditional compilation
155 // ----------------------------------------------------------------------------
156
157 // many versions of Unices have this function, but it is not defined in system
158 // headers - please add your system here if it is the case for your OS.
159 // SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this.
160 #if !defined(HAVE_USLEEP) && \
161 ((defined(__SUN__) && !defined(__SunOs_5_6) && \
162 !defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
163 defined(__osf__) || defined(__EMX__))
164 extern "C"
165 {
166 #ifdef __EMX__
167 /* I copied this from the XFree86 diffs. AV. */
168 #define INCL_DOSPROCESS
169 #include <os2.h>
170 inline void usleep(unsigned long delay)
171 {
172 DosSleep(delay ? (delay/1000l) : 1l);
173 }
174 #else // Unix
175 int usleep(unsigned int usec);
176 #endif // __EMX__/Unix
177 };
178
179 #define HAVE_USLEEP 1
180 #endif // Unices without usleep()
181
182 // ============================================================================
183 // implementation
184 // ============================================================================
185
186 // ----------------------------------------------------------------------------
187 // sleeping
188 // ----------------------------------------------------------------------------
189
190 void wxSleep(int nSecs)
191 {
192 sleep(nSecs);
193 }
194
195 void wxMicroSleep(unsigned long microseconds)
196 {
197 #if defined(HAVE_NANOSLEEP)
198 timespec tmReq;
199 tmReq.tv_sec = (time_t)(microseconds / 1000000);
200 tmReq.tv_nsec = (microseconds % 1000000) * 1000;
201
202 // we're not interested in remaining time nor in return value
203 (void)nanosleep(&tmReq, (timespec *)NULL);
204 #elif defined(HAVE_USLEEP)
205 // uncomment this if you feel brave or if you are sure that your version
206 // of Solaris has a safe usleep() function but please notice that usleep()
207 // is known to lead to crashes in MT programs in Solaris 2.[67] and is not
208 // documented as MT-Safe
209 #if defined(__SUN__) && wxUSE_THREADS
210 #error "usleep() cannot be used in MT programs under Solaris."
211 #endif // Sun
212
213 usleep(microseconds);
214 #elif defined(HAVE_SLEEP)
215 // under BeOS sleep() takes seconds (what about other platforms, if any?)
216 sleep(microseconds * 1000000);
217 #else // !sleep function
218 #error "usleep() or nanosleep() function required for wxMicroSleep"
219 #endif // sleep function
220 }
221
222 void wxMilliSleep(unsigned long milliseconds)
223 {
224 wxMicroSleep(milliseconds*1000);
225 }
226
227 // ----------------------------------------------------------------------------
228 // process management
229 // ----------------------------------------------------------------------------
230
231 int wxKill(long pid, wxSignal sig, wxKillError *rc, int flags)
232 {
233 int err = kill((pid_t) (flags & wxKILL_CHILDREN) ? -pid : pid, (int)sig);
234 if ( rc )
235 {
236 switch ( err ? errno : 0 )
237 {
238 case 0:
239 *rc = wxKILL_OK;
240 break;
241
242 case EINVAL:
243 *rc = wxKILL_BAD_SIGNAL;
244 break;
245
246 case EPERM:
247 *rc = wxKILL_ACCESS_DENIED;
248 break;
249
250 case ESRCH:
251 *rc = wxKILL_NO_PROCESS;
252 break;
253
254 default:
255 // this goes against Unix98 docs so log it
256 wxLogDebug(_T("unexpected kill(2) return value %d"), err);
257
258 // something else...
259 *rc = wxKILL_ERROR;
260 }
261 }
262
263 return err;
264 }
265
266 #define WXEXECUTE_NARGS 127
267
268 #if defined(__DARWIN__)
269 long wxMacExecute(wxChar **argv,
270 int flags,
271 wxProcess *process);
272 #endif
273
274 long wxExecute( const wxString& command, int flags, wxProcess *process )
275 {
276 wxCHECK_MSG( !command.empty(), 0, wxT("can't exec empty command") );
277
278 wxLogTrace(wxT("exec"), wxT("Executing \"%s\""), command.c_str());
279
280 #if wxUSE_THREADS
281 // fork() doesn't mix well with POSIX threads: on many systems the program
282 // deadlocks or crashes for some reason. Probably our code is buggy and
283 // doesn't do something which must be done to allow this to work, but I
284 // don't know what yet, so for now just warn the user (this is the least we
285 // can do) about it
286 wxASSERT_MSG( wxThread::IsMain(),
287 _T("wxExecute() can be called only from the main thread") );
288 #endif // wxUSE_THREADS
289
290 int argc = 0;
291 wxChar *argv[WXEXECUTE_NARGS];
292 wxString argument;
293 const wxChar *cptr = command.c_str();
294 wxChar quotechar = wxT('\0'); // is arg quoted?
295 bool escaped = false;
296
297 // split the command line in arguments
298 do
299 {
300 argument = wxEmptyString;
301 quotechar = wxT('\0');
302
303 // eat leading whitespace:
304 while ( wxIsspace(*cptr) )
305 cptr++;
306
307 if ( *cptr == wxT('\'') || *cptr == wxT('"') )
308 quotechar = *cptr++;
309
310 do
311 {
312 if ( *cptr == wxT('\\') && ! escaped )
313 {
314 escaped = true;
315 cptr++;
316 continue;
317 }
318
319 // all other characters:
320 argument += *cptr++;
321 escaped = false;
322
323 // have we reached the end of the argument?
324 if ( (*cptr == quotechar && ! escaped)
325 || (quotechar == wxT('\0') && wxIsspace(*cptr))
326 || *cptr == wxT('\0') )
327 {
328 wxASSERT_MSG( argc < WXEXECUTE_NARGS,
329 wxT("too many arguments in wxExecute") );
330
331 argv[argc] = new wxChar[argument.length() + 1];
332 wxStrcpy(argv[argc], argument.c_str());
333 argc++;
334
335 // if not at end of buffer, swallow last character:
336 if(*cptr)
337 cptr++;
338
339 break; // done with this one, start over
340 }
341 } while(*cptr);
342 } while(*cptr);
343 argv[argc] = NULL;
344
345 long lRc;
346 #if defined(__DARWIN__)
347 // wxMacExecute only executes app bundles.
348 // It returns an error code if the target is not an app bundle, thus falling
349 // through to the regular wxExecute for non app bundles.
350 lRc = wxMacExecute(argv, flags, process);
351 if( lRc != ((flags & wxEXEC_SYNC) ? -1 : 0))
352 return lRc;
353 #endif
354
355 // do execute the command
356 lRc = wxExecute(argv, flags, process);
357
358 // clean up
359 argc = 0;
360 while( argv[argc] )
361 delete [] argv[argc++];
362
363 return lRc;
364 }
365
366 // ----------------------------------------------------------------------------
367 // wxShell
368 // ----------------------------------------------------------------------------
369
370 static wxString wxMakeShellCommand(const wxString& command)
371 {
372 wxString cmd;
373 if ( !command )
374 {
375 // just an interactive shell
376 cmd = _T("xterm");
377 }
378 else
379 {
380 // execute command in a shell
381 cmd << _T("/bin/sh -c '") << command << _T('\'');
382 }
383
384 return cmd;
385 }
386
387 bool wxShell(const wxString& command)
388 {
389 return wxExecute(wxMakeShellCommand(command), wxEXEC_SYNC) == 0;
390 }
391
392 bool wxShell(const wxString& command, wxArrayString& output)
393 {
394 wxCHECK_MSG( !command.empty(), false, _T("can't exec shell non interactively") );
395
396 return wxExecute(wxMakeShellCommand(command), output);
397 }
398
399 // Shutdown or reboot the PC
400 bool wxShutdown(wxShutdownFlags wFlags)
401 {
402 wxChar level;
403 switch ( wFlags )
404 {
405 case wxSHUTDOWN_POWEROFF:
406 level = _T('0');
407 break;
408
409 case wxSHUTDOWN_REBOOT:
410 level = _T('6');
411 break;
412
413 default:
414 wxFAIL_MSG( _T("unknown wxShutdown() flag") );
415 return false;
416 }
417
418 return system(wxString::Format(_T("init %c"), level).mb_str()) == 0;
419 }
420
421 // ----------------------------------------------------------------------------
422 // wxStream classes to support IO redirection in wxExecute
423 // ----------------------------------------------------------------------------
424
425 #if HAS_PIPE_INPUT_STREAM
426
427 bool wxPipeInputStream::CanRead() const
428 {
429 if ( m_lasterror == wxSTREAM_EOF )
430 return false;
431
432 // check if there is any input available
433 struct timeval tv;
434 tv.tv_sec = 0;
435 tv.tv_usec = 0;
436
437 const int fd = m_file->fd();
438
439 fd_set readfds;
440
441 wxFD_ZERO(&readfds);
442 wxFD_SET(fd, &readfds);
443
444 switch ( select(fd + 1, &readfds, NULL, NULL, &tv) )
445 {
446 case -1:
447 wxLogSysError(_("Impossible to get child process input"));
448 // fall through
449
450 case 0:
451 return false;
452
453 default:
454 wxFAIL_MSG(_T("unexpected select() return value"));
455 // still fall through
456
457 case 1:
458 // input available -- or maybe not, as select() returns 1 when a
459 // read() will complete without delay, but it could still not read
460 // anything
461 return !Eof();
462 }
463 }
464
465 #endif // HAS_PIPE_INPUT_STREAM
466
467 // ----------------------------------------------------------------------------
468 // wxExecute: the real worker function
469 // ----------------------------------------------------------------------------
470
471 long wxExecute(wxChar **argv, int flags, wxProcess *process)
472 {
473 // for the sync execution, we return -1 to indicate failure, but for async
474 // case we return 0 which is never a valid PID
475 //
476 // we define this as a macro, not a variable, to avoid compiler warnings
477 // about "ERROR_RETURN_CODE value may be clobbered by fork()"
478 #define ERROR_RETURN_CODE ((flags & wxEXEC_SYNC) ? -1 : 0)
479
480 wxCHECK_MSG( *argv, ERROR_RETURN_CODE, wxT("can't exec empty command") );
481
482 #if wxUSE_UNICODE
483 int mb_argc = 0;
484 char *mb_argv[WXEXECUTE_NARGS];
485
486 while (argv[mb_argc])
487 {
488 wxWX2MBbuf mb_arg = wxSafeConvertWX2MB(argv[mb_argc]);
489 mb_argv[mb_argc] = strdup(mb_arg);
490 mb_argc++;
491 }
492 mb_argv[mb_argc] = (char *) NULL;
493
494 // this macro will free memory we used above
495 #define ARGS_CLEANUP \
496 for ( mb_argc = 0; mb_argv[mb_argc]; mb_argc++ ) \
497 free(mb_argv[mb_argc])
498 #else // ANSI
499 // no need for cleanup
500 #define ARGS_CLEANUP
501
502 wxChar **mb_argv = argv;
503 #endif // Unicode/ANSI
504
505 // we want this function to work even if there is no wxApp so ensure that
506 // we have a valid traits pointer
507 wxConsoleAppTraits traitsConsole;
508 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
509 if ( !traits )
510 traits = &traitsConsole;
511
512 // this struct contains all information which we pass to and from
513 // wxAppTraits methods
514 wxExecuteData execData;
515 execData.flags = flags;
516 execData.process = process;
517
518 // create pipes
519 if ( !execData.pipeEndProcDetect.Create() )
520 {
521 wxLogError( _("Failed to execute '%s'\n"), *argv );
522
523 ARGS_CLEANUP;
524
525 return ERROR_RETURN_CODE;
526 }
527
528 // pipes for inter process communication
529 wxPipe pipeIn, // stdin
530 pipeOut, // stdout
531 pipeErr; // stderr
532
533 if ( process && process->IsRedirected() )
534 {
535 if ( !pipeIn.Create() || !pipeOut.Create() || !pipeErr.Create() )
536 {
537 wxLogError( _("Failed to execute '%s'\n"), *argv );
538
539 ARGS_CLEANUP;
540
541 return ERROR_RETURN_CODE;
542 }
543 }
544
545 // fork the process
546 //
547 // NB: do *not* use vfork() here, it completely breaks this code for some
548 // reason under Solaris (and maybe others, although not under Linux)
549 // But on OpenVMS we do not have fork so we have to use vfork and
550 // cross our fingers that it works.
551 #ifdef __VMS
552 pid_t pid = vfork();
553 #else
554 pid_t pid = fork();
555 #endif
556 if ( pid == -1 ) // error?
557 {
558 wxLogSysError( _("Fork failed") );
559
560 ARGS_CLEANUP;
561
562 return ERROR_RETURN_CODE;
563 }
564 else if ( pid == 0 ) // we're in child
565 {
566 // These lines close the open file descriptors to to avoid any
567 // input/output which might block the process or irritate the user. If
568 // one wants proper IO for the subprocess, the right thing to do is to
569 // start an xterm executing it.
570 if ( !(flags & wxEXEC_SYNC) )
571 {
572 // FD_SETSIZE is unsigned under BSD, signed under other platforms
573 // so we need a cast to avoid warnings on all platforms
574 for ( int fd = 0; fd < (int)FD_SETSIZE; fd++ )
575 {
576 if ( fd == pipeIn[wxPipe::Read]
577 || fd == pipeOut[wxPipe::Write]
578 || fd == pipeErr[wxPipe::Write]
579 || fd == (execData.pipeEndProcDetect)[wxPipe::Write] )
580 {
581 // don't close this one, we still need it
582 continue;
583 }
584
585 // leave stderr opened too, it won't do any harm
586 if ( fd != STDERR_FILENO )
587 close(fd);
588 }
589 }
590
591 #if !defined(__VMS) && !defined(__EMX__)
592 if ( flags & wxEXEC_MAKE_GROUP_LEADER )
593 {
594 // Set process group to child process' pid. Then killing -pid
595 // of the parent will kill the process and all of its children.
596 setsid();
597 }
598 #endif // !__VMS
599
600 // reading side can be safely closed but we should keep the write one
601 // opened, it will be only closed when the process terminates resulting
602 // in a read notification to the parent
603 execData.pipeEndProcDetect.Detach(wxPipe::Write);
604 execData.pipeEndProcDetect.Close();
605
606 // redirect stdin, stdout and stderr
607 if ( pipeIn.IsOk() )
608 {
609 if ( dup2(pipeIn[wxPipe::Read], STDIN_FILENO) == -1 ||
610 dup2(pipeOut[wxPipe::Write], STDOUT_FILENO) == -1 ||
611 dup2(pipeErr[wxPipe::Write], STDERR_FILENO) == -1 )
612 {
613 wxLogSysError(_("Failed to redirect child process input/output"));
614 }
615
616 pipeIn.Close();
617 pipeOut.Close();
618 pipeErr.Close();
619 }
620
621 execvp (*mb_argv, mb_argv);
622
623 fprintf(stderr, "execvp(");
624 // CS changed ppc to ppc_ as ppc is not available under mac os CW Mach-O
625 for ( char **ppc_ = mb_argv; *ppc_; ppc_++ )
626 fprintf(stderr, "%s%s", ppc_ == mb_argv ? "" : ", ", *ppc_);
627 fprintf(stderr, ") failed with error %d!\n", errno);
628
629 // there is no return after successful exec()
630 _exit(-1);
631
632 // some compilers complain about missing return - of course, they
633 // should know that exit() doesn't return but what else can we do if
634 // they don't?
635 //
636 // and, sure enough, other compilers complain about unreachable code
637 // after exit() call, so we can just always have return here...
638 #if defined(__VMS) || defined(__INTEL_COMPILER)
639 return 0;
640 #endif
641 }
642 else // we're in parent
643 {
644 ARGS_CLEANUP;
645
646 // save it for WaitForChild() use
647 execData.pid = pid;
648
649 // prepare for IO redirection
650
651 #if HAS_PIPE_INPUT_STREAM
652 // the input buffer bufOut is connected to stdout, this is why it is
653 // called bufOut and not bufIn
654 wxStreamTempInputBuffer bufOut,
655 bufErr;
656
657 if ( process && process->IsRedirected() )
658 {
659 wxOutputStream *inStream =
660 new wxFileOutputStream(pipeIn.Detach(wxPipe::Write));
661
662 const int fdOut = pipeOut.Detach(wxPipe::Read);
663 wxPipeInputStream *outStream = new wxPipeInputStream(fdOut);
664
665 const int fdErr = pipeErr.Detach(wxPipe::Read);
666 wxPipeInputStream *errStream = new wxPipeInputStream(fdErr);
667
668 process->SetPipeStreams(outStream, inStream, errStream);
669
670 bufOut.Init(outStream);
671 bufErr.Init(errStream);
672
673 execData.bufOut = &bufOut;
674 execData.bufErr = &bufErr;
675
676 execData.fdOut = fdOut;
677 execData.fdErr = fdErr;
678 }
679 #endif // HAS_PIPE_INPUT_STREAM
680
681 if ( pipeIn.IsOk() )
682 {
683 pipeIn.Close();
684 pipeOut.Close();
685 pipeErr.Close();
686 }
687
688 return traits->WaitForChild(execData);
689 }
690
691 #if !defined(__VMS) && !defined(__INTEL_COMPILER)
692 return ERROR_RETURN_CODE;
693 #endif
694 }
695
696 #undef ERROR_RETURN_CODE
697 #undef ARGS_CLEANUP
698
699 // ----------------------------------------------------------------------------
700 // file and directory functions
701 // ----------------------------------------------------------------------------
702
703 const wxChar* wxGetHomeDir( wxString *home )
704 {
705 *home = wxGetUserHome();
706 wxString tmp;
707 if ( home->empty() )
708 *home = wxT("/");
709 #ifdef __VMS
710 tmp = *home;
711 if ( tmp.Last() != wxT(']'))
712 if ( tmp.Last() != wxT('/')) *home << wxT('/');
713 #endif
714 return home->c_str();
715 }
716
717 wxString wxGetUserHome( const wxString &user )
718 {
719 struct passwd *who = (struct passwd *) NULL;
720
721 if ( !user )
722 {
723 wxChar *ptr;
724
725 if ((ptr = wxGetenv(wxT("HOME"))) != NULL)
726 {
727 return ptr;
728 }
729
730 if ((ptr = wxGetenv(wxT("USER"))) != NULL ||
731 (ptr = wxGetenv(wxT("LOGNAME"))) != NULL)
732 {
733 who = getpwnam(wxSafeConvertWX2MB(ptr));
734 }
735
736 // make sure the user exists!
737 if ( !who )
738 {
739 who = getpwuid(getuid());
740 }
741 }
742 else
743 {
744 who = getpwnam (user.mb_str());
745 }
746
747 return wxSafeConvertMB2WX(who ? who->pw_dir : 0);
748 }
749
750 // ----------------------------------------------------------------------------
751 // network and user id routines
752 // ----------------------------------------------------------------------------
753
754 // private utility function which returns output of the given command, removing
755 // the trailing newline
756 static wxString wxGetCommandOutput(const wxString &cmd)
757 {
758 FILE *f = popen(cmd.ToAscii(), "r");
759 if ( !f )
760 {
761 wxLogSysError(_T("Executing \"%s\" failed"), cmd.c_str());
762 return wxEmptyString;
763 }
764
765 wxString s;
766 char buf[256];
767 while ( !feof(f) )
768 {
769 if ( !fgets(buf, sizeof(buf), f) )
770 break;
771
772 s += wxString::FromAscii(buf);
773 }
774
775 pclose(f);
776
777 if ( !s.empty() && s.Last() == _T('\n') )
778 s.RemoveLast();
779
780 return s;
781 }
782
783 // retrieve either the hostname or FQDN depending on platform (caller must
784 // check whether it's one or the other, this is why this function is for
785 // private use only)
786 static bool wxGetHostNameInternal(wxChar *buf, int sz)
787 {
788 wxCHECK_MSG( buf, false, wxT("NULL pointer in wxGetHostNameInternal") );
789
790 *buf = wxT('\0');
791
792 // we're using uname() which is POSIX instead of less standard sysinfo()
793 #if defined(HAVE_UNAME)
794 struct utsname uts;
795 bool ok = uname(&uts) != -1;
796 if ( ok )
797 {
798 wxStrncpy(buf, wxSafeConvertMB2WX(uts.nodename), sz - 1);
799 buf[sz] = wxT('\0');
800 }
801 #elif defined(HAVE_GETHOSTNAME)
802 char cbuf[sz];
803 bool ok = gethostname(cbuf, sz) != -1;
804 if ( ok )
805 {
806 wxStrncpy(buf, wxSafeConvertMB2WX(cbuf), sz - 1);
807 buf[sz] = wxT('\0');
808 }
809 #else // no uname, no gethostname
810 wxFAIL_MSG(wxT("don't know host name for this machine"));
811
812 bool ok = false;
813 #endif // uname/gethostname
814
815 if ( !ok )
816 {
817 wxLogSysError(_("Cannot get the hostname"));
818 }
819
820 return ok;
821 }
822
823 bool wxGetHostName(wxChar *buf, int sz)
824 {
825 bool ok = wxGetHostNameInternal(buf, sz);
826
827 if ( ok )
828 {
829 // BSD systems return the FQDN, we only want the hostname, so extract
830 // it (we consider that dots are domain separators)
831 wxChar *dot = wxStrchr(buf, wxT('.'));
832 if ( dot )
833 {
834 // nuke it
835 *dot = wxT('\0');
836 }
837 }
838
839 return ok;
840 }
841
842 bool wxGetFullHostName(wxChar *buf, int sz)
843 {
844 bool ok = wxGetHostNameInternal(buf, sz);
845
846 if ( ok )
847 {
848 if ( !wxStrchr(buf, wxT('.')) )
849 {
850 struct hostent *host = gethostbyname(wxSafeConvertWX2MB(buf));
851 if ( !host )
852 {
853 wxLogSysError(_("Cannot get the official hostname"));
854
855 ok = false;
856 }
857 else
858 {
859 // the canonical name
860 wxStrncpy(buf, wxSafeConvertMB2WX(host->h_name), sz);
861 }
862 }
863 //else: it's already a FQDN (BSD behaves this way)
864 }
865
866 return ok;
867 }
868
869 bool wxGetUserId(wxChar *buf, int sz)
870 {
871 struct passwd *who;
872
873 *buf = wxT('\0');
874 if ((who = getpwuid(getuid ())) != NULL)
875 {
876 wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_name), sz - 1);
877 return true;
878 }
879
880 return false;
881 }
882
883 bool wxGetUserName(wxChar *buf, int sz)
884 {
885 #ifdef HAVE_PW_GECOS
886 struct passwd *who;
887
888 *buf = wxT('\0');
889 if ((who = getpwuid (getuid ())) != NULL)
890 {
891 char *comma = strchr(who->pw_gecos, ',');
892 if (comma)
893 *comma = '\0'; // cut off non-name comment fields
894 wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_gecos), sz - 1);
895 return true;
896 }
897
898 return false;
899 #else // !HAVE_PW_GECOS
900 return wxGetUserId(buf, sz);
901 #endif // HAVE_PW_GECOS/!HAVE_PW_GECOS
902 }
903
904 bool wxIsPlatform64Bit()
905 {
906 const wxString machine = wxGetCommandOutput(wxT("uname -m"));
907
908 // the test for "64" is obviously not 100% reliable but seems to work fine
909 // in practice
910 return machine.Contains(wxT("64")) ||
911 machine.Contains(wxT("alpha"));
912 }
913
914 // these functions are in mac/utils.cpp for wxMac
915 #ifndef __WXMAC__
916
917 wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin)
918 {
919 // get OS version
920 int major, minor;
921 wxString release = wxGetCommandOutput(wxT("uname -r"));
922 if ( release.empty() ||
923 wxSscanf(release.c_str(), wxT("%d.%d"), &major, &minor) != 2 )
924 {
925 // failed to get version string or unrecognized format
926 major =
927 minor = -1;
928 }
929
930 if ( verMaj )
931 *verMaj = major;
932 if ( verMin )
933 *verMin = minor;
934
935 // try to understand which OS are we running
936 wxString kernel = wxGetCommandOutput(wxT("uname -s"));
937 if ( kernel.empty() )
938 kernel = wxGetCommandOutput(wxT("uname -o"));
939
940 if ( kernel.empty() )
941 return wxOS_UNKNOWN;
942
943 return wxPlatformInfo::GetOperatingSystemId(kernel);
944 }
945
946 wxString wxGetOsDescription()
947 {
948 return wxGetCommandOutput(wxT("uname -s -r -m"));
949 }
950
951 #endif // !__WXMAC__
952
953 unsigned long wxGetProcessId()
954 {
955 return (unsigned long)getpid();
956 }
957
958 wxMemorySize wxGetFreeMemory()
959 {
960 #if defined(__LINUX__)
961 // get it from /proc/meminfo
962 FILE *fp = fopen("/proc/meminfo", "r");
963 if ( fp )
964 {
965 long memFree = -1;
966
967 char buf[1024];
968 if ( fgets(buf, WXSIZEOF(buf), fp) && fgets(buf, WXSIZEOF(buf), fp) )
969 {
970 // /proc/meminfo changed its format in kernel 2.6
971 if ( wxPlatformInfo().CheckOSVersion(2, 6) )
972 {
973 unsigned long cached, buffers;
974 sscanf(buf, "MemFree: %ld", &memFree);
975
976 fgets(buf, WXSIZEOF(buf), fp);
977 sscanf(buf, "Buffers: %lu", &buffers);
978
979 fgets(buf, WXSIZEOF(buf), fp);
980 sscanf(buf, "Cached: %lu", &cached);
981
982 // add to "MemFree" also the "Buffers" and "Cached" values as
983 // free(1) does as otherwise the value never makes sense: for
984 // kernel 2.6 it's always almost 0
985 memFree += buffers + cached;
986
987 // values here are always expressed in kB and we want bytes
988 memFree *= 1024;
989 }
990 else // Linux 2.4 (or < 2.6, anyhow)
991 {
992 long memTotal, memUsed;
993 sscanf(buf, "Mem: %ld %ld %ld", &memTotal, &memUsed, &memFree);
994 }
995 }
996
997 fclose(fp);
998
999 return (wxMemorySize)memFree;
1000 }
1001 #elif defined(__SGI__)
1002 struct rminfo realmem;
1003 if ( sysmp(MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0 )
1004 return ((wxMemorySize)realmem.physmem * sysconf(_SC_PAGESIZE));
1005 #elif defined(_SC_AVPHYS_PAGES)
1006 return ((wxMemorySize)sysconf(_SC_AVPHYS_PAGES))*sysconf(_SC_PAGESIZE);
1007 //#elif defined(__FREEBSD__) -- might use sysctl() to find it out, probably
1008 #endif
1009
1010 // can't find it out
1011 return -1;
1012 }
1013
1014 bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree)
1015 {
1016 #if defined(HAVE_STATFS) || defined(HAVE_STATVFS)
1017 // the case to "char *" is needed for AIX 4.3
1018 wxStatfs_t fs;
1019 if ( wxStatfs((char *)(const char*)path.fn_str(), &fs) != 0 )
1020 {
1021 wxLogSysError( wxT("Failed to get file system statistics") );
1022
1023 return false;
1024 }
1025
1026 // under Solaris we also have to use f_frsize field instead of f_bsize
1027 // which is in general a multiple of f_frsize
1028 #ifdef HAVE_STATVFS
1029 wxDiskspaceSize_t blockSize = fs.f_frsize;
1030 #else // HAVE_STATFS
1031 wxDiskspaceSize_t blockSize = fs.f_bsize;
1032 #endif // HAVE_STATVFS/HAVE_STATFS
1033
1034 if ( pTotal )
1035 {
1036 *pTotal = wxDiskspaceSize_t(fs.f_blocks) * blockSize;
1037 }
1038
1039 if ( pFree )
1040 {
1041 *pFree = wxDiskspaceSize_t(fs.f_bavail) * blockSize;
1042 }
1043
1044 return true;
1045 #else // !HAVE_STATFS && !HAVE_STATVFS
1046 return false;
1047 #endif // HAVE_STATFS
1048 }
1049
1050 // ----------------------------------------------------------------------------
1051 // env vars
1052 // ----------------------------------------------------------------------------
1053
1054 #if USE_PUTENV
1055
1056 WX_DECLARE_STRING_HASH_MAP(char *, wxEnvVars);
1057
1058 static wxEnvVars gs_envVars;
1059
1060 class wxSetEnvModule : public wxModule
1061 {
1062 public:
1063 virtual bool OnInit() { return true; }
1064 virtual void OnExit()
1065 {
1066 for ( wxEnvVars::const_iterator i = gs_envVars.begin();
1067 i != gs_envVars.end();
1068 ++i )
1069 {
1070 free(i->second);
1071 }
1072
1073 gs_envVars.clear();
1074 }
1075
1076 DECLARE_DYNAMIC_CLASS(wxSetEnvModule)
1077 };
1078
1079 IMPLEMENT_DYNAMIC_CLASS(wxSetEnvModule, wxModule)
1080
1081 #endif // USE_PUTENV
1082
1083 bool wxGetEnv(const wxString& var, wxString *value)
1084 {
1085 // wxGetenv is defined as getenv()
1086 char *p = wxGetenv(var);
1087 if ( !p )
1088 return false;
1089
1090 if ( value )
1091 {
1092 *value = p;
1093 }
1094
1095 return true;
1096 }
1097
1098 static bool wxDoSetEnv(const wxString& variable, const char *value)
1099 {
1100 #if defined(HAVE_SETENV)
1101 if ( !value )
1102 {
1103 #ifdef HAVE_UNSETENV
1104 // don't test unsetenv() return value: it's void on some systems (at
1105 // least Darwin)
1106 unsetenv(variable.mb_str());
1107 return true;
1108 #else
1109 value = ""; // we can't pass NULL to setenv()
1110 #endif
1111 }
1112
1113 return setenv(variable.mb_str(), value, 1 /* overwrite */) == 0;
1114 #elif defined(HAVE_PUTENV)
1115 wxString s = variable;
1116 if ( value )
1117 s << _T('=') << value;
1118
1119 // transform to ANSI
1120 const wxWX2MBbuf p = s.mb_str();
1121
1122 char *buf = (char *)malloc(strlen(p) + 1);
1123 strcpy(buf, p);
1124
1125 // store the string to free() it later
1126 wxEnvVars::iterator i = gs_envVars.find(variable);
1127 if ( i != gs_envVars.end() )
1128 {
1129 free(i->second);
1130 i->second = buf;
1131 }
1132 else // this variable hadn't been set before
1133 {
1134 gs_envVars[variable] = buf;
1135 }
1136
1137 return putenv(buf) == 0;
1138 #else // no way to set an env var
1139 return false;
1140 #endif
1141 }
1142
1143 bool wxSetEnv(const wxString& variable, const wxString& value)
1144 {
1145 return wxDoSetEnv(variable, value.mb_str());
1146 }
1147
1148 bool wxUnsetEnv(const wxString& variable)
1149 {
1150 return wxDoSetEnv(variable, NULL);
1151 }
1152
1153 // ----------------------------------------------------------------------------
1154 // signal handling
1155 // ----------------------------------------------------------------------------
1156
1157 #if wxUSE_ON_FATAL_EXCEPTION
1158
1159 #include <signal.h>
1160
1161 extern "C" void wxFatalSignalHandler(wxTYPE_SA_HANDLER)
1162 {
1163 if ( wxTheApp )
1164 {
1165 // give the user a chance to do something special about this
1166 wxTheApp->OnFatalException();
1167 }
1168
1169 abort();
1170 }
1171
1172 bool wxHandleFatalExceptions(bool doit)
1173 {
1174 // old sig handlers
1175 static bool s_savedHandlers = false;
1176 static struct sigaction s_handlerFPE,
1177 s_handlerILL,
1178 s_handlerBUS,
1179 s_handlerSEGV;
1180
1181 bool ok = true;
1182 if ( doit && !s_savedHandlers )
1183 {
1184 // install the signal handler
1185 struct sigaction act;
1186
1187 // some systems extend it with non std fields, so zero everything
1188 memset(&act, 0, sizeof(act));
1189
1190 act.sa_handler = wxFatalSignalHandler;
1191 sigemptyset(&act.sa_mask);
1192 act.sa_flags = 0;
1193
1194 ok &= sigaction(SIGFPE, &act, &s_handlerFPE) == 0;
1195 ok &= sigaction(SIGILL, &act, &s_handlerILL) == 0;
1196 ok &= sigaction(SIGBUS, &act, &s_handlerBUS) == 0;
1197 ok &= sigaction(SIGSEGV, &act, &s_handlerSEGV) == 0;
1198 if ( !ok )
1199 {
1200 wxLogDebug(_T("Failed to install our signal handler."));
1201 }
1202
1203 s_savedHandlers = true;
1204 }
1205 else if ( s_savedHandlers )
1206 {
1207 // uninstall the signal handler
1208 ok &= sigaction(SIGFPE, &s_handlerFPE, NULL) == 0;
1209 ok &= sigaction(SIGILL, &s_handlerILL, NULL) == 0;
1210 ok &= sigaction(SIGBUS, &s_handlerBUS, NULL) == 0;
1211 ok &= sigaction(SIGSEGV, &s_handlerSEGV, NULL) == 0;
1212 if ( !ok )
1213 {
1214 wxLogDebug(_T("Failed to uninstall our signal handler."));
1215 }
1216
1217 s_savedHandlers = false;
1218 }
1219 //else: nothing to do
1220
1221 return ok;
1222 }
1223
1224 #endif // wxUSE_ON_FATAL_EXCEPTION
1225
1226 // ----------------------------------------------------------------------------
1227 // wxExecute support
1228 // ----------------------------------------------------------------------------
1229
1230 int wxAppTraits::AddProcessCallback(wxEndProcessData *data, int fd)
1231 {
1232 // define a custom handler processing only the closure of the descriptor
1233 struct wxEndProcessFDIOHandler : public wxFDIOHandler
1234 {
1235 wxEndProcessFDIOHandler(wxEndProcessData *data, int fd)
1236 : m_data(data), m_fd(fd)
1237 {}
1238
1239 virtual void OnReadWaiting()
1240 { wxFAIL_MSG("this isn't supposed to happen"); }
1241 virtual void OnWriteWaiting()
1242 { wxFAIL_MSG("this isn't supposed to happen"); }
1243
1244 virtual void OnExceptionWaiting()
1245 {
1246 const int pid = m_data->pid > 0 ? m_data->pid : -(m_data->pid);
1247 int status = 0;
1248
1249 // has the process really terminated?
1250 int rc = waitpid(pid, &status, WNOHANG);
1251 if ( rc == 0 )
1252 {
1253 // This can only happen if the child application closes our
1254 // dummy pipe that is used to monitor its lifetime; in that
1255 // case, our best bet is to pretend the process did terminate,
1256 // because otherwise wxExecute() would hang indefinitely
1257 // (OnExceptionWaiting() won't be called again, the descriptor
1258 // is closed now).
1259 wxLogDebug("Child process (PID %d) still alive, "
1260 "even though pipe was closed.", pid);
1261 }
1262 else if ( rc == -1 )
1263 {
1264 // As above, if waitpid() fails, the best we can do is to log the
1265 // error and pretend the child terminated:
1266 wxLogSysError(_("Failed to check child process' status"));
1267 }
1268
1269 // set exit code to -1 if something bad happened
1270 m_data->exitcode = rc > 0 && WIFEXITED(status) ? WEXITSTATUS(status)
1271 : -1;
1272
1273 wxLogTrace("exec",
1274 "Child process (PID %d) terminated with exit code %d",
1275 pid, m_data->exitcode);
1276
1277 // child exited, end waiting
1278 wxFDIODispatcher::Get()->UnregisterFD(m_fd);
1279 close(m_fd);
1280
1281 wxHandleProcessTermination(m_data);
1282
1283 delete this;
1284 }
1285
1286 wxEndProcessData * const m_data;
1287 const int m_fd;
1288 };
1289
1290 wxFDIODispatcher::Get()->RegisterFD
1291 (
1292 fd,
1293 new wxEndProcessFDIOHandler(data, fd),
1294 wxFDIO_EXCEPTION
1295 );
1296 return fd; // unused, but return something unique for the tag
1297 }
1298
1299 bool wxAppTraits::CheckForRedirectedIO(wxExecuteData& execData)
1300 {
1301 #if HAS_PIPE_INPUT_STREAM
1302 bool hasIO = false;
1303
1304 if ( execData.bufOut && execData.bufOut->Update() )
1305 hasIO = true;
1306
1307 if ( execData.bufErr && execData.bufErr->Update() )
1308 hasIO = true;
1309
1310 return hasIO;
1311 #else // !HAS_PIPE_INPUT_STREAM
1312 return false;
1313 #endif // HAS_PIPE_INPUT_STREAM/!HAS_PIPE_INPUT_STREAM
1314 }
1315
1316 class wxReadFDIOHandler : public wxFDIOHandler
1317 {
1318 public:
1319 wxReadFDIOHandler(wxFDIODispatcher& disp, int fd) : m_fd(fd)
1320 {
1321 if ( fd )
1322 disp.RegisterFD(fd, this, wxFDIO_INPUT);
1323 }
1324
1325 int GetFD() const { return m_fd; }
1326
1327 virtual void OnWriteWaiting() { wxFAIL_MSG("unreachable"); }
1328 virtual void OnExceptionWaiting() { wxFAIL_MSG("unreachable"); }
1329
1330 private:
1331 const int m_fd;
1332
1333 DECLARE_NO_COPY_CLASS(wxReadFDIOHandler)
1334 };
1335
1336 class wxEndHandler : public wxReadFDIOHandler
1337 {
1338 public:
1339 wxEndHandler(wxFDIODispatcher& disp, int fd)
1340 : wxReadFDIOHandler(disp, fd)
1341 {
1342 m_terminated = false;
1343 }
1344
1345 bool Terminated() const { return m_terminated; }
1346
1347 virtual void OnReadWaiting() { m_terminated = true; }
1348
1349 private:
1350 bool m_terminated;
1351
1352 DECLARE_NO_COPY_CLASS(wxEndHandler)
1353 };
1354
1355 #if wxUSE_STREAMS
1356
1357 class wxRedirectedIOHandler : public wxReadFDIOHandler
1358 {
1359 public:
1360 wxRedirectedIOHandler(wxFDIODispatcher& disp,
1361 int fd,
1362 wxStreamTempInputBuffer *buf)
1363 : wxReadFDIOHandler(disp, fd),
1364 m_buf(buf)
1365 {
1366 }
1367
1368 virtual void OnReadWaiting()
1369 {
1370 m_buf->Update();
1371 }
1372
1373 private:
1374 wxStreamTempInputBuffer * const m_buf;
1375
1376 DECLARE_NO_COPY_CLASS(wxRedirectedIOHandler)
1377 };
1378
1379 #endif // wxUSE_STREAMS
1380
1381 int wxAppTraits::WaitForChild(wxExecuteData& execData)
1382 {
1383 if ( !(execData.flags & wxEXEC_SYNC) )
1384 {
1385 // asynchronous execution: just launch the process and return
1386 wxEndProcessData *endProcData = new wxEndProcessData;
1387 endProcData->process = execData.process;
1388 endProcData->pid = execData.pid;
1389 endProcData->tag = AddProcessCallback
1390 (
1391 endProcData,
1392 execData.GetEndProcReadFD()
1393 );
1394
1395 return execData.pid;
1396 }
1397
1398 #if wxUSE_STREAMS
1399 wxProcess * const process = execData.process;
1400 if ( process && process->IsRedirected() )
1401 {
1402 // we can't simply block waiting for the child to terminate as we would
1403 // dead lock if it writes more than the pipe buffer size (typically
1404 // 4KB) bytes of output -- it would then block waiting for us to read
1405 // the data while we'd block waiting for it to terminate
1406 //
1407 // so multiplex here waiting for any input from the child or closure of
1408 // the pipe used to indicate its termination
1409 wxSelectDispatcher disp;
1410
1411 wxEndHandler endHandler(disp, execData.GetEndProcReadFD());
1412
1413 wxRedirectedIOHandler outHandler(disp, execData.fdOut, execData.bufOut),
1414 errHandler(disp, execData.fdErr, execData.bufErr);
1415
1416 while ( !endHandler.Terminated() )
1417 {
1418 disp.Dispatch();
1419 }
1420 }
1421 //else: no IO redirection, just block waiting for the child to exit
1422 #endif // wxUSE_STREAMS
1423
1424 int status = 0;
1425
1426 int result = waitpid(execData.pid, &status, 0);
1427 #ifdef __DARWIN__
1428 /* DE: waitpid manpage states that waitpid can fail with EINTR
1429 if the call is interrupted by a caught signal. I suppose
1430 that means that this ought to be a while loop.
1431
1432 The odd thing is that it seems to fail EVERY time. It fails
1433 with a quickly exiting process (e.g. echo), and fails with a
1434 slowly exiting process (e.g. sleep 2) but clearly after
1435 having waited for the child to exit. Maybe it's a bug in
1436 my particular version.
1437
1438 It works, however, from the CFSocket callback without this
1439 trick but in that case it's used only after CFSocket calls
1440 the callback and with the WNOHANG flag which would seem to
1441 preclude it from being interrupted or at least make it much
1442 less likely since it would not then be waiting.
1443
1444 If Darwin's man page is to be believed then this is definitely
1445 necessary. It's just weird that I've never seen it before
1446 and apparently no one else has either or you'd think they'd
1447 have reported it by now. Perhaps blocking the GUI while
1448 waiting for a child process to exit is simply not that common.
1449 */
1450 if ( result == -1 && errno == EINTR )
1451 {
1452 result = waitpid(execData.pid, &status, 0);
1453 }
1454 #endif // __DARWIN__
1455
1456 if ( result == -1 )
1457 {
1458 wxLogLastError("waitpid");
1459 }
1460 else // child terminated
1461 {
1462 wxASSERT_MSG( result == execData.pid,
1463 "unexpected waitpid() return value" );
1464
1465 if ( WIFEXITED(status) )
1466 {
1467 return WEXITSTATUS(status);
1468 }
1469 else // abnormal termination?
1470 {
1471 wxASSERT_MSG( WIFSIGNALED(status),
1472 "unexpected child wait status" );
1473 }
1474 }
1475
1476 wxLogSysError(_("Waiting for subprocess termination failed"));
1477
1478 return -1;
1479 }
1480
1481 void wxHandleProcessTermination(wxEndProcessData *proc_data)
1482 {
1483 // notify user about termination if required
1484 if ( proc_data->process )
1485 {
1486 proc_data->process->OnTerminate(proc_data->pid, proc_data->exitcode);
1487 }
1488
1489 // clean up
1490 if ( proc_data->pid > 0 )
1491 {
1492 // async execution
1493 delete proc_data;
1494 }
1495 else // sync execution
1496 {
1497 // let wxExecute() know that the process has terminated
1498 proc_data->pid = 0;
1499 }
1500 }
1501