Index: script.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/script.cc,v retrieving revision 2.6 diff -u -p -r2.6 script.cc --- script.cc 17 Mar 2003 22:23:33 -0000 2.6 +++ script.cc 18 Mar 2003 15:50:02 -0000 @@ -26,11 +26,12 @@ static const char *cvsid = #include #include #include -#include "log.h" +#include "LogSingleton.h" #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; @@ -79,12 +80,92 @@ init_run_script () } } +class OutputLog +{ +public: + OutputLog (String const &filename); + ~OutputLog (); + HANDLE handle () { return _handle; } + BOOL isValid () { return _handle != INVALID_HANDLE_VALUE; } + BOOL isEmpty () { return GetFileSize (_handle, NULL) == 0; } + friend std::ostream &operator<< (std::ostream &, OutputLog &); +private: + enum { BUFLEN = 1000 }; + HANDLE _handle; + String _filename; + void out_to(std::ostream &); +}; + +OutputLog::OutputLog (String const &filename) + : _handle(INVALID_HANDLE_VALUE), _filename(filename) +{ + if (!_filename.size()) + return; + + SECURITY_ATTRIBUTES sa; + memset (&sa, 0, sizeof (sa)); + sa.nLength = sizeof (sa); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + if (mkdir_p (0, backslash (cygpath (_filename)).cstr_oneuse())) + return; + + _handle = CreateFile (backslash (cygpath (_filename)).cstr_oneuse(), + GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (_handle == INVALID_HANDLE_VALUE) + { + log(LOG_PLAIN) << "error: Unable to redirect output to '" << _filename + << "'; using console" << endLog; + } +} + +OutputLog::~OutputLog () +{ + if (_handle != INVALID_HANDLE_VALUE) + CloseHandle (_handle); + if (_filename.size() && + !DeleteFile(backslash (cygpath (_filename)).cstr_oneuse())) + { + log(LOG_PLAIN) << "error: Unable to remove temporary file '" << _filename + << "'" << endLog; + } +} + +std::ostream & +operator<< (std::ostream &out, OutputLog &log) +{ + log.out_to(out); + return out; +} + +void +OutputLog::out_to(std::ostream &out) +{ + char buf[BUFLEN]; + DWORD num; + FlushFileBuffers (_handle); + SetFilePointer(_handle, 0, NULL, FILE_BEGIN); + + while (ReadFile(_handle, buf, BUFLEN-1, &num, NULL) && num != 0) + { + buf[num] = '\0'; + out << buf; + } + + SetFilePointer(_handle, 0, NULL, FILE_END); +} + static void -run (const char *sh, const char *args, const char *file) +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; + BOOL inheritHandles = FALSE; sprintf (cmdline, "%s %s %s", sh, args, file); memset (&pi, 0, sizeof (pi)); @@ -93,8 +174,26 @@ run (const char *sh, const char *args, c si.lpTitle = (char *) "Cygwin Setup Post-Install Script"; si.dwFlags = STARTF_USEPOSITION; - BOOL createSucceeded = CreateProcess (0, cmdline, 0, 0, 0, - CREATE_NEW_CONSOLE, 0, get_root_dir ().cstr_oneuse(), &si, &pi); + if (file_out.isValid ()) + { + inheritHandles = TRUE; + si.dwFlags |= STARTF_USESTDHANDLES; + si.hStdInput = GetStdHandle (STD_INPUT_HANDLE); + si.hStdOutput = file_out.handle (); + si.hStdError = file_out.handle (); + si.dwFlags |= STARTF_USESHOWWINDOW; +#if 0 + si.wShowWindow = SW_HIDE; + flags = CREATE_NO_WINDOW; // Note: might not work on Win9x +#else + // TODO: introduce a script progress tracker and use the above + si.wShowWindow = SW_MINIMIZE; +#endif + } + + BOOL createSucceeded = CreateProcess (0, cmdline, 0, 0, inheritHandles, + flags, 0, get_root_dir ().cstr_oneuse(), + &si, &pi); if (createSucceeded) WaitForSingleObject (pi.hProcess, INFINITE); @@ -103,26 +202,37 @@ run (const char *sh, const char *args, c } 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 log_name = ""; + if (to_log) + { + char tmp_pat[] = "/var/log/setup.log.postinstallXXXXXXX"; + log_name = String (mktemp(tmp_pat)); + } + OutputLog file_out(log_name); + 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()); + log(LOG_PLAIN) << "running: " << sh << " -c " << f2 << endLog; + run (sh.cstr_oneuse(), "-c", f2.cstr_oneuse(), file_out); } 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()); + log(LOG_PLAIN) << "running: " << cmd << " /c " << f2 << endLog; + run (cmd, "/c", f2.cstr_oneuse(), file_out); } else return; + + if (to_log && !file_out.isEmpty ()) + log(LOG_BABBLE) << file_out << endLog; /* 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.3 diff -u -p -r2.3 script.h --- script.h 17 Mar 2003 22:23:33 -0000 2.3 +++ script.h 18 Mar 2003 15:50:02 -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 (); Index: postinstall.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v retrieving revision 2.10 diff -u -p -r2.10 postinstall.cc --- postinstall.cc 17 Mar 2003 22:23:33 -0000 2.10 +++ postinstall.cc 18 Mar 2003 15:50:02 -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: @@ -56,7 +56,7 @@ do_postinstall (HINSTANCE h, HWND owner) packagemeta & pkg = **i; if (pkg.installed) for (std::vector