Setup: capturing postinstall output
Bradey Honsinger
BradeyH@construx.com
Thu Jun 27 02:49:00 GMT 2002
Being able to run package-specific postinstall scripts is pretty nifty, but
one drawback is that the output of those scripts is lost. It flickers by in
console windows as setup finishes, but that's pretty much unreadable, at
least
on my system. Since some packages (like apache-mod*) aren't really installed
unless their postinstall script succeeds--and the only way to tell whether
it
succeeded is by looking at the output--this is kind of a problem.
I searched the list for "postinstall output" and "postinstall log" and
didn't
find anything, so I decided to have a go at it myself. Given the complexity
of redirecting child processes' stdin/stdout/stderr using Win32[1], it
seemed
like the simplest solution was to make bash do the redirection, so I wrote a
little script and patched setup to call it instead of running the
postinstall scripts directly. It's a little less cool than the current
implementation--no opportunity to use the Visitor pattern!--but to my
Unix-centric mind, it seems just as elegant.
The script is pretty simple:
#!/bin/sh
# This is /tmp/run-postinstall.sh
{
for file in /etc/postinstall/*.sh
do
echo "Running $file:"
sh $file
mv $file $file.done
echo "------------------------------------------"
done
} > /var/log/postinstall.log 2>&1
The patch (which is against setup-2.249.2.4, not the tip) is included below.
It worked for me with an existing Cygwin 1.3.10 install and the script above
in /tmp/run-postinstall.sh (although I had to make some minor changes to get
setup to build). I haven't yet tried it with a 'clean' install. YMMV.
There are a couple of considerations:
- This script doesn't run .bat files, while the current code does.
The only .bat postinstall script that I saw was passwd-grp.bat (and I
installed pretty much everything). There's nothing in passwd-grp.bat
that
can't go in a shell script, so I just renamed it passwd-grp.sh (this is
included in the patch). Not allowing .bat postinstalls would, of course,
have to be a well-considered policy change by whoever considers these
things.
- The run-postinstall.sh script has to come from somewhere. Since there
isn't
a mandatory 'setup' package that could contain it, we'd either have to
make
one or write it out from code (like passwd-grp.sh in desktop.cc).
- This doesn't really solve the problem of failed postinstall scripts. It
would be nice to require postinstall scripts to exit non-zero if they
fail,
and then have setup notify the user. This script does at least allow the
user to _detect_ that a postinstall script failed, though, which is a
start.
- Bradey
[1] Look at
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/pr
othred_4uus.asp>
to see how to redirect a child process's standard input and output using the
Win32 API.
diff -ruN setup-2.249.2.4/setup-0/desktop.cc
setup-2.249.2.4-capture-postinstall-output/setup-0/desktop.cc
--- setup-2.249.2.4/setup-0/desktop.cc 2002-05-12 04:28:22.000000000 -0700
+++ setup-2.249.2.4-capture-postinstall-output/setup-0/desktop.cc
2002-06-26 16:49:03.000000000 -0700
@@ -278,7 +278,7 @@
static void
make_passwd_group ()
{
- String fname = cygpath ("/etc/postinstall/passwd-grp.bat");
+ String fname = cygpath ("/etc/postinstall/passwd-grp.sh");
io_stream::mkpath_p (PATH_TO_FILE, String("file://") + fname);
if ((uexists ("/etc/passwd") || uexists ("/etc/passwd.lnk"))
@@ -304,9 +304,9 @@
if (!p)
return;
if (!(uexists ("/etc/passwd") || uexists ("/etc/passwd.lnk")))
- fprintf (p, "bin\\mkpasswd -l > etc\\passwd\n");
+ fprintf (p, "bin/mkpasswd -l > etc/passwd\n");
if (!(uexists ("/etc/group") || uexists ("/etc/group.lnk")))
- fprintf (p, "bin\\mkgroup -l > etc\\group\n");
+ fprintf (p, "bin/mkgroup -l > etc/group\n");
fclose (p);
}
diff -ruN setup-2.249.2.4/setup-0/postinstall.cc
setup-2.249.2.4-capture-postinstall-output/setup-0/postinstall.cc
--- setup-2.249.2.4/setup-0/postinstall.cc 2002-05-18
20:07:52.000000000 -0700
+++ setup-2.249.2.4-capture-postinstall-output/setup-0/postinstall.cc
2002-06-26 16:30:52.000000000 -0700
@@ -22,32 +22,14 @@
#endif
#include "dialog.h"
-#include "find.h"
#include "mount.h"
#include "script.h"
-#include "FindVisitor.h"
-class RunFindVisitor : public FindVisitor
-{
-public:
- RunFindVisitor (){}
- virtual void visitFile(String const &basePath, const WIN32_FIND_DATA
*theFile)
- {
- run_script ("/etc/postinstall/", theFile->cFileName);
- }
- virtual ~ RunFindVisitor () {}
-protected:
- RunFindVisitor (RunFindVisitor const &);
- RunFindVisitor & operator= (RunFindVisitor const &);
-};
-
void
do_postinstall (HINSTANCE h, HWND owner)
{
next_dialog = 0;
init_run_script ();
SetCurrentDirectory (get_root_dir ().cstr_oneuse());
- RunFindVisitor myVisitor;
- String postinst = cygpath ("/etc/postinstall");
- Find (postinst).accept (myVisitor);
+ run_script ("/tmp/", "run-postinstall.sh" );
}
More information about the Cygwin-apps
mailing list