00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018
00019 #if defined(_WIN32) || defined(_WIN64)
00020 #include <spl/configwin32.h>
00021 #include <spl/cleanwindows.h>
00022 #else
00023 #include <spl/autoconf/config.h>
00024 #endif
00025
00026 #include <spl/types.h>
00027 #include <spl/Debug.h>
00028
00029 #ifdef HAVE_SYS_TYPES_H
00030 #include <sys/types.h>
00031 #endif
00032 #ifdef HAVE_PWD_H
00033 #include <pwd.h>
00034 #endif
00035 #ifdef HAVE_SYS_UTSNAME_H
00036 #include <sys/utsname.h>
00037 #endif
00038 #ifdef HAVE_ERRNO_H
00039 #include <errno.h>
00040 #endif
00041 #ifdef HAVE_FCNTL_H
00042 #include <fcntl.h>
00043 #endif
00044 #ifdef HAVE_IO_H
00045 #include <io.h>
00046 #endif
00047 #ifdef HAVE_DIRECT_H
00048 #include <direct.h>
00049 #endif
00050 #ifdef HAVE_DIRENT_H
00051 #include <dirent.h>
00052 #endif
00053 #ifdef HAVE_SYS_STAT_H
00054 #include <sys/stat.h>
00055 #endif
00056 #ifdef HAVE_UNISTD_H
00057 #include <unistd.h>
00058 #endif
00059 #ifdef HAVE_STRING_H
00060 #include <string.h>
00061 #endif
00062 #ifdef HAVE_SYS_VFS_H
00063 #include <sys/vfs.h>
00064 #endif
00065
00066 #include <spl/Char.h>
00067 #include <spl/io/Directory.h>
00068 #include <spl/Environment.h>
00069 #include <spl/io/File.h>
00070 #include <spl/Int32.h>
00071 #include <spl/text/Regex.h>
00072
00073 String Environment::NewLine()
00074 {
00075 #ifdef _WINDOWS
00076 return "\r\n";
00077 #elif defined(_MACOS)
00078 return "\r";
00079 #else
00080 return "\n";
00081 #endif
00082 }
00083
00084 String Environment::ProcessName()
00085 {
00086 #ifdef _WINDOWS
00087 char path[512] = { 0 };
00088
00089 if (!GetModuleFileName(NULL, path, sizeof(path)) || !path[0])
00090 {
00091 return "unknown";
00092 }
00093 String fullName(path);
00094 return *fullName.Substring(fullName.LastIndexOf('\\')+1);
00095 #else
00096 pid_t pid = getpid();
00097 StringPtr spid(Int32::ToString((int)pid));
00098 String path = "/proc/" + *spid + "/execname";
00099 if (!File::Exists(path))
00100 {
00101 return "unknown";
00102 }
00103 TextReaderPtr reader = File::ReadText(path);
00104 StringPtr execname = reader->ReadLine();
00105 reader->Close();
00106 return *execname->Substring(execname->LastIndexOf('/')+1);
00107 #endif
00108 }
00109
00110 String Environment::GetVariable(const String& name)
00111 {
00112 #ifdef _WINDOWS
00113 DWORD len = ::GetEnvironmentVariable(name.GetChars(), NULL, 0);
00114 if(len == 0)
00115 {
00116 return String();
00117 }
00118
00119 char *buf = new char[len];
00120
00121 len = ::GetEnvironmentVariable(name.GetChars(), buf, len);
00122
00123 String val(buf);
00124 delete [] buf;
00125 return val;
00126
00127 #else
00128
00129 String val = ::getenv(name.GetChars());
00130 return(val);
00131
00132 #endif
00133 }
00134
00135 void Environment::SetVariable(const String& name, const String& value)
00136 {
00137 if(name.IndexOf('=') > -1)
00138 {
00139 return;
00140 }
00141
00142 #ifdef _WINDOWS
00143
00144 ::SetEnvironmentVariable(name.GetChars(), value.GetChars());
00145
00146 #else
00147
00148 ::setenv(name.GetChars(), value.GetChars(), 1);
00149
00150 #endif
00151 }
00152
00153 String Environment::UserName()
00154 {
00155 #ifdef _WINDOWS
00156 char ubuf[256];
00157
00158 DWORD size = (DWORD)sizeof(ubuf);
00159 if(::GetUserName(ubuf, &size) != TRUE)
00160 {
00161 throw new Exception("GetUserName error");
00162 }
00163 return String(ubuf);
00164 #else
00165 passwd *pw = getpwuid(geteuid());
00166 if(! pw)
00167 {
00168 throw new Exception("getpwuid error");
00169 }
00170 return String(pw->pw_name);
00171 #endif
00172 }
00173
00174 Vector<StringPtr> Environment::GetLogicalDrives(bool localOnly)
00175 {
00176 Vector<StringPtr> drives;
00177
00178 #ifdef _WINDOWS
00179
00180 DWORD mask = ::GetLogicalDrives();
00181
00182 for(int i = 0; i < 26; i++)
00183 {
00184 if(mask & 0x01)
00185 {
00186 char path[4];
00187
00188 sprintf(path, "%c:\\", 'A' + i);
00189
00190 if(! localOnly || (::GetDriveType(path) == DRIVE_FIXED))
00191 {
00192 drives.Add( StringPtr(new String((const char *)path)) );
00193 }
00194 }
00195
00196 mask >>= 1;
00197 }
00198
00199 #else
00200
00201 drives.Add(StringPtr(new String("/")));
00202
00203 #endif
00204
00205 return drives;
00206 }
00207
00208 String Environment::HostName()
00209 {
00210 #ifdef _WINDOWS
00211 char hbuf[MAX_COMPUTERNAME_LENGTH + 1];
00212
00213 DWORD size = (DWORD)sizeof(hbuf);
00214 if(::GetComputerName(hbuf, &size) != TRUE)
00215 {
00216 throw new Exception("GetComputerName error");
00217 }
00218 return String(hbuf);
00219 #else
00220 struct utsname uts;
00221 uname(&uts);
00222 return String(uts.nodename);
00223 #endif
00224 }
00225
00226 String Environment::HostArchitecture()
00227 {
00228 #ifdef _WINDOWS
00229 SYSTEM_INFO sys_info;
00230
00231 ::GetSystemInfo(&sys_info);
00232
00233 switch(sys_info.dwProcessorType)
00234 {
00235 case PROCESSOR_INTEL_386:
00236 case PROCESSOR_INTEL_486:
00237 case PROCESSOR_INTEL_PENTIUM:
00238 return String("x86");
00239
00240 case 2200:
00241 return String("ia64");
00242
00243 #ifdef PROCESSOR_AMD_X8664
00244 case PROCESSOR_AMD_X8664:
00245 return String("amd8664");
00246 #endif
00247
00248 default:
00249 return String("unknown");
00250 }
00251
00252 #else
00253 struct utsname uts;
00254 uname(&uts);
00255 return String(uts.machine);
00256 #endif
00257 }
00258
00259 String Environment::OSName()
00260 {
00261 #ifdef _WINDOWS
00262 return String("Windows");
00263 #else
00264 struct utsname uts;
00265 uname(&uts);
00266
00267 return String(uts.sysname);
00268 #endif
00269 }
00270
00271 String Environment::OSVersion()
00272 {
00273 #ifdef _WINDOWS
00274 OSVERSIONINFO os_info;
00275
00276 os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00277 ::GetVersionEx(&os_info);
00278
00279 switch(os_info.dwMajorVersion)
00280 {
00281 case 4:
00282 switch(os_info.dwMinorVersion)
00283 {
00284 case 0:
00285 if(os_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
00286 return String("NT 4.0");
00287 else
00288 return String("95");
00289 break;
00290
00291 case 10:
00292 return String("98");
00293
00294 case 90:
00295 return String("ME");
00296
00297 default:
00298 return String("unknown");
00299 }
00300 break;
00301
00302 case 5:
00303 switch(os_info.dwMinorVersion)
00304 {
00305 case 0:
00306 return String("2000");
00307
00308 case 1:
00309 return String("XP");
00310
00311 case 2:
00312 return String("Server 2003");
00313
00314 default:
00315 return String("unknown");
00316 }
00317 break;
00318
00319 case 6:
00320 return String("Vista");
00321
00322 case 7:
00323 return String("7");
00324
00325 default:
00326 return String("unknown");
00327 }
00328 #else
00329 struct utsname uts;
00330 uname(&uts);
00331 return String(uts.release);
00332 #endif
00333 }
00334
00335 String Environment::HomeDirectory()
00336 {
00337 #ifdef _WINDOWS
00338 return String(Environment::GetVariable("USERPROFILE"));
00339 #else
00340 passwd *pw = getpwuid(geteuid());
00341 if(! pw)
00342 {
00343 throw new Exception("getpwuid error");
00344 }
00345 return String(pw->pw_dir);
00346 #endif
00347 }
00348
00349 String Environment::TempDirectory()
00350 {
00351 #ifdef _WINDOWS
00352 DWORD tmpLen = ::GetTempPath(0, NULL);
00353 char *buf = new char[tmpLen];
00354 ::GetTempPath(tmpLen, buf);
00355 String path(buf);
00356 delete [] buf;
00357 return path;
00358 #else
00359 const char *tmpEnv = getenv("TMPDIR");
00360 if (NULL != tmpEnv)
00361 {
00362 return String(tmpEnv);
00363 }
00364 tmpEnv = getenv("TMP");
00365 if (NULL == tmpEnv)
00366 {
00367 char *tpath = tempnam(NULL, NULL);
00368 if (NULL != tpath)
00369 {
00370 String ret(tpath);
00371 realfree(tpath);
00372 return ret;
00373 }
00374 }
00375 String dir = HomeDirectory() + *Char::ToString(Directory::SeperatorChar()) + "tmp";
00376 if (!Directory::IsDirectory(dir))
00377 {
00378 Directory::Create(dir);
00379 }
00380 return dir;
00381 #endif
00382 }
00383
00384 uint64 Environment::DiskFreeSpace()
00385 {
00386 #ifdef _WINDOWS
00387
00388 ULARGE_INTEGER x, avail;
00389
00390 if(::GetDiskFreeSpaceEx("\\", &x, &x, &avail) == FALSE)
00391 return 0;
00392
00393 return (uint64)avail.QuadPart;
00394
00395 #else
00396
00397 struct statfs buf;
00398 if(::statfs("/", &buf) != 0)
00399 return 0;
00400
00401 return (uint64)(buf.f_bavail) * 1024;
00402
00403 #endif
00404 }
00405
00406 int Environment::LastError()
00407 {
00408 #ifdef _WINDOWS
00409 return GetLastError();
00410 #else
00411 return errno;
00412 #endif
00413 }
00414
00415 String Environment::LastErrorMessage()
00416 {
00417 #ifdef _WINDOWS
00418 void *buf = NULL;
00419 ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
00420 FORMAT_MESSAGE_FROM_SYSTEM |
00421 FORMAT_MESSAGE_IGNORE_INSERTS,
00422 NULL,GetLastError(),0,
00423 (LPTSTR) &buf,0,NULL);
00424 String ret((char *)buf);
00425
00426
00427 ::LocalFree(buf);
00428
00429 return ret;
00430 #else
00431 char buf[256];
00432 buf[0] = '\0';
00433 #ifdef HAVE_STRERROR_R
00434 strerror_r(errno, buf, 256);
00435 if ('\0' == buf[0])
00436 {
00437 return *(String::Format("Error number %d", errno));
00438 }
00439 return String(buf);
00440 #else
00441 return String(strerror(errno));
00442 #endif
00443 #endif
00444 }
00445
00446 int Environment::ProcessorCount()
00447 {
00448 #ifdef _WINDOWS
00449 SYSTEM_INFO si;
00450 ::GetSystemInfo(&si);
00451 return si.dwNumberOfProcessors;
00452 #else
00453 const char *procCpuInfo = "/proc/cpuinfo";
00454 if (File::Exists(procCpuInfo))
00455 {
00456 Regex regex("^processor", RegexOptions::MULTILINE);
00457 StringPtr cpuinfo = File::LoadText(procCpuInfo);
00458 if (cpuinfo.IsNull())
00459 {
00460 return 1;
00461 }
00462 RefCountPtr<Array<StringPtr> > matches = regex.Matches(cpuinfo);
00463 return matches->Count();
00464 }
00465 return 1;
00466 #endif
00467 }
00468