tags 378152 + patch fixed-upstream pending thanks Roger Leigh <[EMAIL PROTECTED]> writes:
> The terminal settings are not being restored on exit (either > on sucess or failure). This looks like a recent regression with > the splitting up of main(). exit() should not be called from > any subclass of schroot_base::main()? The attached patch fixes this by removing all but one exit point in each binary. This ensures the terminal restore is in the exit path under all conditions. -- .''`. Roger Leigh : :' : Debian GNU/Linux http://people.debian.org/~rleigh/ `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/ `- GPG Public Key: 0x25BFB848 Please sign and encrypt your mail.
Index: schroot/schroot-base-main.cc
===================================================================
--- schroot/schroot-base-main.cc (revision 854)
+++ schroot/schroot-base-main.cc (working copy)
@@ -160,11 +160,6 @@
exit(EXIT_FAILURE);
}
- catch (...)
- {
- sbuild::log_error() << _("An unknown exception occured") << endl;
- exit(EXIT_FAILURE);
- }
}
/*
Index: schroot/schroot-main-base.cc
===================================================================
--- schroot/schroot-main-base.cc (revision 854)
+++ schroot/schroot-main-base.cc (working copy)
@@ -38,6 +38,31 @@
using boost::format;
using namespace schroot;
+namespace
+{
+
+ typedef std::pair<main_base::error_code,const char *> emap;
+
+ /**
+ * This is a list of the supported error codes. It's used to
+ * construct the real error codes map.
+ */
+ emap init_errors[] =
+ {
+ emap(main_base::CHROOTS_NOTFOUND, N_("%1%: Chroots not found")),
+ emap(main_base::CHROOT_NOTDEFINED,
+ N_("The specified chroots are not defined in '%1%'")),
+ emap(main_base::CHROOT_NOTFOUND, N_("%1%: Chroot not found"))
+ };
+
+}
+
+template<>
+sbuild::error<main_base::error_code>::map_type
+sbuild::error<main_base::error_code>::error_strings
+(init_errors,
+ init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
+
main_base::main_base (std::string const& program_name,
std::string const& program_usage,
options_base::ptr& options):
@@ -99,13 +124,19 @@
if (!invalid_chroots.empty())
{
+ std::string invalid_list;
for (sbuild::string_list::const_iterator chroot =
invalid_chroots.begin();
chroot != invalid_chroots.end();
++chroot)
- sbuild::log_error() << format(_("%1%: No such chroot")) % *chroot
- << endl;
- exit(EXIT_FAILURE);
+ {
+ invalid_list += *chroot;
+ if (chroot + 1 != invalid_chroots.end())
+ invalid_list += ", ";
+ }
+ throw error(invalid_list,
+ (invalid_chroots.size() == 1)
+ ? CHROOT_NOTFOUND : CHROOTS_NOTFOUND);
}
ret = this->options->chroots;
}
@@ -135,13 +166,13 @@
if (this->options->action == options_base::ACTION_HELP)
{
action_help(std::cout);
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
if (this->options->action == options_base::ACTION_VERSION)
{
action_version(std::cout);
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
/* Initialise chroot configuration. */
@@ -169,46 +200,31 @@
if (this->options->action == options_base::ACTION_LIST)
{
action_list();
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
/* Get list of chroots to use */
chroots = get_chroot_options();
if (this->chroots.empty())
- {
- sbuild::log_error()
- << format(_("The specified chroots are not defined in '%1%'"))
- % SCHROOT_CONF
- << endl;
- exit (EXIT_FAILURE);
- }
+ throw error(SCHROOT_CONF, CHROOT_NOTDEFINED);
/* Print chroot information for specified chroots. */
if (this->options->action == options_base::ACTION_INFO)
{
action_info();
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
if (this->options->action == options_base::ACTION_LOCATION)
{
action_location();
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
if (this->options->action == options_base::ACTION_CONFIG)
{
action_config();
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
- if (this->options->action == options_base::ACTION_SESSION_BEGIN &&
- this->chroots.size() != 1)
- {
- sbuild::log_error()
- << _("Only one chroot may be specified when beginning a session")
- << endl;
- exit (EXIT_FAILURE);
- }
-
/* Create a session. */
sbuild::session::operation sess_op(sbuild::session::OPERATION_AUTOMATIC);
if (this->options->action == options_base::ACTION_SESSION_BEGIN)
@@ -255,9 +271,9 @@
}
if (this->session)
- exit(this->session->get_child_status());
+ return this->session->get_child_status();
else
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
/*
Index: schroot/schroot-main-base.h
===================================================================
--- schroot/schroot-main-base.h (revision 846)
+++ schroot/schroot-main-base.h (working copy)
@@ -23,6 +23,8 @@
#include <schroot/schroot-base-main.h>
#include <schroot/schroot-options-base.h>
+#include <sbuild/sbuild-custom-error.h>
+
namespace schroot
{
@@ -34,6 +36,17 @@
class main_base : public schroot_base::main
{
public:
+ /// Error codes.
+ enum error_code
+ {
+ CHROOTS_NOTFOUND, ///< Chroots not found.
+ CHROOT_NOTDEFINED, ///< The specified chroots are not defined.
+ CHROOT_NOTFOUND ///< Chroot not found.
+ };
+
+ /// Exception type.
+ typedef sbuild::custom_error<error_code> error;
+
/**
* The constructor.
*
Index: schroot/schroot-releaselock-main.h
===================================================================
--- schroot/schroot-releaselock-main.h (revision 846)
+++ schroot/schroot-releaselock-main.h (working copy)
@@ -23,6 +23,8 @@
#include <schroot/schroot-base-main.h>
#include <schroot/schroot-releaselock-options.h>
+#include <sbuild/sbuild-custom-error.h>
+
namespace schroot_releaselock
{
@@ -32,6 +34,18 @@
class main : public schroot_base::main
{
public:
+ /// Error codes.
+ enum error_code
+ {
+ DEVICE_NOTBLOCK, ///< File is not a block device.
+ DEVICE_OWNED, ///< Failed to release device lock (lock held by PID).
+ DEVICE_RELEASE, ///< Failed to release device lock.
+ DEVICE_STAT ///< Failed to stat device.
+ };
+
+ /// Exception type.
+ typedef sbuild::custom_error<error_code> error;
+
/**
* The constructor.
*
Index: schroot/schroot-options-base.cc
===================================================================
--- schroot/schroot-options-base.cc (revision 846)
+++ schroot/schroot-options-base.cc (working copy)
@@ -155,7 +155,7 @@
this->load_chroots = true;
this->load_sessions = false;
if (this->chroots.size() != 1 || all_used())
- throw opt::validation_error(_("Only one chroot may be specified when recovering, running or ending a session"));
+ throw opt::validation_error(_("Only one chroot may be specified when beginning a session"));
this->all = this->all_chroots = this->all_sessions = false;
break;
Index: schroot/schroot-releaselock-main.cc
===================================================================
--- schroot/schroot-releaselock-main.cc (revision 854)
+++ schroot/schroot-releaselock-main.cc (working copy)
@@ -39,6 +39,31 @@
using boost::format;
using namespace schroot_releaselock;
+namespace
+{
+
+ typedef std::pair<main::error_code,const char *> emap;
+
+ /**
+ * This is a list of the supported error codes. It's used to
+ * construct the real error codes map.
+ */
+ emap init_errors[] =
+ {
+ emap(main::DEVICE_NOTBLOCK, N_("File is not a block device")),
+ emap(main::DEVICE_OWNED, N_("Failed to release device lock (lock held by PID %4%")),
+ emap(main::DEVICE_RELEASE, N_("Failed to release device lock")),
+ emap(main::DEVICE_STAT, N_("Failed to stat device"))
+};
+
+}
+
+template<>
+sbuild::error<main::error_code>::map_type
+sbuild::error<main::error_code>::error_strings
+(init_errors,
+ init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
+
main::main (options::ptr& options):
schroot_base::main("schroot-releaselock",
_("[OPTION...] - release a device lock"),
@@ -63,38 +88,16 @@
struct stat statbuf;
if (stat(this->options->device.c_str(), &statbuf) == -1)
- {
- sbuild::log_error()
- << format(_("Failed to stat device '%1%': %2%"))
- % this->options->device % strerror(errno)
- << endl;
- exit (EXIT_FAILURE);
- }
+ throw error(this->options->device, DEVICE_STAT, strerror(errno));
+
if (!S_ISBLK(statbuf.st_mode))
- {
- sbuild::log_error()
- << format(_("'%1%' is not a block device")) % this->options->device
- << endl;
- exit (EXIT_FAILURE);
- }
+ throw error(this->options->device, DEVICE_NOTBLOCK);
pid_t status = dev_unlock(this->options->device.c_str(), this->options->pid);
if (status < 0) // Failure
- {
- sbuild::log_error()
- << format(_("%1%: failed to release device lock"))
- % this->options->device
- << endl;
- exit (EXIT_FAILURE);
- }
+ throw error(this->options->device, DEVICE_RELEASE);
else if (status > 0) // Owned
- {
- sbuild::log_error()
- << format(_("%1%: failed to release device lock owned by pid %2%"))
- % this->options->device % status
- << endl;
- exit (EXIT_FAILURE);
- }
+ throw error(this->options->device, DEVICE_OWNED, status);
}
int
Index: debian/changelog
===================================================================
--- debian/changelog (revision 846)
+++ debian/changelog (working copy)
@@ -10,6 +10,8 @@
single command, separated by spaces. This restores compatibility with
dchroot 0.13 and earlier (Closes: #378028). Thanks to David Liontooth
for reporting this.
+ * Terminal settings are correctly restored under all normal exit
+ conditions (Closes: #378152).
* debian/schroot.docs: Add the contents of debian/docs.
* debian/docs: Remove.
* debian/rules:
@@ -20,7 +22,7 @@
* debian/dchroot-dsa.preinst: New file. Remove
/usr/share/doc/dchroot-dsa.
- -- Roger Leigh <[EMAIL PROTECTED]> Thu, 13 Jul 2006 13:22:20 +0100
+ -- Roger Leigh <[EMAIL PROTECTED]> Fri, 14 Jul 2006 14:43:50 +0100
schroot (0.99.2-1) unstable; urgency=low
Index: sbuild/sbuild-session.cc
===================================================================
--- sbuild/sbuild-session.cc (revision 854)
+++ sbuild/sbuild-session.cc (working copy)
@@ -997,7 +997,7 @@
}
/* This should never be reached */
- exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
void
@@ -1087,7 +1087,7 @@
{
log_error() << e.what() << endl;
}
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
else
{
Index: sbuild/sbuild-run-parts.cc
===================================================================
--- sbuild/sbuild-run-parts.cc (revision 854)
+++ sbuild/sbuild-run-parts.cc (working copy)
@@ -179,7 +179,7 @@
exec(this->directory + '/' + file, command, env);
error e(file, EXEC, strerror(errno));
log_error() << e.what() << std::endl;
- exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
else
{
Index: ChangeLog
===================================================================
--- ChangeLog (revision 855)
+++ ChangeLog (working copy)
@@ -1,5 +1,30 @@
2006-07-14 Roger Leigh <[EMAIL PROTECTED]>
+ * debian/changelog: Close #378152.
+
+ * Having a single exit point now means terminal settings are
+ always restored correctly.
+
+ * sbuild/sbuild-run-parts.cc: Use _exit rather than exit when
+ terminating a child process when execve has failed.
+
+ * sbuild/sbuild-session.cc: Use _exit rather than exit when
+ terminating a child process when execve has failed.
+
+ * schroot/schroot-releaselock-main.(cc|h): Add error_code enum and
+ error typedef for sbuild::custom_error. Throw error in place of
+ exiting with EXIT_FAILURE.
+
+ * schroot/schroot-main-base.(cc|h): Add error_code enum and error
+ typedef for sbuild::custom_error. Throw error in place of exiting
+ with EXIT_FAILURE. Don't ever exit successfully; return a success
+ status.
+
+ * schroot/schroot-base-main.cc (run): Don't catch "..."; it's
+ handled by the main() stubs.
+
+2006-07-14 Roger Leigh <[EMAIL PROTECTED]>
+
* sbuild/sbuild-chroot-directory.cc (setup_env): Remove.
CHROOT_LOCATION is already set in the parent class.
pgp2H67pglsyk.pgp
Description: PGP signature

