Here's a small patch for setup.exe which causes setup to indicate if a postinstall script didn't run successfully.
This should help avoid the situation where the postinstall scripts fail to run and the user has a broken installation, but they don't notice until they try to run something which relies on postinstall scripts, e.g [1] and I'm sure there are other examples.
[1] http://cygwin.com/ml/cygwin-xfree/2010-07/msg00084.html ChangeLog: * postinstall.cc : Note if any postinstall script fails and tell the user with an error messagebox * script.cc (run): Don't rename script as .done if it didn't run successfully
Index: postinstall.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v retrieving revision 2.23 diff -u -p -r2.23 postinstall.cc --- postinstall.cc 11 May 2009 10:49:15 -0000 2.23 +++ postinstall.cc 23 Jul 2010 17:34:30 -0000 @@ -64,7 +64,7 @@ private: class RunScript : public unary_function<Script const &, int> { public: - RunScript(const std::string& name, int num) : _num(num), _cnt(0) + RunScript(const std::string& name, int num) : _num(num), _cnt(0), _no_errors(TRUE) { Progress.SetText2 (name.c_str()); Progress.SetBar1 (_cnt, _num); @@ -80,16 +80,26 @@ public: retval = aScript.run(); ++_cnt; Progress.SetBar1 (_cnt, _num); + + if ((retval != 0) && (retval != -ERROR_INVALID_DATA)) + _no_errors = FALSE; + return retval; } + bool success(void) + { + return _no_errors; + } private: int _num; int _cnt; + bool _no_errors; }; -static void +static bool do_postinstall_thread (HINSTANCE h, HWND owner) { + bool success = TRUE; Progress.SetText1 ("Running..."); Progress.SetText2 (""); Progress.SetText3 (""); @@ -114,8 +124,8 @@ do_postinstall_thread (HINSTANCE h, HWND { packagemeta & pkg = **i; - for_each (pkg.installed.scripts().begin(), pkg.installed.scripts().end(), - RunScript(pkg.name, pkg.installed.scripts().size())); + success &= for_each (pkg.installed.scripts().begin(), pkg.installed.scripts().end(), + RunScript(pkg.name, pkg.installed.scripts().size())).success(); ++k; Progress.SetBar2 (k, numpkg); @@ -125,9 +135,10 @@ do_postinstall_thread (HINSTANCE h, HWND RunFindVisitor myVisitor (&scripts); Progress.SetBar1 (0, 1); Find (postinst).accept (myVisitor); - for_each (scripts.begin(), scripts.end(), - RunScript("No package", scripts.size())); + success &= for_each (scripts.begin(), scripts.end(), + RunScript("No package", scripts.size())).success(); Progress.SetBar2 (numpkg, numpkg); + return success; } static DWORD WINAPI @@ -138,7 +149,17 @@ do_postinstall_reflector (void *p) try { - do_postinstall_thread ((HINSTANCE) context[0], (HWND) context[1]); + if (!do_postinstall_thread ((HINSTANCE) context[0], (HWND) context[1])) + { + // one or more postinstall scripts failed to run successfully + // installation may be broken + MessageBox (NULL, + "You will need to investigate and correct these errors " + "before your Cygwin installation will function properly.\n" + "Check setup.log for details.", + "ERROR - postinstall scripts failed", + MB_OK | MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); + } // Tell the progress page that we're done running scripts Progress.PostMessage (WM_APP_POSTINSTALL_THREAD_COMPLETE); Index: script.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/script.cc,v retrieving revision 2.35 diff -u -p -r2.35 script.cc --- script.cc 26 Jun 2009 12:08:54 -0000 2.35 +++ script.cc 23 Jul 2010 17:34:30 -0000 @@ -285,11 +285,13 @@ Script::run() const if (retval) log(LOG_PLAIN) << "abnormal exit: exit code=" << retval << endLog; - /* if file exists then delete it otherwise just ignore no file error */ + /* if .done file exists then delete it otherwise just ignore no file error */ io_stream::remove ("cygfile://" + scriptName + ".done"); - io_stream::move ("cygfile://" + scriptName, - "cygfile://" + scriptName + ".done"); + /* don't rename the script as .done if it didn't run successfully */ + if (!retval) + io_stream::move ("cygfile://" + scriptName, + "cygfile://" + scriptName + ".done"); return retval; }