diff --git a/include/Utils.h b/include/Utils.h index 0f10902c..93402ae8 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -153,6 +153,11 @@ public: Glib::ustring & output, Glib::ustring & error, bool use_C_locale = false ) ; + static int execute_command( const Glib::ustring & command, + const char * input, + Glib::ustring & output, + Glib::ustring & error, + bool use_C_locale = false ); static int get_failure_status( Glib::SpawnError & e ); static int decode_wait_status( int wait_status ); static Glib::ustring regexp_label( const Glib::ustring & text diff --git a/src/Utils.cc b/src/Utils.cc index a955f6a5..b0d26cd9 100644 --- a/src/Utils.cc +++ b/src/Utils.cc @@ -32,6 +32,8 @@ #include #include #include +#include +#include namespace GParted { @@ -515,7 +517,7 @@ double Utils::sector_to_unit( Sector sectors, Byte_Value sector_size, SIZE_UNIT int Utils::execute_command( const Glib::ustring & command ) { Glib::ustring dummy ; - return execute_command( command, dummy, dummy ) ; + return execute_command( command, NULL, dummy, dummy ); } class CommandStatus @@ -579,8 +581,18 @@ int Utils::execute_command( const Glib::ustring & command, Glib::ustring & output, Glib::ustring & error, bool use_C_locale ) +{ + return execute_command( command, NULL, output, error, use_C_locale ); +} + +int Utils::execute_command( const Glib::ustring & command, + const char * input, + Glib::ustring & output, + Glib::ustring & error, + bool use_C_locale ) { Glib::Pid pid; + int in = -1; // set up pipes for capture int out, err; CommandStatus status; @@ -595,7 +607,7 @@ int Utils::execute_command( const Glib::ustring & command, Glib::SPAWN_DO_NOT_REAP_CHILD | Glib::SPAWN_SEARCH_PATH, use_C_locale ? sigc::ptr_fun( set_locale ) : sigc::slot< void >(), &pid, - 0, + ( input != NULL ) ? &in : 0, &out, &err ); } catch (Glib::SpawnError &e) { @@ -616,6 +628,17 @@ int Utils::execute_command( const Glib::ustring & command, outputcapture.connect_signal(); errorcapture.connect_signal(); + if ( input != NULL && in != -1 ) + { + // Write small amount of input to pipe to the child process. Linux will + // always accept up 4096 bytes without blocking. See pipe(7). + size_t len = strlen( input ); + ssize_t written = write( in, input, len ); + if ( written == -1 || (size_t)written < len ) + std::cerr << "Write to child failed: " << Glib::strerror( errno ) << std::endl; + close( in ); + } + if( status.foreground) Gtk::Main::run(); else {