On 10 Mar 2003, Robert Collins wrote: > On Wed, [EMAIL PROTECTED]:52, Igor Pechtchanski wrote: > > On 5 Mar 2003, Robert Collins wrote: > > > > Other than that, please expand to address all scripts. > > > Rob > > > > Rob, > > > > There is a design issue here that I'd like to address before I work more > > on this. I recall your comment that this should be tied into the logging > > subsystem. Unfortunately, this would involve a much more complex code, > > with pipes and forks. The same is true if we want "tee"-like behavior, > > i.e. windows popping up *and* output going to a file. The way this is > > implemented now is the output stream of the script process is tied to a > > file, but the limitation is that the file is written right away. Do we > > want a more complex design now, or should I just allow running a generic > > script with output going to a file (for the moment)? > > Igor > > Hmm, I'd like the following idiom: > generate to a file. > copy the file into the log buffer. > > That will get the postinstall scripts into the log. > > Howabout that? > Rob
Ok, here's the next iteration of this patch. It still pops a console with nothing in it when running postinstall scripts -- I'm sure there's a way to remove it, but can't find it at the moment. It does, however, correctly redirect the output of postinstall scripts into the LOG_BABBLE file. Most of the patch is OS-independent, but the output redirection mechanism has been tested on Win95 by Brian Keener (see <http://cygwin.com/ml/cygwin-apps/2003-03/msg00364.html>) and hasn't been changed in this patch. Igor P.S. Note that this patch conflicts slightly with my other patch (postinstall script ordering). Nothing a human can't fix, but both at once will not apply cleanly OOTB. Whichever one of them goes in first, I'll regenerate and resubmit the other one. ============================================================================== ChangeLog: 2003-03-13 Igor Pechtchanski <[EMAIL PROTECTED]> * script.cc (run): Add lname parameter. Redirect output of subprocess to file, creating the path if necessary. (run_script): Add optional to_log boolean parameter. If to_log, redirect output to temporary file. (openOutputLog): New helper function. (closeOutputLog): New helper function. (removeOutputLog): New helper function. * script.h (run_script): Add optional to_log parameter. * log.h (log_file): New function. * log.cc (log_file): New Function (BUFLEN): New #define. * postinstall.cc (RunFindVisitor::visitFile): Pass filename to run_script(). -- http://cs.nyu.edu/~pechtcha/ |\ _,,,---,,_ [EMAIL PROTECTED] ZZZzz /,`.-'`' -. ;-;;,_ [EMAIL PROTECTED] |,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski '---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow! Oh, boy, virtual memory! Now I'm gonna make myself a really *big* RAMdisk! -- /usr/games/fortune
Index: postinstall.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v retrieving revision 2.9 diff -u -p -r2.9 postinstall.cc --- postinstall.cc 19 May 2002 03:07:51 -0000 2.9 +++ postinstall.cc 13 Mar 2003 18:34:51 -0000 @@ -33,7 +33,7 @@ public: RunFindVisitor (){} virtual void visitFile(String const &basePath, const WIN32_FIND_DATA *theFile) { - run_script ("/etc/postinstall/", theFile->cFileName); + run_script ("/etc/postinstall/", theFile->cFileName, TRUE); } virtual ~ RunFindVisitor () {} protected: Index: log.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/log.cc,v retrieving revision 2.13 diff -u -p -r2.13 log.cc --- log.cc 27 Jun 2002 11:01:10 -0000 2.13 +++ log.cc 14 Mar 2003 17:12:21 -0000 @@ -36,6 +36,8 @@ static const char *cvsid = #include "io_stream.h" +#define BUFLEN 1000 + void log (enum log_level level, String const &message) { @@ -45,9 +47,38 @@ log (enum log_level level, String const void log (enum log_level level, const char *fmt, ...) { - char buf[1000]; + char buf[BUFLEN]; va_list args; va_start (args, fmt); - vsnprintf (buf, 1000, fmt, args); + vsnprintf (buf, BUFLEN, fmt, args); log (level, String(buf)); +} + +void +log_file (enum log_level level, String const &filename) +{ + char buf[BUFLEN]; + int num; + bool non_empty = false; + io_stream *f = io_stream::open(String("cygfile://") + filename, "rt"); + if (!f) + { + const char *err = strerror (errno); + if (!err) + err = "(unknown error)"; + note (NULL, IDS_ERR_OPEN_READ, filename.cstr_oneuse(), err); + return; + } + + std::ostream &out = LogSingleton::GetInstance()(level); + while ((num = f->read(buf, BUFLEN-1)) != 0) + { + buf[num] = '\0'; + out << buf; + non_empty = true; + } + if (non_empty) + out << endLog; + + delete f; } Index: log.h =================================================================== RCS file: /cvs/cygwin-apps/setup/log.h,v retrieving revision 2.5 diff -u -p -r2.5 log.h --- log.h 4 May 2002 12:15:56 -0000 2.5 +++ log.h 14 Mar 2003 17:12:21 -0000 @@ -23,3 +23,4 @@ void log (enum log_level level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); void log (enum log_level level, String const &); +void log_file (enum log_level level, String const &filename); Index: script.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/script.cc,v retrieving revision 2.4 diff -u -p -r2.4 script.cc --- script.cc 18 Feb 2002 13:53:07 -0000 2.4 +++ script.cc 14 Mar 2003 17:12:21 -0000 @@ -30,6 +30,8 @@ static const char *cvsid = #include "filemanip.h" #include "mount.h" #include "io_stream.h" +#include "script.h" +#include "mkdir.h" static String sh = String(); static const char *cmd = 0; @@ -78,13 +80,60 @@ init_run_script () } } +static BOOL +openOutputLog (HANDLE &file_out, String const &lname) +{ + SECURITY_ATTRIBUTES sa; + memset (&sa, 0, sizeof (sa)); + sa.nLength = sizeof (sa); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + if (mkdir_p (0, backslash (cygpath (lname)).cstr_oneuse())) + return FALSE; + + file_out = CreateFile (backslash (cygpath (lname)).cstr_oneuse(), + GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (file_out == INVALID_HANDLE_VALUE) + { + log (LOG_PLAIN, String ("Error: Unable to redirect output to '") + + lname + "'; using console"); + return FALSE; + } + + return TRUE; +} + +static void +closeOutputLog (HANDLE &file_out) +{ + if (file_out == INVALID_HANDLE_VALUE) + return; + + CloseHandle (file_out); +} + +static void +removeOutputLog (String const &lname) +{ + if (io_stream::remove (String ("cygfile://") + lname)) + { + log (LOG_PLAIN, String ("error: Unable to remove temporary file '") + + lname + "'"); + } +} + static void -run (const char *sh, const char *args, const char *file) +run (const char *sh, const char *args, const char *file, String const &lname) { BOOL b; char cmdline[_MAX_PATH]; STARTUPINFO si; PROCESS_INFORMATION pi; + HANDLE file_out = INVALID_HANDLE_VALUE; + DWORD dwCPFlags = CREATE_NEW_CONSOLE; + BOOL bInheritHandles = FALSE; sprintf (cmdline, "%s %s %s", sh, args, file); memset (&pi, 0, sizeof (pi)); @@ -93,34 +142,60 @@ run (const char *sh, const char *args, c si.lpTitle = (char *) "Cygwin Setup Post-Install Script"; si.dwFlags = STARTF_USEPOSITION; - b = CreateProcess (0, cmdline, 0, 0, 0, - CREATE_NEW_CONSOLE, 0, get_root_dir ().cstr_oneuse(), &si, &pi); + if (lname.size()) + if (openOutputLog (file_out, lname)) + { + bInheritHandles = TRUE; + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdOutput = file_out; + si.hStdError = file_out; + dwCPFlags = 0; + } + + b = CreateProcess (0, cmdline, 0, 0, bInheritHandles, + dwCPFlags, 0, get_root_dir ().cstr_oneuse(), &si, &pi); if (b) WaitForSingleObject (pi.hProcess, INFINITE); + + if (lname.size()) + closeOutputLog (file_out); } void -run_script (String const &dir, String const &fname) +run_script (String const &dir, String const &fname, BOOL to_log) { char *ext = strrchr (fname.cstr_oneuse(), '.'); if (!ext) return; + String lname = ""; + if (to_log) + { + char tmp_pat[] = "/var/log/setup.log.postinstallXXXXXXX"; + lname = String (mktemp(tmp_pat)); + } + if (sh.size() && strcmp (ext, ".sh") == 0) { String f2 = dir + fname; log (LOG_PLAIN, String ("running: ") + sh + " -c " + f2); - run (sh.cstr_oneuse(), "-c", f2.cstr_oneuse()); + run (sh.cstr_oneuse(), "-c", f2.cstr_oneuse(), lname); } else if (cmd && strcmp (ext, ".bat") == 0) { String f2 = backslash (cygpath (dir + fname)); log (LOG_PLAIN, String ("running: ") + cmd + " /c " + f2); - run (cmd, "/c", f2.cstr_oneuse()); + run (cmd, "/c", f2.cstr_oneuse(), lname); } else return; + + if (to_log) + { + log_file(LOG_BABBLE, lname); + removeOutputLog (lname); + } /* if file exists then delete it otherwise just ignore no file error */ io_stream::remove (String ("cygfile://") + dir + fname + ".done"); Index: script.h =================================================================== RCS file: /cvs/cygwin-apps/setup/script.h,v retrieving revision 2.2 diff -u -p -r2.2 script.h --- script.h 18 Feb 2002 12:35:23 -0000 2.2 +++ script.h 14 Mar 2003 17:12:21 -0000 @@ -21,7 +21,7 @@ we have a Bourne shell, execute it using sh. Otherwise, if fname has suffix .bat, execute using cmd */ -void run_script (String const &dir, String const &fname); +void run_script (String const &dir, String const &fname, BOOL to_log = FALSE); /* Initialisation stuff for run_script: sh, cmd, CYGWINROOT and PATH */ void init_run_script ();