Setup: capturing postinstall output

Bradey Honsinger
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
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
succeeded is by looking at the output--this is kind of a problem.

I searched the list for "postinstall output" and "postinstall log" and
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
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:

    # This is /tmp/

        for file in /etc/postinstall/*.sh
            echo "Running $file:"
            sh $file
            mv $file $file.done
            echo "------------------------------------------"
    } > /var/log/postinstall.log 2>&1

The patch (which is against setup-, not the tip) is included below.

It worked for me with an existing Cygwin 1.3.10 install and the script above

in /tmp/ (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
    can't go in a shell script, so I just renamed it (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

  - The script has to come from somewhere. Since there
    a mandatory 'setup' package that could contain it, we'd either have to
    one or write it out from code (like in

  - 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
    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

- Bradey

[1] Look at
to see how to redirect a child process's standard input and output using the
Win32 API.

diff -ruN setup-
--- setup-	2002-05-12 04:28:22.000000000 -0700
+++ setup-
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/");
   io_stream::mkpath_p (PATH_TO_FILE, String("file://") + fname);
   if ((uexists ("/etc/passwd") || uexists ("/etc/passwd.lnk"))
@@ -304,9 +304,9 @@
   if (!p)
   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-
--- setup-	2002-05-18
20:07:52.000000000 -0700
+++ setup-
2002-06-26 16:30:52.000000000 -0700
@@ -22,32 +22,14 @@
 #include "dialog.h"
-#include "find.h"
 #include "mount.h"
 #include "script.h"
-#include "FindVisitor.h"
-class RunFindVisitor : public FindVisitor
-  RunFindVisitor (){}
-  virtual void visitFile(String const &basePath, const WIN32_FIND_DATA
-    {
-      run_script ("/etc/postinstall/", theFile->cFileName);
-    }
-  virtual ~ RunFindVisitor () {}
-  RunFindVisitor (RunFindVisitor const &);
-  RunFindVisitor & operator= (RunFindVisitor const &);
 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/", "" );

More information about the Cygwin-apps mailing list