[gparted] Connect output progress tracking callbacks inside execute_command() (#760709)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Connect output progress tracking callbacks inside execute_command() (#760709)
- Date: Sat, 13 Feb 2016 17:12:36 +0000 (UTC)
commit c00927c23d7b569078473734a3685b5d449d0f70
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Sat Jan 23 09:27:38 2016 +0000
Connect output progress tracking callbacks inside execute_command() (#760709)
All the output progress tracking callbacks for execution of ext2/3/4 and
ntfs file system specific commands followed this pattern:
sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::..._progress ) );
bool success = ! execute_command( ... );
c.disconnect();
return success;
Instead, pass the callback slot and a flag into execute_command() and
connect the callback inside. This simplifies the pattern to:
return ! execute_command( ...|EXEC_PROGRESS_STDOUT,
sigc::mem_fun( *this, &ext2::..._progress ) );
Note that as the progress tracking callbacks are only registered against
updates to the relevant stream from the tracked commands they won't be
called when the other stream is updated any more.
Also note that signal_progress is a member of the FileSystem class and
derived objects so lives as long as GParted is running, therefore the
progress tracking callbacks need explicitly disconnecting at the end of
execute_command(). However signal_update is a member of the PipeCapture
class of which the output and error local variables in execute_command()
are types. Therefore there is no need to explicitly disconnect the
signal_update callbacks as they will be destructed along with the
callback slots when they go out of scope at the end of the
execute_command() method.
Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
copy methods
include/FileSystem.h | 30 ++++++++++++++++++++++--------
src/FileSystem.cc | 25 ++++++++++++++++++++-----
src/ext2.cc | 35 +++++++++++++----------------------
src/ntfs.cc | 5 ++---
4 files changed, 57 insertions(+), 38 deletions(-)
---
diff --git a/include/FileSystem.h b/include/FileSystem.h
index 215bf65..bce53d3 100644
--- a/include/FileSystem.h
+++ b/include/FileSystem.h
@@ -25,19 +25,23 @@
#include <fstream>
#include <sys/stat.h>
+#include <sigc++/slot.h>
namespace GParted
{
enum ExecFlags
{
- EXEC_NONE = 1 << 0,
- EXEC_CHECK_STATUS = 1 << 1, // Set the status of the command in the operation
- // details based on the exit status being zero or
- // non-zero. Must either use this flag when calling
- // ::execute_command() or call ::set_status()
- // afterwards.
- EXEC_CANCEL_SAFE = 1 << 2
+ EXEC_NONE = 1 << 0,
+ EXEC_CHECK_STATUS = 1 << 1, // Set the status of the command in the operation
+ // details based on the exit status being zero or
+ // non-zero. Must either use this flag when calling
+ // ::execute_command() or call ::set_status()
+ // afterwards.
+ EXEC_CANCEL_SAFE = 1 << 2,
+ EXEC_PROGRESS_STDOUT = 1 << 3, // Run progress tracking callback after reading new
+ // data on stdout from command.
+ EXEC_PROGRESS_STDERR = 1 << 4 // Same but for stderr.
};
inline ExecFlags operator|( ExecFlags lhs, ExecFlags rhs )
@@ -77,8 +81,18 @@ public:
virtual bool remove( const Partition & partition, OperationDetail & operationdetail ) { return true;
};
protected:
+ typedef sigc::slot<void, OperationDetail *> StreamSlot;
+
+ // Use sigc::slot<> class default constructor, via StreamSlot typedef, to create
+ // an empty, unconnected slot to use as the default stream_progress_slot parameter
+ // for when none is provided.
+ // References:
+ // * How to set default parameter as class object in c++?
+ // http://stackoverflow.com/questions/12121645/how-to-set-default-parameter-as-class-object-in-c
+ // * C++ function, what default value can I give for an object?
+ //
http://stackoverflow.com/questions/9909444/c-function-what-default-value-can-i-give-for-an-object
int execute_command( const Glib::ustring & command, OperationDetail & operationdetail,
- ExecFlags flags = EXEC_NONE );
+ ExecFlags flags = EXEC_NONE, StreamSlot stream_progress_slot = StreamSlot() );
void set_status( OperationDetail & operationdetail, bool success );
void execute_command_eof();
Glib::ustring mk_temp_dir( const Glib::ustring & infix, OperationDetail & operationdetail ) ;
diff --git a/src/FileSystem.cc b/src/FileSystem.cc
index 0b4b9e1..10870b5 100644
--- a/src/FileSystem.cc
+++ b/src/FileSystem.cc
@@ -23,6 +23,7 @@
#include <gtkmm/main.h>
#include <signal.h>
#include <fcntl.h>
+#include <sigc++/slot.h>
namespace GParted
{
@@ -80,7 +81,7 @@ static void setup_child()
}
int FileSystem::execute_command( const Glib::ustring & command, OperationDetail & operationdetail,
- ExecFlags flags )
+ ExecFlags flags, StreamSlot stream_progress_slot )
{
operationdetail.add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) );
Glib::Pid pid;
@@ -122,13 +123,24 @@ int FileSystem::execute_command( const Glib::ustring & command, OperationDetail
outputcapture.signal_update.connect( sigc::bind( sigc::ptr_fun( update_command_output ),
children[children.size() - 2],
&output ) );
- outputcapture.signal_update.connect( sigc::bind( sigc::mem_fun( *this,
&FileSystem::update_command_progress ),
- &operationdetail ) );
errorcapture.signal_update.connect( sigc::bind( sigc::ptr_fun( update_command_output ),
children[children.size() - 1],
&error ) );
- errorcapture.signal_update.connect( sigc::bind( sigc::mem_fun( *this,
&FileSystem::update_command_progress ),
- &operationdetail ) );
+ sigc::connection c;
+ if ( flags & EXEC_PROGRESS_STDOUT && ! stream_progress_slot.empty() )
+ {
+ // Call progress tracking callback when stdout updates
+ outputcapture.signal_update.connect( sigc::bind( sigc::mem_fun( *this,
&FileSystem::update_command_progress ),
+ &operationdetail ) );
+ c = signal_progress.connect( stream_progress_slot );
+ }
+ else if ( flags & EXEC_PROGRESS_STDERR && ! stream_progress_slot.empty() )
+ {
+ // Call progress tracking callback when stderr updates
+ errorcapture.signal_update.connect( sigc::bind( sigc::mem_fun( *this,
&FileSystem::update_command_progress ),
+ &operationdetail ) );
+ c = signal_progress.connect( stream_progress_slot );
+ }
outputcapture.connect_signal();
errorcapture.connect_signal();
@@ -148,6 +160,9 @@ int FileSystem::execute_command( const Glib::ustring & command, OperationDetail
}
close( out );
close( err );
+ if ( c.connected() )
+ c.disconnect();
+ operationdetail.stop_progressbar();
return exit_status;
}
diff --git a/src/ext2.cc b/src/ext2.cc
index 1e89a41..cb2b873 100644
--- a/src/ext2.cc
+++ b/src/ext2.cc
@@ -228,12 +228,10 @@ bool ext2::write_uuid( const Partition & partition, OperationDetail & operationd
bool ext2::create( const Partition & new_partition, OperationDetail & operationdetail )
{
- sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::create_progress ) );
- bool ret = ! execute_command( mkfs_cmd + " -F -L \"" + new_partition.get_filesystem_label() + "\" " +
- new_partition.get_path(),
- operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
- c.disconnect();
- return ret;
+ return ! execute_command( mkfs_cmd + " -F -L \"" + new_partition.get_filesystem_label() + "\" " +
+ new_partition.get_path(),
+ operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE|EXEC_PROGRESS_STDOUT,
+ sigc::mem_fun( *this, &ext2::create_progress ) );
}
bool ext2::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
@@ -244,18 +242,15 @@ bool ext2::resize( const Partition & partition_new, OperationDetail & operationd
str_temp += " " + Utils::num_to_str( floor( Utils::sector_to_unit(
partition_new .get_sector_length(), partition_new .sector_size,
UNIT_KIB ) ) ) + "K";
- sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::resize_progress ) );
- bool ret = ! execute_command( str_temp, operationdetail, EXEC_CHECK_STATUS );
- c.disconnect();
- return ret;
+ return ! execute_command( str_temp, operationdetail, EXEC_CHECK_STATUS|EXEC_PROGRESS_STDOUT,
+ sigc::mem_fun( *this, &ext2::resize_progress ) );
}
bool ext2::check_repair( const Partition & partition, OperationDetail & operationdetail )
{
- sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::check_repair_progress ) );
exit_status = execute_command( fsck_cmd + " -f -y -v -C 0 " + partition.get_path(), operationdetail,
- EXEC_CANCEL_SAFE );
- c.disconnect();
+ EXEC_CANCEL_SAFE|EXEC_PROGRESS_STDOUT,
+ sigc::mem_fun( *this, &ext2::check_repair_progress ) );
bool success = ( exit_status == 0 || exit_status == 1 || exit_status == 2 );
set_status( operationdetail, success );
return success;
@@ -274,10 +269,8 @@ bool ext2::move( const Partition & partition_new,
cmd = image_cmd + " -ra -p -O " + offset + " " + partition_new.get_path();
fs_block_size = partition_old.fs_block_size;
- sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::copy_progress ) );
- bool success = ! execute_command( cmd, operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
- c.disconnect();
- return success;
+ return ! execute_command( cmd, operationdetail,
EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE|EXEC_PROGRESS_STDERR,
+ sigc::mem_fun( *this, &ext2::copy_progress ) );
}
bool ext2::copy( const Partition & src_part,
@@ -285,11 +278,9 @@ bool ext2::copy( const Partition & src_part,
OperationDetail & operationdetail )
{
fs_block_size = src_part.fs_block_size;
- sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::copy_progress ) );
- bool success = ! execute_command( image_cmd + " -ra -p " + src_part.get_path() + " " +
dest_part.get_path(),
- operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
- c.disconnect();
- return success;
+ return ! execute_command( image_cmd + " -ra -p " + src_part.get_path() + " " + dest_part.get_path(),
+ operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE|EXEC_PROGRESS_STDERR,
+ sigc::mem_fun( *this, &ext2::copy_progress ) );
}
//Private methods
diff --git a/src/ntfs.cc b/src/ntfs.cc
index 0a75bdf..d5d6700 100644
--- a/src/ntfs.cc
+++ b/src/ntfs.cc
@@ -234,9 +234,9 @@ bool ntfs::resize( const Partition & partition_new, OperationDetail & operationd
//real resize
operationdetail .add_child( OperationDetail( _("real resize") ) ) ;
- sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ntfs::resize_progress )
);
if ( ! execute_command( cmd + " " + partition_new.get_path(),
- operationdetail.get_last_child(), EXEC_CHECK_STATUS ) )
+ operationdetail.get_last_child(),
EXEC_CHECK_STATUS|EXEC_PROGRESS_STDOUT,
+ sigc::mem_fun( *this, &ntfs::resize_progress ) ) )
{
operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
return_value = true ;
@@ -245,7 +245,6 @@ bool ntfs::resize( const Partition & partition_new, OperationDetail & operationd
{
operationdetail .get_last_child() .set_status( STATUS_ERROR ) ;
}
- c.disconnect();
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]