[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