diff --git a/include/eepp/system/sys.hpp b/include/eepp/system/sys.hpp index 6ae9b9460..5224959fb 100644 --- a/include/eepp/system/sys.hpp +++ b/include/eepp/system/sys.hpp @@ -83,10 +83,16 @@ class EE_API Sys { * @return The executable file path, or an empty string if not found. */ static std::string which( const std::string& exeName, const std::vector& customSearchPaths = {} ); - - /* It will attach the console to the parent process console if any. Windows only function. - * Other platforms will do nothing. - */ + + /** @return An environment variable */ + static std::string getEnv( const std::string& name ); + + /** @return A splitted environment variable */ + static std::vector getEnvSplitted( const std::string& name ); + + /** It will attach the console to the parent process console if any. Windows only function. + * Other platforms will do nothing. + */ static bool windowAttachConsole(); }; diff --git a/src/eepp/system/process.cpp b/src/eepp/system/process.cpp index 9233c5170..05207f6af 100644 --- a/src/eepp/system/process.cpp +++ b/src/eepp/system/process.cpp @@ -21,6 +21,8 @@ #include #endif +#define CHUNK_SIZE 4096 + namespace EE { namespace System { #define PROCESS_PTR ( static_cast( mProcess ) ) @@ -141,16 +143,16 @@ bool Process::create( const std::string& command, const std::string& args, const } size_t Process::readAllStdOut( std::string& buffer ) { + if ( buffer.empty() ) + buffer.resize( CHUNK_SIZE ); size_t bytesRead = 0; size_t totalBytesRead = 0; - const size_t chunkSize = mBufferSize; totalBytesRead = bytesRead = readStdOut( (char* const)buffer.c_str(), buffer.size() ); while ( bytesRead != 0 && isAlive() && !mShuttingDown ) { - bytesRead = readStdOut( (char* const)buffer.c_str() + bytesRead, chunkSize ); - if ( bytesRead ) { - totalBytesRead += bytesRead; - buffer.resize( totalBytesRead + chunkSize ); - } + if ( totalBytesRead + CHUNK_SIZE > buffer.size() ) + buffer.resize( totalBytesRead + CHUNK_SIZE ); + bytesRead = readStdOut( (char* const)buffer.c_str() + totalBytesRead, CHUNK_SIZE ); + totalBytesRead += bytesRead; } return totalBytesRead; } @@ -165,16 +167,16 @@ size_t Process::readStdOut( char* const buffer, const size_t& size ) { } size_t Process::readAllStdErr( std::string& buffer ) { + if ( buffer.empty() ) + buffer.resize( CHUNK_SIZE ); size_t bytesRead = 0; - size_t totalBytesRead = 0; - const size_t chunkSize = 4096; + size_t totalBytesRead = 0; totalBytesRead = bytesRead = readStdErr( (char* const)buffer.c_str(), buffer.size() ); while ( bytesRead != 0 && isAlive() && !mShuttingDown ) { - bytesRead = readStdErr( (char* const)buffer.c_str() + bytesRead, chunkSize ); - if ( bytesRead ) { - totalBytesRead += bytesRead; - buffer.resize( totalBytesRead + chunkSize ); - } + if ( totalBytesRead + CHUNK_SIZE > buffer.size() ) + buffer.resize( totalBytesRead + CHUNK_SIZE ); + bytesRead = readStdErr( (char* const)buffer.c_str() + totalBytesRead, CHUNK_SIZE ); + totalBytesRead += bytesRead; } return totalBytesRead; } diff --git a/src/eepp/system/sys.cpp b/src/eepp/system/sys.cpp index 15156e6e7..d5e6d4170 100644 --- a/src/eepp/system/sys.cpp +++ b/src/eepp/system/sys.cpp @@ -1014,22 +1014,6 @@ std::vector Sys::getLogicalDrives() { #endif } -static std::string getenv( const std::string& name ) { -#if EE_PLATFORM == EE_PLATFORM_WIN && defined( EE_COMPILER_MSVC ) - wchar_t* envbuf; - size_t envsize; - _wdupenv_s( &envbuf, &envsize, String( name ).toWideString().c_str() ); - std::string env; - if ( NULL != envbuf ) - env = String::fromWide( envbuf ).toUtf8(); - free( envbuf ); - return env; -#else - char* env = ::getenv( name.c_str() ); - return NULL == env ? std::string() : std::string( env ); -#endif -} - #if EE_PLATFORM == EE_PLATFORM_WIN #define PATH_SEP_CHAR ';' #else @@ -1037,10 +1021,9 @@ static std::string getenv( const std::string& name ) { #endif std::string Sys::which( const std::string& exeName, const std::vector& customSearchPaths ) { - std::string PATH = getenv( "PATH" ); - std::vector PATHS = String::split( PATH, PATH_SEP_CHAR ); + std::vector PATHS = getEnvSplitted( "PATH" ); #if EE_PLATFORM == EE_PLATFORM_WIN - static std::vector PATHEXTS = String::split( getenv( "PATHEXT" ), PATH_SEP_CHAR ); + static std::vector PATHEXTS = getEnvSplitted( "PATHEXT" ); std::string exePath; #endif @@ -1082,6 +1065,26 @@ std::string Sys::which( const std::string& exeName, return ""; } +std::string Sys::getEnv( const std::string& name ) { +#if EE_PLATFORM == EE_PLATFORM_WIN && defined( EE_COMPILER_MSVC ) + wchar_t* envbuf; + size_t envsize; + _wdupenv_s( &envbuf, &envsize, String( name ).toWideString().c_str() ); + std::string env; + if ( NULL != envbuf ) + env = String::fromWide( envbuf ).toUtf8(); + free( envbuf ); + return env; +#else + char* env = ::getenv( name.c_str() ); + return NULL == env ? std::string() : std::string( env ); +#endif +} + +std::vector Sys::getEnvSplitted( const std::string& name ) { + return String::split( getEnv( name.c_str() ), PATH_SEP_CHAR ); +} + #if EE_PLATFORM == EE_PLATFORM_WIN static ULONG_PTR GetParentProcessId() { ULONG_PTR pbi[6]; diff --git a/src/eepp/window/input.cpp b/src/eepp/window/input.cpp index 4af78fd4e..7b0fdf964 100644 --- a/src/eepp/window/input.cpp +++ b/src/eepp/window/input.cpp @@ -219,6 +219,7 @@ void Input::processEvent( InputEvent* Event ) { break; } case InputEvent::Quit: { + mWindow->onCloseRequest(); break; } } diff --git a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp index 92b0fe780..5a61f0dbf 100644 --- a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp @@ -142,6 +142,10 @@ class TerminalEmulator final { void terminate(); + bool isStarting() const; + + bool isRunning() const; + bool hasExited() const; int getExitCode() const; diff --git a/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp b/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp index cd8eae778..ed3a37061 100644 --- a/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp @@ -1619,7 +1619,8 @@ void TerminalEmulator::csihandle( void ) { mCsiescseq.arg[0] < TerminalCursorMode::MAX_CURSOR ) goto unknown; dpy = mDpy.lock(); - dpy->setCursorMode( (TerminalCursorMode)mCsiescseq.arg[0] ); + if ( dpy ) + dpy->setCursorMode( (TerminalCursorMode)mCsiescseq.arg[0] ); break; default: goto unknown; @@ -1664,6 +1665,9 @@ void TerminalEmulator::strhandle( void ) { std::shared_ptr dpy = mDpy.lock(); + if ( !dpy ) + return; + switch ( mStrescseq.type ) { case ']': /* OSC -- Operating System Command */ switch ( par ) { @@ -1924,8 +1928,9 @@ void TerminalEmulator::tcontrolcode( uchar ascii ) { /* backwards compatibility to xterm */ strhandle(); } else { - auto belDpyPtr = mDpy.lock(); - belDpyPtr->bell(); + auto dpy = mDpy.lock(); + if ( dpy ) + dpy->bell(); } break; case '\033': /* ESC */ @@ -2442,12 +2447,15 @@ void TerminalEmulator::redraw() { void TerminalEmulator::xsetmode( int set, unsigned int mode ) { auto dpy = mDpy.lock(); - dpy->setMode( (TerminalWinMode)mode, set ); + if ( dpy ) + dpy->setMode( (TerminalWinMode)mode, set ); } bool TerminalEmulator::xgetmode( const TerminalWinMode& mode ) { auto dpy = mDpy.lock(); - return dpy->getMode( mode ); + if ( dpy ) + return dpy->getMode( mode ); + return false; } void TerminalEmulator::mousereport( const TerminalMouseEventType& type, const Vector2i& pos, @@ -2640,24 +2648,20 @@ void TerminalEmulator::terminate() { void TerminalEmulator::onProcessExit( int exitCode ) { auto dpy = mDpy.lock(); - if ( !dpy ) - return; - dpy->onProcessExit( exitCode ); + if ( dpy ) + dpy->onProcessExit( exitCode ); } void TerminalEmulator::setClipboard( const char* str ) { auto dpy = mDpy.lock(); - if ( !dpy ) - return; - dpy->setClipboard( str ); + if ( dpy ) + dpy->setClipboard( str ); } void TerminalEmulator::loadColors() { auto dpy = mDpy.lock(); - if ( !dpy ) - return; - - dpy->resetColors(); + if ( dpy ) + dpy->resetColors(); } int TerminalEmulator::resetColor( int i, const char* name ) { @@ -2668,6 +2672,14 @@ int TerminalEmulator::resetColor( int i, const char* name ) { return dpy->resetColor( i, name ); } +bool TerminalEmulator::isStarting() const { + return mStatus == STARTING; +} + +bool TerminalEmulator::isRunning() const { + return mStatus == RUNNING; +} + bool TerminalEmulator::hasExited() const { return mStatus == TERMINATED; }