diff options
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llerror.cpp | 118 | 
1 files changed, 79 insertions, 39 deletions
| diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 6ef0fde886..a8e1481774 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -53,6 +53,46 @@  #include "llstl.h"  #include "lltimer.h" +#if LL_WINDOWS +#define fhclose  _close +#define fhdup    _dup +#define fhdup2   _dup2 +#define fhfdopen _fdopen +#define fhfileno _fileno +#else +#define fhclose  ::close +#define fhdup    ::dup +#define fhdup2   ::dup2 +#define fhfdopen ::fdopen +#define fhfileno ::fileno +#endif + +namespace LLError +{ + +	class SettingsConfig; +	typedef LLPointer<SettingsConfig> SettingsConfigPtr; + +	class Settings : public LLSingleton<Settings> +	{ +		LLSINGLETON(Settings); +	public: +		SettingsConfigPtr getSettingsConfig(); +		~Settings(); + +		void reset(); +		SettingsStoragePtr saveAndReset(); +		void restore(SettingsStoragePtr pSettingsStorage); + +		int getDupStderr() const; + +	private: +		SettingsConfigPtr mSettingsConfig; +		int mDupStderr; +	}; + +} // namespace LLError +  namespace {  #if LL_WINDOWS  	void debugger_print(const std::string& s) @@ -120,7 +160,8 @@ namespace {  	public:  		RecordToFile(const std::string& filename):  			mName(filename), -			mFile(LLFile::fopen(filename, "a")) +			mFile(LLFile::fopen(filename, "a")), +			mSavedStderr(LLError::Settings::instance().getDupStderr())  		{  			if (!mFile)  			{ @@ -128,25 +169,19 @@ namespace {  			}  			else  			{ -#if LL_DARWIN || LL_LINUX  				// We use a number of classic-C libraries, some of which write  				// log output to stderr. The trouble with that is that unless  				// you launch the viewer from a console, stderr output is  				// lost. Redirect STDERR_FILENO to write into this log file. -				// But first, save the original stream in case we want it later. -				mSavedStderr = ::dup(STDERR_FILENO); -				::dup2(::fileno(mFile), STDERR_FILENO); -#endif +				fhdup2(fhfileno(mFile), fhfileno(stderr));  			}  		}  		~RecordToFile()  		{ -#if LL_DARWIN || LL_LINUX  			// restore stderr to its original fileno so any subsequent output  			// to stderr goes to original stream -			::dup2(mSavedStderr, STDERR_FILENO); -#endif +			fhdup2(mSavedStderr, fhfileno(stderr));  			mFile.close();  		} @@ -166,7 +201,8 @@ namespace {  		virtual void recordMessage(LLError::ELevel level,  									const std::string& message) override  		{ -			fwrite(message.c_str(), sizeof(char), message.length(), mFile); +			::fwrite(message.c_str(), sizeof(char), message.length(), mFile); +			::fputc('\n', mFile);  			if (LLError::getAlwaysFlush())  			{  				::fflush(mFile); @@ -176,22 +212,26 @@ namespace {  	private:  		const std::string mName;  		LLUniqueFile mFile; -		int mSavedStderr{0}; +		int mSavedStderr;  	};  	class RecordToStderr : public LLError::Recorder  	{  	public: -		RecordToStderr(bool timestamp) : mUseANSI(checkANSI())  +		RecordToStderr(bool timestamp) : +			mUseANSI(checkANSI()), +			// use duplicate stderr file handle so THIS output isn't affected +			// by our internal redirection of all (other) stderr output +			mStderr(fhfdopen(LLError::Settings::instance().getDupStderr(), "a"))  		{ -            this->showMultiline(true); +			this->showMultiline(true); +		} + +		virtual bool enabled() override +		{ +			return LLError::getEnabledLogTypesMask() & 0x04;  		} -		 -        virtual bool enabled() override -        { -            return LLError::getEnabledLogTypesMask() & 0x04; -        }  		virtual void recordMessage(LLError::ELevel level,  					   const std::string& message) override @@ -214,17 +254,18 @@ namespace {  					break;  				}  			} -			fprintf(stderr, "%s\n", message.c_str()); +			fprintf(mStderr, "%s\n", message.c_str());  			if (mUseANSI) colorANSI("0"); // reset  		} -	 +  	private:  		bool mUseANSI; +		LLFILE* mStderr;  		void colorANSI(const std::string color)  		{  			// ANSI color code escape sequence -			fprintf(stderr, "\033[%sm", color.c_str() ); +			fprintf(mStderr, "\033[%sm", color.c_str() );  		};  		static bool checkANSI(void) @@ -233,7 +274,7 @@ namespace {  			// Check whether it's okay to use ANSI; if stderr is  			// a tty then we assume yes.  Can be turned off with  			// the LL_NO_ANSI_COLOR env var. -			return (0 != isatty(2)) && +			return (0 != isatty(fhfileno(stderr))) &&  				(NULL == getenv("LL_NO_ANSI_COLOR"));  #endif // LL_LINUX  			return false; @@ -504,22 +545,6 @@ namespace LLError  		SettingsConfig();  	}; -	typedef LLPointer<SettingsConfig> SettingsConfigPtr; - -	class Settings : public LLSingleton<Settings> -	{ -		LLSINGLETON(Settings); -	public: -		SettingsConfigPtr getSettingsConfig(); - -		void reset(); -		SettingsStoragePtr saveAndReset(); -		void restore(SettingsStoragePtr pSettingsStorage); -		 -	private: -		SettingsConfigPtr mSettingsConfig; -	}; -  	SettingsConfig::SettingsConfig()  		: LLRefCount(),  		mDefaultLevel(LLError::LEVEL_DEBUG), @@ -543,8 +568,18 @@ namespace LLError  	}  	Settings::Settings(): -		mSettingsConfig(new SettingsConfig()) +		mSettingsConfig(new SettingsConfig()), +		// duplicate stderr file handle right away +		mDupStderr(fhdup(fhfileno(stderr))) +	{ +	} + +	Settings::~Settings()  	{ +		// restore original stderr +		fhdup2(mDupStderr, fhfileno(stderr)); +		// and close the duplicate +		fhclose(mDupStderr);  	}  	SettingsConfigPtr Settings::getSettingsConfig() @@ -572,6 +607,11 @@ namespace LLError  		mSettingsConfig = newSettingsConfig;  	} +	int Settings::getDupStderr() const +	{ +		return mDupStderr; +	} +  	bool is_available()  	{  		return Settings::instanceExists() && Globals::instanceExists(); | 
