1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
18 #include <OSD_Environment.hxx>
19 #include <OSD_OSDError.hxx>
20 #include <OSD_WhoAmI.hxx>
21 #include <Standard_ConstructionError.hxx>
22 #include <Standard_Failure.hxx>
23 #include <Standard_Mutex.hxx>
24 #include <Standard_NullObject.hxx>
25 #include <TCollection_AsciiString.hxx>
26 #include <NCollection_UtfString.hxx>
32 static const OSD_WhoAmI Iam = OSD_WEnvironment;
34 // ----------------------------------------------------------------------
36 // Updated by : JPT Dec,7 1992
37 // What : OSD_Environment::OSD_Environment
38 // (const TCollection_AsciiString& Name,
39 // const TCollection_AsciiString& Value)
40 // Value could contain the character $ (Ex setenv a = $c)
42 // ----------------------------------------------------------------------
45 OSD_Environment::OSD_Environment()
50 // ----------------------------------------------------------------------
52 // ----------------------------------------------------------------------
54 OSD_Environment::OSD_Environment(const TCollection_AsciiString& Name)
57 if (!Name.IsAscii() || Name.Search("$") != -1 )
58 Standard_ConstructionError::Raise("OSD_Environment::OSD_Environment: bad argument");
64 // ----------------------------------------------------------------------
65 // Create an environment variable and initialize it
66 // ----------------------------------------------------------------------
68 OSD_Environment::OSD_Environment(const TCollection_AsciiString& Name,
69 const TCollection_AsciiString& Value)
72 if (!Name.IsAscii() || !Value.IsAscii() ||
73 // JPT : Dec-7-1992 Name.Search("$") != -1 || Value.Search("$") != -1)
74 Name.Search("$") != -1 )
75 Standard_ConstructionError::Raise("OSD_Environment::OSD_Environment: bad argument");
82 // ----------------------------------------------------------------------
83 // Returns the name of the symbol
84 // ----------------------------------------------------------------------
86 TCollection_AsciiString OSD_Environment::Name () const
91 // ----------------------------------------------------------------------
92 // Set new value for environment variable
93 // ----------------------------------------------------------------------
95 void OSD_Environment::SetName (const TCollection_AsciiString& Name)
98 if (!Name.IsAscii() || Name.Search("$") != -1 )
99 Standard_ConstructionError::Raise("OSD_Environment::SetName: bad argument");
104 // ----------------------------------------------------------------------
106 // ----------------------------------------------------------------------
108 void OSD_Environment::SetValue (const TCollection_AsciiString& Value)
110 if (!Value.IsAscii() || Value.Search("$") != -1)
111 Standard_ConstructionError::Raise("OSD_Environment::Change: bad argument");
116 // ----------------------------------------------------------------------
117 // Get environment variable physically
118 // ----------------------------------------------------------------------
120 TCollection_AsciiString OSD_Environment::Value()
122 char *result = getenv(myName.ToCString());
123 if (result == NULL) myValue.Clear();
124 else myValue = result;
128 // ----------------------------------------------------------------------
129 // Sets physically the environment variable
130 // ----------------------------------------------------------------------
132 void OSD_Environment::Build ()
134 // Static buffer to hold definitions of new variables for the environment.
135 // Note that they need to be static since putenv does not make a copy
136 // of the string, but just adds its pointer to the environment.
137 static char **buffer = 0 ; // JPT:
138 static int Ibuffer = 0 ; // Tout ca pour putenv,getenv
140 // Use mutex to avoid concurrent access to the buffer
141 static Standard_Mutex theMutex;
142 Standard_Mutex::Sentry aSentry ( theMutex );
144 // check if such variable has already been created in the buffer
145 int index = -1, len = myName.Length();
146 for ( int i=0; i < Ibuffer; i++ ) {
147 if ( ! strncmp ( buffer[i], myName.ToCString(), len ) && buffer[i][len] == '=' ) {
153 // and either add a new entry, or remember the old entry for a while
156 old_value = buffer[index];
159 // Allocation memoire. Surtout tout la heap!
162 aTmp = (char **) realloc ( buffer, Ibuffer * sizeof(char*) );
169 myError.SetValue(errno, Iam, "Memory realloc failure");
174 // create a new entry in the buffer and add it to environment
175 buffer[index] = (char *) malloc ( len + myValue.Length() + 2 );
176 sprintf(buffer[index], "%s=%s", myName.ToCString(), myValue.ToCString());
177 putenv(buffer[index]);
179 // then (and only then!) free old entry, if existed
184 char *result = getenv(myName.ToCString());
186 myError.SetValue(errno, Iam, "Set Environment");
189 // ----------------------------------------------------------------------
190 // Remove physically the environment variable
191 // ----------------------------------------------------------------------
193 void OSD_Environment::Remove ()
201 // ----------------------------------------------------------------------
202 // ----------------------------------------------------------------------
203 void OSD_Environment::Reset()
208 // ----------------------------------------------------------------------
209 // ----------------------------------------------------------------------
210 Standard_Boolean OSD_Environment::Failed() const
212 return myError.Failed();
215 // ----------------------------------------------------------------------
216 // ----------------------------------------------------------------------
217 void OSD_Environment::Perror()
223 // ----------------------------------------------------------------------
224 // ----------------------------------------------------------------------
225 Standard_Integer OSD_Environment::Error() const
227 return myError.Error();
232 //------------------------------------------------------------------------
233 //------------------- WNT Sources of OSD_Environment --------------------
234 //------------------------------------------------------------------------
237 #include <OSD_Environment.hxx>
239 #include <OSD_WNT.hxx>
243 #include <NCollection_UtfString.hxx>
245 #if defined(_MSC_VER)
246 #pragma warning( disable : 4700 )
250 static void __fastcall _set_error ( OSD_Error&, DWORD );
253 OSD_Environment :: OSD_Environment () {
255 } // end constructor ( 1 )
257 OSD_Environment :: OSD_Environment ( const TCollection_AsciiString& Name ) {
261 } // end constructor ( 2 )
263 OSD_Environment :: OSD_Environment (
264 const TCollection_AsciiString& Name,
265 const TCollection_AsciiString& Value
271 } // end constructor ( 3 )
273 void OSD_Environment :: SetValue ( const TCollection_AsciiString& Value ) {
277 } // end OSD_Environment :: SetValue
279 TCollection_AsciiString OSD_Environment::Value()
284 SetLastError (ERROR_SUCCESS);
285 wchar_t* anEnvVal = NULL;
286 NCollection_UtfWideString aNameWide (myName.ToCString());
287 DWORD aSize = GetEnvironmentVariableW (aNameWide.ToCString(), NULL, 0);
288 if ((aSize == 0 && GetLastError() != ERROR_SUCCESS)
289 || (anEnvVal = _wgetenv (aNameWide.ToCString())) == NULL)
291 _set_error (myError, ERROR_ENVVAR_NOT_FOUND);
295 NCollection_Utf8String aValue;
296 if (anEnvVal != NULL)
298 aValue.FromUnicode (anEnvVal);
302 aSize += 1; // NULL-terminator
303 wchar_t* aBuff = new wchar_t[aSize];
304 GetEnvironmentVariableW (aNameWide.ToCString(), aBuff, aSize);
305 aBuff[aSize - 1] = L'\0';
306 aValue.FromUnicode (aBuff);
310 myValue = aValue.ToCString();
318 void OSD_Environment :: SetName ( const TCollection_AsciiString& name ) {
322 } // end OSD_Environment :: SetName
324 TCollection_AsciiString OSD_Environment :: Name () const {
328 } // end OSD_Environment :: Name
330 void OSD_Environment::Build()
333 NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=" + myValue.ToCString();
334 _wputenv (aSetVariable.ToUtfWide().ToCString());
338 void OSD_Environment::Remove()
341 NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=";
342 _wputenv (aSetVariable.ToUtfWide().ToCString());
346 Standard_Boolean OSD_Environment :: Failed () const {
348 return myError.Failed ();
350 } // end OSD_Environment :: Failed
352 void OSD_Environment :: Reset () {
356 } // end OSD_Environment :: Reset
358 void OSD_Environment :: Perror ()
361 } // end OSD_Environment :: Perror
363 Standard_Integer OSD_Environment :: Error () const {
365 return myError.Error ();
367 } // end OSD_Environment :: Error
370 static void __fastcall _set_error ( OSD_Error& err, DWORD code ) {
373 Standard_Character buffer[ 2048 ];
375 errCode = code ? code : GetLastError ();
377 if ( !FormatMessage (
378 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
379 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
384 sprintf ( buffer, "error code %d", (Standard_Integer)errCode );
385 SetLastError ( errCode );
389 err.SetValue ( errCode, OSD_WEnvironment, buffer );