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" ); }