OSDN Git Service

Fix "mingw-get deletes itself" bug in last rites handling.
authorCharles Wilson <cwilso11@users.sourceforge.net>
Fri, 10 Sep 2010 01:44:24 +0000 (01:44 +0000)
committerCharles Wilson <cwilso11@users.sourceforge.net>
Fri, 10 Sep 2010 01:44:24 +0000 (01:44 +0000)
ChangeLog
README
configure.ac
src/climain.cpp
src/clistub.c
src/dmh.cpp
src/dmh.h

index 3973a97..c4810c1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2010-09-10  Charles Wilson  <mingw@cwilson.fastmail.fm>
+
+       Fix "mingw-get deletes itself" bug in last rites handling.
+
+       * README: Add new release notes.
+
+       * configure.ac: Bump version to 0.1-alpha-4.
+
+       * src/dmh.h: If __cplusplus, include <exception> and
+       declare dmh_exception class.
+
+       * src/dmh.cpp (class dmh_exception): Implement.
+       (abort_if_fatal): If DMH_FATAL, throw dmh_exception rather
+       than calling exit().
+
+       * src/climain.cpp (climain): Wrap entry function body in try/
+       catch block. If dmh_exception is caught, return EXIT_FAILURE.
+
+       * src/clistub.c (main): Capture return value of climain(). If
+       non-zero, perform last rites and return EXIT_FAILURE.
+
 2010-08-30  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        mingw-get-0.1-mingw32-alpha-3 released.
diff --git a/README b/README
index 0a91950..8d84436 100644 (file)
--- a/README
+++ b/README
@@ -1,10 +1,41 @@
-Release Notes for mingw-get-0.1-mingw32-alpha-3
+Release Notes for mingw-get-0.1-mingw32-alpha-4
 
 $Id$
 
 Preamble
 --------
 
+This is the fourth alpha release of mingw-get; this is primarily a bug
+fix release, with few user visible changes.  The installation procedure
+remains the same as for previous releases; to upgrade from a previous
+release, simply unpack the -bin package over the top of the existing
+installation.  For further information, and usage advice, see:
+
+    http://mingw.org/wiki/Getting_Started
+
+
+User Visible Changes for mingw-get-0.1-mingw32-alpha-4
+------------------------------------------------------
+
+- This release of mingw-get fixes a bug in the earlier self-upgrade
+  functionality, where any runtime error "deleted" mingw-get.  (mingw-get
+  and its support file(s) were actually only renamed, but recovery was
+  difficult).  Now, "ordinary" errors such as bad command line arguments,
+  failed downloads, missing manifests, etc, will not cause this behavior.
+  However, a catastrophic operating system error may prevent the new
+  auto-recovery code from executing, leaving mingw-get in its "deleted"
+  (e.g. renamed) state.  If this occurs, simply do the following:
+
+     cd /mingw
+     mv bin/mingw-get.exe~ bin/mingw-get.exe
+     mv libexec/mingw-get/mingw-get-0.dll~ libexec/mingw-get/mingw-get-0.dll
+
+
+===============================================
+
+Preamble
+--------
+
 This is the third alpha release of mingw-get; this is primarily a bug
 fix release, with few user visible changes.  The installation procedure
 remains the same as for previous releases; to upgrade from a previous
index 78b092d..5f51cd0 100644 (file)
@@ -22,7 +22,7 @@
 # MinGW Project, accept liability for any damages, however caused,
 # arising from the use of this software.
 #
-  AC_INIT([mingw-get],[0.1-alpha-3],[http://mingw.org/reporting_bugs])
+  AC_INIT([mingw-get],[0.1-alpha-4],[http://mingw.org/reporting_bugs])
 
   AC_SUBST([COPYRIGHT_HOLDER],["MinGW Project"])
   AC_SUBST([YEARS_OF_ISSUE],["2009, 2010"])
index 8c352a9..651fae3 100644 (file)
@@ -38,6 +38,9 @@
 
 EXTERN_C int climain( int argc, char **argv )
 {
+  try
+  {
+
   /* Set up the diagnostic message handler, using the console's
    * `stderr' stream for notifications...
    */
@@ -134,6 +137,12 @@ EXTERN_C int climain( int argc, char **argv )
    * function without a return value assignment...
    */
   return dmh_notify( DMH_FATAL, "%s: cannot load configuration\n", dfile );
+
+  }
+  catch (dmh_exception &e)
+  {
+    return EXIT_FAILURE;
+  }
 }
 
 /* $RCSfile$: end of file */
index ee45e56..dbea42f 100644 (file)
@@ -243,19 +243,22 @@ int main( int argc, char **argv )
     if( (lock = pkgInitRites( progname )) >= 0 )
     {
       /* ...and proceed, only if successful.
-       * (Note that we don't capture the exit status from "climain()";
-       *  MS-Windows degenerate process model provides us with no viable
-       *  mechanism to pass it back to our parent, when the last rites
-       *  handler exits with a successful "exec()" call).
+       *  A non-zero return value indicates that a fatal error occurred.
        */
-      (void) climain( argc, argv );
+      int rc = climain( argc, argv );
 
       /* We must release the mingw-get DLL code, BEFORE we invoke
        * last rites processing, (otherwise the last rites clean-up
        * handler exhibits abnormal behaviour when it is exec'd).
        */
       FreeLibrary( my_dll );
-      return pkgLastRites( lock, progname );
+      if (rc == 0)
+        return pkgLastRites( lock, progname );
+      else
+      {
+        (void) pkgLastRites( lock, progname );
+        return EXIT_FATAL;
+      }
     }
     /* If we get to here, then we failed to acquire a lock;
      * we MUST abort!
index 3dc2be7..bca0a88 100644 (file)
@@ -66,6 +66,25 @@ class dmhTypeGUI : public dmhTypeGeneric
     virtual int printf( const char*, va_list );
 };
 
+dmh_exception::dmh_exception() throw()
+  : message("Unspecified error")
+{}
+
+dmh_exception::dmh_exception::dmh_exception(const char * msg) throw()
+  : message("Unspecified error")
+{
+  if (msg && *msg)
+    message = msg;
+}
+
+dmh_exception::~dmh_exception() throw()
+{}
+
+const char * dmh_exception::what() const throw()
+{
+  return message;
+}
+
 /* Constructors serve to initialise the message handler,
  * simply creating the class instance, and storing the specified
  * program name within it.
@@ -111,7 +130,7 @@ int abort_if_fatal( const dmh_severity code, int status )
    * of a DMH_FATAL exception.
    */
   if( code == DMH_FATAL )
-    exit( EXIT_FAILURE );
+    throw dmh_exception("Fatal error occured");
 
   /* If the exception wasn't DMH_FATAL, then fall through to
    * return the specified status code.
index 60929b2..62fb179 100644 (file)
--- a/src/dmh.h
+++ b/src/dmh.h
@@ -29,6 +29,9 @@
 #define DMH_H  1
 
 #include <stdint.h>
+#ifdef __cplusplus
+#include <exception>
+#endif
 
 #undef EXTERN_C
 #ifdef __cplusplus
@@ -62,4 +65,24 @@ EXTERN_C int dmh_printf( const char *fmt, ... );
 
 EXTERN_C uint16_t dmh_control( const uint16_t, const uint16_t );
 
+#ifdef __cplusplus
+class dmh_exception : public std::exception
+{
+  /* Limited purpose exception class; can only accept messages
+   * that are const char, because lifetime is assumed infinite,
+   * and storage is not freed. Used to handle fatal errors,
+   * which otherwise would force a direct call to exit().  By
+   * using this class, we can ensure that last rites are
+   * performed before exiting.
+   */
+public:
+  dmh_exception() throw();
+  dmh_exception(const char * msg) throw();
+  virtual ~dmh_exception() throw();
+  virtual const char* what() const throw();
+protected:
+  const char * message;
+};
+#endif /* __cplusplus */
+
 #endif /* DMH_H: $RCSfile$: end of file */