]>
git.saurik.com Git - wxWidgets.git/blob - src/msdos/utilsdos.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msdos/utils.cpp 
   3 // Purpose:     DOS implementations of utility functions 
   4 // Author:      Vaclav Slavik, M.J.Wetherell 
   6 // Copyright:   (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) 
   7 //              (c) 2005 M.J.Wetherell 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // For compilers that support precompilation, includes "wx.h". 
  12 #include "wx/wxprec.h" 
  21     #include "wx/string.h" 
  27 #include "wx/apptrait.h" 
  28 #include "wx/process.h" 
  29 #include "wx/confbase.h"        // for wxExpandEnvVars() 
  30 #include "wx/cmdline.h" 
  31 #include "wx/filename.h" 
  32 #include "wx/wfstream.h" 
  37 #include <sys/types.h> 
  44 //---------------------------------------------------------------------------- 
  46 //---------------------------------------------------------------------------- 
  48 void wxSleep(int nSecs
) 
  50     wxMilliSleep(1000 * nSecs
); 
  53 void wxMilliSleep(unsigned long milliseconds
) 
  55 #if HAVE_USLEEP || defined __DJGPP__ 
  56     usleep(milliseconds 
* 1000); 
  57 #elif defined __WATCOMC__ 
  60     clock_t start 
= clock(); 
  61     while ((clock() - start
) * 1000 / CLOCKS_PER_SEC 
< (clock_t)milliseconds
) 
  63         // yield if in a multitasking environment 
  64         // "Release Current Virtual Machine's Time Slice" in DPMI 1.0 
  66         memset(&r
, 0, sizeof(r
)); 
  73 void wxMicroSleep(unsigned long microseconds
) 
  75 #if HAVE_USLEEP || defined __DJGPP__ 
  78     wxMilliSleep(microseconds
/1000); 
  82 //---------------------------------------------------------------------------- 
  83 // Get/Set environment variables 
  84 //---------------------------------------------------------------------------- 
  86 bool wxGetEnv(const wxString
& var
, wxString 
*value
) 
  88     // wxGetenv is defined as getenv() 
  89     wxChar 
*p 
= wxGetenv(var
); 
  99 static bool wxDoSetEnv(const wxString
& variable
, const char *value
) 
 101     wxString s 
= variable
; 
 103         s 
<< _T('=') << value
; 
 106     const char *p 
= s
.mb_str(); 
 108     // the string will be free()d by libc 
 109     char *buf 
= (char *)malloc(strlen(p
) + 1); 
 112     return putenv(buf
) == 0; 
 115 bool wxSetEnv(const wxString
& variable
, const wxString
& value
) 
 117     return wxDoSetEnv(variable
, value
.mb_str()); 
 120 bool wxUnsetEnv(const wxString
& variable
) 
 122     return wxDoSetEnv(variable
, NULL
); 
 126 //---------------------------------------------------------------------------- 
 127 // Hostname, username, home directory 
 128 //---------------------------------------------------------------------------- 
 130 // Based on the MSW implementation 
 132 // Respects the following environment variables in this order: %HomeDrive% + 
 133 // %HomePath%, %UserProfile%, $HOME. Otherwise takes program's directory if 
 134 // wxApp has been initialised, otherwise returns ".". 
 136 const wxChar
* wxGetHomeDir(wxString 
*home
) 
 138     wxString
& strDir 
= *home
; 
 142     // try HOMEDRIVE/PATH 
 143     const wxChar 
*szHome 
= wxGetenv(wxT("HOMEDRIVE")); 
 144     if ( szHome 
!= NULL 
) 
 146     szHome 
= wxGetenv(wxT("HOMEPATH")); 
 148     if ( szHome 
!= NULL 
) 
 152         // the idea is that under NT these variables have default values of 
 153         // "%systemdrive%:" and "\\". As we don't want to create our config 
 154         // files in the root directory of the system drive, we will create it 
 155         // in our program's dir. However, if the user took care to set 
 156         // HOMEPATH to something other than "\\", we suppose that he knows 
 157         // what he is doing and use the supplied value. 
 158         if ( wxStrcmp(szHome
, wxT("\\")) == 0 ) 
 162     if ( strDir
.empty() ) 
 164         // If we have a valid USERPROFILE directory, as is the case in 
 165         // Windows NT, 2000 and XP, we should use that as our home directory. 
 166         szHome 
= wxGetenv(wxT("USERPROFILE")); 
 168         if ( szHome 
!= NULL 
) 
 172     if ( strDir
.empty() ) 
 174         // If we have a valid HOME directory, as is used on many machines 
 175         // that have unix utilities on them, we should use that. 
 176         szHome 
= wxGetenv(wxT("HOME")); 
 178         if ( szHome 
!= NULL 
) 
 181             // when msys sets %HOME% it uses '/' (cygwin uses '\\') 
 182             strDir
.Replace(_T("/"), _T("\\")); 
 186     if ( !strDir
.empty() ) 
 188         // sometimes the value of HOME may be "%USERPROFILE%", so reexpand the 
 189         // value once again, it shouldn't hurt anyhow 
 190         strDir 
= wxExpandEnvVars(strDir
); 
 192     else // fall back to the program directory 
 196             wxString 
prog(wxTheApp
->argv
[0]); 
 198             // djgpp startup code switches the slashes around, so restore them 
 199             prog
.Replace(_T("/"), _T("\\")); 
 201             // it needs to be a full path to be usable 
 202             if ( prog
.compare(1, 2, _T(":\\")) == 0 ) 
 203                 wxFileName::SplitPath(prog
, &strDir
, NULL
, NULL
); 
 205         if ( strDir
.empty() ) 
 211     return strDir
.c_str(); 
 214 wxString 
wxGetUserHome(const wxString
& user
) 
 218     if (user
.empty() || user 
== wxGetUserId()) 
 224 // returns %UserName%, $USER or just "user" 
 226 bool wxGetUserId(wxChar 
*buf
, int n
) 
 228     const wxChar 
*user 
= wxGetenv(_T("UserName")); 
 231         user 
= wxGetenv(_T("USER")); 
 236     wxStrlcpy(buf
, user
, n
); 
 240 bool wxGetUserName(wxChar 
*buf
, int n
) 
 242     return wxGetUserId(buf
, n
); 
 245 // returns %ComputerName%, or $HOSTNAME, or "host" 
 247 bool wxGetHostName(wxChar 
*buf
, int n
) 
 249     const wxChar 
*host 
= wxGetenv(_T("ComputerName")); 
 252         host 
= wxGetenv(_T("HOSTNAME")); 
 257     wxStrlcpy(buf
, host
, n
); 
 261 // adds %UserDnsDomain% to wxGetHostName() 
 263 bool wxGetFullHostName(wxChar 
*buf
, int n
) 
 265     wxGetHostName(buf
, n
); 
 267     const wxChar 
*domain 
= wxGetenv(_T("UserDnsDomain")); 
 270         wxStrncat(wxStrncat(buf
, _T("."), n
), domain
, n
); 
 275 //---------------------------------------------------------------------------- 
 277 //---------------------------------------------------------------------------- 
 279 unsigned long wxGetProcessId() 
 281     return (unsigned long)getpid(); 
 284 int wxKill(long pid
, wxSignal sig
, wxKillError 
*rc
, int WXUNUSED(flags
)) 
 288     if (pid 
!= (long)wxGetProcessId()) 
 292             *rc 
= result 
== 0 ? wxKILL_OK 
: wxKILL_BAD_SIGNAL
; 
 296         wxLogDebug(_T("wxKill can only send signals to the current process under MSDOS")); 
 298             *rc 
= wxKILL_NO_PROCESS
; 
 304 bool wxShell(const wxString
& command 
/*=wxEmptyString*/) 
 306     // FIXME: suspend/resume gui 
 307     int result 
= system(command
); 
 310         wxLogSysError(_("can't execute '%s'"), command
.c_str()); 
 315 long wxExecute(const wxString
& command
, int flags
, wxProcess 
*process
) 
 317     // FIXME: shouldn't depend on wxCmdLineParser 
 318     wxArrayString 
args(wxCmdLineParser::ConvertStringToArgs(command
)); 
 319     size_t n 
= args
.size(); 
 320     wxChar 
**argv 
= new wxChar
*[n 
+ 1]; 
 324         argv
[n
] = const_cast<wxChar
*>((const char *)args
[n
].c_str()); 
 326     long result 
= wxExecute(argv
, flags
, process
); 
 334 // A wxFFileInputStream that deletes the file in it's destructor 
 336 class wxTempFileInStream 
: public wxFFileInputStream
 
 339     wxTempFileInStream(const wxString
& name
) 
 340         : wxFFileInputStream(name
, _T("rt")) 
 343     virtual ~wxTempFileInStream() 
 346         wxRemoveFile(m_file
->GetName()); 
 350 // A file descriptor that can be redirected to a file 
 352 class wxRedirectableFd
 
 355     wxRedirectableFd(int fd
) : m_fd(fd
), m_dup(-1) { } 
 358     // Redirect the descriptor to a file, similar to ANSI C's freopen, but 
 359     // for low level descriptors. The desctructor un-redirects. If O_CREAT 
 360     // is in the flags then the destructor will delete the file unless it is 
 361     // given away with Release(). 
 362     bool Reopen(const wxString
& name
, int flags
); 
 364     // un-redirect the redirected file descriptor, closing the file, and give 
 365     // away the filename without deleting it 
 369     // un-redirect the descriptor, closing the file 
 377 wxRedirectableFd::~wxRedirectableFd() 
 381         wxRemoveFile(m_name
); 
 384 bool wxRedirectableFd::Reopen(const wxString
& name
, int flags
) 
 386     wxASSERT(m_dup 
== -1); 
 389     // save a duplicate so that the descriptor can be closed now and 
 395         int tmp 
= open(name
.mb_str(), flags
); 
 404             result 
= dup2(tmp
, m_fd
) == m_fd
; 
 410         wxLogSysError(_("error opening '%s'"), name
.c_str()); 
 415 void wxRedirectableFd::Restore() 
 426 wxString 
wxRedirectableFd::Release() 
 429     wxString name 
= m_name
; 
 434 #endif // wxUSE_STREAMS 
 436 // wxExecute implementation 
 438 long wxExecute(wxChar 
**argv
, int flags
, wxProcess 
*process
) 
 442     const int STDOUT 
= 1; 
 443     const int STDERR 
= 2; 
 445     wxRedirectableFd 
in(STDIN
), out(STDOUT
), err(STDERR
); 
 446     bool redirect 
= process 
&& process
->IsRedirected() && (flags 
& wxEXEC_SYNC
); 
 450         // close stdin/out/err and reopen them as files 
 451         if (!in
.Reopen(_T("NUL"), O_RDONLY 
| O_TEXT
)) 
 454         if (!out
.Reopen(wxFileName::CreateTempFileName(_T("out")), 
 455                         O_CREAT 
| O_WRONLY 
| O_TRUNC 
| O_TEXT
)) 
 458         if (!err
.Reopen(wxFileName::CreateTempFileName(_T("err")), 
 459                         O_CREAT 
| O_WRONLY 
| O_TRUNC 
| O_TEXT
)) 
 462 #endif // wxUSE_STREAMS 
 464     // FIXME: suspend/resume gui 
 465     int mode 
= flags 
& wxEXEC_SYNC 
? P_WAIT 
: P_NOWAIT
; 
 466     int result 
= spawnvp(mode
, argv
[0], argv
); 
 469         wxLogSysError(_("can't execute '%s'"), argv
[0]); 
 473         process
->SetPipeStreams(new wxTempFileInStream(out
.Release()), 
 474                                 new wxFFileOutputStream(_T("NUL"), _T("wt")), 
 475                                 new wxTempFileInStream(err
.Release())); 
 476 #endif // wxUSE_STREAMS 
 482 //---------------------------------------------------------------------------- 
 484 //---------------------------------------------------------------------------- 
 486 wxString 
wxGetOsDescription() 
 488     wxString 
osname(_T("DOS")); 
 492 wxOperatingSystemId 
wxGetOsVersion(int *verMaj
, int *verMin
) 
 502 bool wxIsPlatform64Bit()