Added error-checking for child.wait() call during removable drive ejection (to prevent #5507)

Mark Ejection as failed if the wait() function fails. It seems that it is not simply possible
to retrieve the exit code of the process in that case (although it usually finishes sucessfully).
This commit is contained in:
David Kocik 2020-12-21 14:53:57 +01:00 committed by Lukas Matena
parent 6c399052c6
commit 99f5dfbde7

View file

@ -277,14 +277,15 @@ void RemovableDriveManager::eject_drive()
//std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n";
// there is no usable command in c++ so terminal command is used instead
// but neither triggers "succesful safe removal messege"
BOOST_LOG_TRIVIAL(info) << "Ejecting started";
boost::process::ipstream istd_err;
boost::process::child child(
BOOST_LOG_TRIVIAL(info) << "Ejecting started";
boost::process::ipstream istd_err;
boost::process::child child(
#if __APPLE__
boost::process::search_path("diskutil"), "eject", correct_path.c_str(), (boost::process::std_out & boost::process::std_err) > istd_err);
//Another option how to eject at mac. Currently not working.
//used insted of system() command;
//this->eject_device(correct_path);
//Another option how to eject at mac. Currently not working.
//used insted of system() command;
//this->eject_device(correct_path);
#else
boost::process::search_path("umount"), correct_path.c_str(), (boost::process::std_out & boost::process::std_err) > istd_err);
#endif
@ -293,8 +294,19 @@ void RemovableDriveManager::eject_drive()
BOOST_LOG_TRIVIAL(trace) << line;
}
// wait for command to finnish (blocks ui thread)
child.wait();
int err = child.exit_code();
std::error_code ec;
child.wait(ec);
if (ec) {
// The wait call can fail, as it did in https://github.com/prusa3d/PrusaSlicer/issues/5507
// It can happen even in cases where the eject is sucessful, but better report it as failed.
// We did not find a way to reliably retrieve the exit code of the process.
BOOST_LOG_TRIVIAL(error) << "boost::process::child::wait() failed during Ejection. State of Ejection is unknown. Error code: " << ec.value();
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
return;
}
int err = child.exit_code();
if (err) {
BOOST_LOG_TRIVIAL(error) << "Ejecting failed. Exit code: " << err;
assert(m_callback_evt_handler);