[PATCH] Propagate exit codes of scripts to setup

Igor Pechtchanski pechtcha@cs.nyu.edu
Fri Aug 19 18:28:00 GMT 2005


As promised, here's a patch that makes Script::run() (and
try_run_script()) return the exit code of the script.  This just sets up
the infrastructure -- the exit code is currently ignored (well, logged),
but that could be changed later in both Installer::preremoveOne(),
packagemeta::uninstall(), and do_postinstall_thread().
As usual, the ChangeLog is below.
	Igor
==============================================================================
ChangeLog:
2005-08-19  Igor Pechtchanski  <pechtcha@cs.nyu.edu>

	* script.cc (run): Change to return the exit code or negative error.
	(Script::run): Ditto.
	(try_run_script): Receive both filename and extension and run only
	one script.  Also return the exit code.
	* script.h (try_run_script): Change signature.
	(Script::run): Ditto.
	* postinstall.cc (RunScript::operator()): Change to return the exit
	code or negative error.
	* install.cc (Installer::preremoveOne): Pass extension to
	try_run_script().
	* package_meta.cc (packagemeta::uninstall): Ditto.

-- 
				http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_		pechtcha@cs.nyu.edu
ZZZzz /,`.-'`'    -.  ;-;;,_		igor@watson.ibm.com
     |,4-  ) )-,_. ,\ (  `'-'		Igor Pechtchanski, Ph.D.
    '---''(_/--'  `-'\_) fL	a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

If there's any real truth it's that the entire multidimensional infinity
of the Universe is almost certainly being run by a bunch of maniacs. /DA
-------------- next part --------------
Index: install.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/install.cc,v
retrieving revision 2.76
diff -u -p -r2.76 install.cc
--- install.cc	14 May 2005 15:30:06 -0000	2.76
+++ install.cc	19 Aug 2005 18:14:43 -0000
@@ -143,7 +143,8 @@ Installer::preremoveOne (packagemeta & p
   Progress.SetText1 ("Running preremove script...");
   Progress.SetText2 (pkg.name.c_str());
   log (LOG_PLAIN) << "Running preremove script for  " << pkg.name << endLog;
-  try_run_script ("/etc/preremove/", pkg.name);
+  try_run_script ("/etc/preremove/", pkg.name, ".sh");
+  try_run_script ("/etc/preremove/", pkg.name, ".bat");
 }
 
 void
Index: package_meta.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/package_meta.cc,v
retrieving revision 2.48
diff -u -p -r2.48 package_meta.cc
--- package_meta.cc	14 May 2005 15:30:06 -0000	2.48
+++ package_meta.cc	19 Aug 2005 18:14:43 -0000
@@ -201,7 +201,8 @@ packagemeta::uninstall ()
         if (RemoveDirectory (d.c_str()))
           log (LOG_BABBLE) << "rmdir " << d << endLog;
       }
-      try_run_script ("/etc/postremove/", name);
+      try_run_script ("/etc/postremove/", name, ".sh");
+      try_run_script ("/etc/postremove/", name, ".bat");
     }
   installed = packageversion();
 }
Index: postinstall.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v
retrieving revision 2.19
diff -u -p -r2.19 postinstall.cc
--- postinstall.cc	5 May 2005 22:48:36 -0000	2.19
+++ postinstall.cc	19 Aug 2005 18:14:43 -0000
@@ -59,7 +59,7 @@ private:
   vector<Script> *_scripts;
 };
 
-class RunScript : public unary_function<Script const &, void>
+class RunScript : public unary_function<Script const &, int>
 {
 public:
   RunScript(String const &name, int num) : _num(num), _cnt(0)
@@ -71,12 +71,14 @@ public:
     {
       Progress.SetText3 ("");
     }
-  void operator() (Script const &aScript) 
+  int operator() (Script const &aScript) 
     {
+      int retval;
       Progress.SetText3 (aScript.fullName().c_str());
-      aScript.run();
+      retval = aScript.run();
       ++_cnt;
       Progress.SetBar1 (_cnt, _num);
+      return retval;
     }
 private:
   int _num;
Index: script.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/script.cc,v
retrieving revision 2.19
diff -u -p -r2.19 script.cc
--- script.cc	5 May 2005 22:48:36 -0000	2.19
+++ script.cc	19 Aug 2005 18:14:44 -0000
@@ -158,14 +158,16 @@ OutputLog::out_to(std::ostream &out)
   SetFilePointer(_handle, 0, NULL, FILE_END);
 }
 
-static void
+static int
 run (const char *sh, const char *args, const char *file, OutputLog &file_out)
 {
   char cmdline[MAX_PATH];
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   DWORD flags = CREATE_NEW_CONSOLE;
+  DWORD exitCode = 0;
   BOOL inheritHandles = FALSE;
+  BOOL exitCodeValid = FALSE;
 
   sprintf (cmdline, "%s %s %s", sh, args, file);
   memset (&pi, 0, sizeof (pi));
@@ -190,10 +192,15 @@ run (const char *sh, const char *args, c
 					flags, 0, get_root_dir ().c_str(),
 					&si, &pi);
 
-  if (createSucceeded)
+  if (createSucceeded) {
     WaitForSingleObject (pi.hProcess, INFINITE);
+    exitCodeValid = GetExitCodeProcess(pi.hProcess, &exitCode);
+  }
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
+  if (exitCodeValid)
+    return exitCode;
+  return -GetLastError();
 }
 
 char const *
@@ -202,14 +209,15 @@ Script::extension() const
   return strrchr (scriptName.c_str(), '.');
 }
 
-void
+int
 Script::run() const
 {
   if (!extension())
-    return;
+    return -ERROR_INVALID_DATA;
 
   BOOL to_log (TRUE);
   String log_name = "";
+  int retval = 0;
   if (to_log)
     {
       char tmp_pat[] = "/var/log/setup.log.postinstallXXXXXXX";
@@ -220,34 +228,38 @@ Script::run() const
   if (sh.size() && strcmp (extension(), ".sh") == 0)
     {
       log(LOG_PLAIN) << "running: " << sh << " -c " << scriptName << endLog;
-      ::run (sh.c_str(), "-c", scriptName.c_str(), file_out);
+      retval = ::run (sh.c_str(), "-c", scriptName.c_str(), file_out);
     }
   else if (cmd && strcmp (extension(), ".bat") == 0)
     {
       String windowsName = backslash (cygpath (scriptName));
       log(LOG_PLAIN) << "running: " << cmd << " /c " << windowsName << endLog;
-      ::run (cmd, "/c", windowsName.c_str(), file_out);
+      retval = ::run (cmd, "/c", windowsName.c_str(), file_out);
     }
   else
-    return;
+    return -ERROR_INVALID_DATA;
 
   if (to_log && !file_out.isEmpty ())
     log(LOG_BABBLE) << file_out << endLog;
 
+  if (!retval)
+    log(LOG_PLAIN) << "abnormal exit: exit code=" << retval << endLog;;
+
   /* if file exists then delete it otherwise just ignore no file error */
   io_stream::remove (String ("cygfile://") + scriptName + ".done");
 
   io_stream::move (String ("cygfile://") + scriptName,
                    String ("cygfile://") + scriptName + ".done");
+
+  return retval;
 }
 
-void
-try_run_script (String const &dir, String const &fname)
+int
+try_run_script (String const &dir, String const &fname, String const &ext)
 {
-  if (io_stream::exists (String ("cygfile://")+ dir + fname + ".sh"))
-    Script (dir + fname+ ".sh").run ();
-  if (io_stream::exists (String ("cygfile://")+ dir + fname + ".bat"))
-    Script (dir + fname+ ".bat").run ();
+  if (io_stream::exists (String ("cygfile://")+ dir + fname + ext))
+    return Script (dir + fname + ext).run ();
+  return NO_ERROR;
 }
 
 char const Script::ETCPostinstall[] = "/etc/postinstall/";
Index: script.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/script.h,v
retrieving revision 2.10
diff -u -p -r2.10 script.h
--- script.h	23 Jun 2003 20:49:00 -0000	2.10
+++ script.h	19 Aug 2005 18:14:44 -0000
@@ -20,8 +20,10 @@
 /* Initialisation stuff for run_script: sh, cmd, CYGWINROOT and PATH */
 void init_run_script ();
 
-/* Run the scripts fname.sh and fname.bat, found in dir. */
-void try_run_script (String const &dir, String const &fname);
+/* Run the scripts fname.sh and fname.bat, found in dir.
+   Returns the script exit status or negative error if any
+ */
+int try_run_script (String const &dir, String const &fname, String const &ext);
 
 class Script {
 public:
@@ -31,8 +33,10 @@ public:
   String fullName() const;
 /* Run the script.  If it it's suffix is .sh, and
    we have a Bourne shell, execute it using sh.  Otherwise, if the 
-   suffix is .bat, execute using cmd */
-  void run() const;
+   suffix is .bat, execute using cmd.
+   Returns the exit status of the process, or negative error if any
+ */
+  int run() const;
 private:
   String scriptName;
   static char const ETCPostinstall[];


More information about the Cygwin-apps mailing list