Avoid glibmm GSource bug/crash (again) (#697727)

The previous commit missed one glibmm GSource wrapper in the form of the
io watch for the PipeCapture class.  Convert this one to use glib
directly as well.

Bug #697727 - Segfault in livecd Gparted v 0.15.0-3 when copying
              partition
This commit is contained in:
Phillip Susi 2013-04-25 16:08:58 -04:00 committed by Mike Fleetwood
parent 1386984def
commit 9475731ac8
4 changed files with 26 additions and 14 deletions

View File

@ -31,11 +31,14 @@ class PipeCapture
unsigned int backcount;
unsigned int linelength;
Glib::RefPtr<Glib::IOChannel> channel;
sigc::connection connection;
guint sourceid;
bool OnReadable( Glib::IOCondition condition );
static gboolean _OnReadable( GIOChannel *source,
GIOCondition condition,
gpointer data );
public:
PipeCapture( int fd, Glib::ustring &buffer );
void connect_signal( int fd );
void connect_signal();
~PipeCapture();
sigc::signal<void> eof;
sigc::signal<void> update;

View File

@ -124,8 +124,8 @@ int FileSystem::execute_command( const Glib::ustring & command, OperationDetail
errorcapture.update.connect( sigc::bind( sigc::ptr_fun( relay_update ),
&(children[children.size() - 1]),
&error ) );
outputcapture.connect_signal( out );
errorcapture.connect_signal( err );
outputcapture.connect_signal();
errorcapture.connect_signal();
operationdetail.get_last_child().signal_cancel.connect(
sigc::bind(

View File

@ -20,22 +20,31 @@
namespace GParted {
PipeCapture::PipeCapture( int fd, Glib::ustring &string ) : buff( string ), backcount( 0 ), linelength( 0 )
PipeCapture::PipeCapture( int fd, Glib::ustring &string ) : buff( string ), backcount( 0 ), linelength( 0 ),
sourceid( 0 )
{
// tie fd to string
// make channel
channel = Glib::IOChannel::create_from_fd( fd );
}
void PipeCapture::connect_signal( int fd )
void PipeCapture::connect_signal()
{
// connect handler to signal input/output
connection = Glib::signal_io().connect(
sigc::mem_fun( *this, &PipeCapture::OnReadable ),
fd,
Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR );
sourceid = g_io_add_watch( channel->gobj(),
GIOCondition(G_IO_IN | G_IO_ERR | G_IO_HUP),
_OnReadable,
this );
}
gboolean PipeCapture::_OnReadable( GIOChannel *source,
GIOCondition condition,
gpointer data )
{
return static_cast<PipeCapture *>(data)->OnReadable( Glib::IOCondition(condition) );
}
bool PipeCapture::OnReadable( Glib::IOCondition condition )
{
// read from pipe and store in buff
@ -71,14 +80,14 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
if (status != Glib::IO_STATUS_EOF)
std::cerr << "Pipe IOChannel read failed" << std::endl;
// signal completion
connection.disconnect();
eof();
return false;
}
PipeCapture::~PipeCapture()
{
connection.disconnect();
if( sourceid > 0 )
g_source_remove( sourceid );
}
} // namespace GParted

View File

@ -501,8 +501,8 @@ int Utils::execute_command( const Glib::ustring & command,
status, &utils_execute_command_status::execute_command_eof ));
errorcapture.eof.connect( sigc::mem_fun(
status, &utils_execute_command_status::execute_command_eof ));
outputcapture.connect_signal( out );
errorcapture.connect_signal( err );
outputcapture.connect_signal();
errorcapture.connect_signal();
if( status.foreground)
Gtk::Main::run();