// Copyright (c) 1998-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _WIN32 #include <OSD_Environment.hxx> #include <OSD_OSDError.hxx> #include <OSD_WhoAmI.hxx> #include <Standard_ConstructionError.hxx> #include <Standard_Failure.hxx> #include <Standard_Mutex.hxx> #include <Standard_NullObject.hxx> #include <TCollection_AsciiString.hxx> #include <NCollection_UtfString.hxx> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static const OSD_WhoAmI Iam = OSD_WEnvironment; // ---------------------------------------------------------------------- // // Updated by : JPT Dec,7 1992 // What : OSD_Environment::OSD_Environment // (const TCollection_AsciiString& Name, // const TCollection_AsciiString& Value) // Value could contain the character $ (Ex setenv a = $c) // // ---------------------------------------------------------------------- // Create object OSD_Environment::OSD_Environment() { } // ---------------------------------------------------------------------- // Constructor // ---------------------------------------------------------------------- OSD_Environment::OSD_Environment(const TCollection_AsciiString& Name) { if (!Name.IsAscii() || Name.Search("$") != -1 ) Standard_ConstructionError::Raise("OSD_Environment::OSD_Environment: bad argument"); myName = Name; } // ---------------------------------------------------------------------- // Create an environment variable and initialize it // ---------------------------------------------------------------------- OSD_Environment::OSD_Environment(const TCollection_AsciiString& Name, const TCollection_AsciiString& Value) { if (!Name.IsAscii() || !Value.IsAscii() || // JPT : Dec-7-1992 Name.Search("$") != -1 || Value.Search("$") != -1) Name.Search("$") != -1 ) Standard_ConstructionError::Raise("OSD_Environment::OSD_Environment: bad argument"); myName = Name; myValue = Value; } // ---------------------------------------------------------------------- // Returns the name of the symbol // ---------------------------------------------------------------------- TCollection_AsciiString OSD_Environment::Name () const { return myName; } // ---------------------------------------------------------------------- // Set new value for environment variable // ---------------------------------------------------------------------- void OSD_Environment::SetName (const TCollection_AsciiString& Name) { myError.Reset(); if (!Name.IsAscii() || Name.Search("$") != -1 ) Standard_ConstructionError::Raise("OSD_Environment::SetName: bad argument"); myName = Name; } // ---------------------------------------------------------------------- // Change value // ---------------------------------------------------------------------- void OSD_Environment::SetValue (const TCollection_AsciiString& Value) { if (!Value.IsAscii() || Value.Search("$") != -1) Standard_ConstructionError::Raise("OSD_Environment::Change: bad argument"); myValue = Value; } // ---------------------------------------------------------------------- // Get environment variable physically // ---------------------------------------------------------------------- TCollection_AsciiString OSD_Environment::Value() { char *result = getenv(myName.ToCString()); if (result == NULL) myValue.Clear(); else myValue = result; return myValue; } // ---------------------------------------------------------------------- // Sets physically the environment variable // ---------------------------------------------------------------------- void OSD_Environment::Build () { // Static buffer to hold definitions of new variables for the environment. // Note that they need to be static since putenv does not make a copy // of the string, but just adds its pointer to the environment. static char **buffer = 0 ; // JPT: static int Ibuffer = 0 ; // Tout ca pour putenv,getenv // Use mutex to avoid concurrent access to the buffer static Standard_Mutex theMutex; Standard_Mutex::Sentry aSentry ( theMutex ); // check if such variable has already been created in the buffer int index = -1, len = myName.Length(); for ( int i=0; i < Ibuffer; i++ ) { if ( ! strncmp ( buffer[i], myName.ToCString(), len ) && buffer[i][len] == '=' ) { index = i; break; } } // and either add a new entry, or remember the old entry for a while char *old_value = 0; if ( index >=0 ) { old_value = buffer[index]; } else { // Allocation memoire. Surtout tout la heap! index = Ibuffer++; char **aTmp; aTmp = (char **) realloc ( buffer, Ibuffer * sizeof(char*) ); if (aTmp) { buffer = aTmp; } else { myError.SetValue(errno, Iam, "Memory realloc failure"); return; } } // create a new entry in the buffer and add it to environment buffer[index] = (char *) malloc ( len + myValue.Length() + 2 ); sprintf(buffer[index], "%s=%s", myName.ToCString(), myValue.ToCString()); putenv(buffer[index]); // then (and only then!) free old entry, if existed if ( old_value ) free ( old_value ); // check the result char *result = getenv(myName.ToCString()); if (result == NULL) myError.SetValue(errno, Iam, "Set Environment"); } // ---------------------------------------------------------------------- // Remove physically the environment variable // ---------------------------------------------------------------------- void OSD_Environment::Remove () { myValue.Clear(); Build(); } // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- void OSD_Environment::Reset() { myError.Reset(); } // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- Standard_Boolean OSD_Environment::Failed() const { return myError.Failed(); } // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- void OSD_Environment::Perror() { myError.Perror(); } // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- Standard_Integer OSD_Environment::Error() const { return myError.Error(); } #else //------------------------------------------------------------------------ //------------------- WNT Sources of OSD_Environment -------------------- //------------------------------------------------------------------------ #define STRICT #include <OSD_Environment.hxx> #include <OSD_WNT.hxx> #include <windows.h> #include <NCollection_UtfString.hxx> #if defined(_MSC_VER) #pragma warning( disable : 4700 ) #endif static void __fastcall _set_error ( OSD_Error&, DWORD ); OSD_Environment :: OSD_Environment () { } // end constructor ( 1 ) OSD_Environment :: OSD_Environment ( const TCollection_AsciiString& Name ) { myName = Name; } // end constructor ( 2 ) OSD_Environment :: OSD_Environment ( const TCollection_AsciiString& Name, const TCollection_AsciiString& Value ) { myName = Name; myValue = Value; } // end constructor ( 3 ) void OSD_Environment :: SetValue ( const TCollection_AsciiString& Value ) { myValue = Value; } // end OSD_Environment :: SetValue TCollection_AsciiString OSD_Environment::Value() { myValue.Clear(); SetLastError (ERROR_SUCCESS); wchar_t* anEnvVal = NULL; NCollection_UtfWideString aNameWide (myName.ToCString()); DWORD aSize = GetEnvironmentVariableW (aNameWide.ToCString(), NULL, 0); if ((aSize == 0 && GetLastError() != ERROR_SUCCESS) || (anEnvVal = _wgetenv (aNameWide.ToCString())) == NULL) { _set_error (myError, ERROR_ENVVAR_NOT_FOUND); return myValue; } NCollection_Utf8String aValue; if (anEnvVal != NULL) { aValue.FromUnicode (anEnvVal); } else { aSize += 1; // NULL-terminator wchar_t* aBuff = new wchar_t[aSize]; GetEnvironmentVariableW (aNameWide.ToCString(), aBuff, aSize); aBuff[aSize - 1] = L'\0'; aValue.FromUnicode (aBuff); delete[] aBuff; Reset(); } myValue = aValue.ToCString(); return myValue; } void OSD_Environment :: SetName ( const TCollection_AsciiString& name ) { myName = name; } // end OSD_Environment :: SetName TCollection_AsciiString OSD_Environment :: Name () const { return myName; } // end OSD_Environment :: Name void OSD_Environment::Build() { NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "=" + myValue.ToCString(); _wputenv (aSetVariable.ToUtfWide().ToCString()); } void OSD_Environment::Remove() { NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "="; _wputenv (aSetVariable.ToUtfWide().ToCString()); } Standard_Boolean OSD_Environment :: Failed () const { return myError.Failed (); } // end OSD_Environment :: Failed void OSD_Environment :: Reset () { myError.Reset (); } // end OSD_Environment :: Reset void OSD_Environment :: Perror () { myError.Perror (); } // end OSD_Environment :: Perror Standard_Integer OSD_Environment :: Error () const { return myError.Error (); } // end OSD_Environment :: Error static void __fastcall _set_error ( OSD_Error& err, DWORD code ) { DWORD errCode; Standard_Character buffer[ 2048 ]; errCode = code ? code : GetLastError (); if ( !FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), buffer, 2048, NULL ) ) { sprintf ( buffer, "error code %d", (Standard_Integer)errCode ); SetLastError ( errCode ); } // end if err.SetValue ( errCode, OSD_WEnvironment, buffer ); } // end _set_error #endif