public inbox for cygwin-apps@cygwin.com
 help / color / mirror / Atom feed
From: Jon Turney <jon.turney@dronecode.org.uk>
To: cygwin-apps@cygwin.com
Cc: Jon Turney <jon.turney@dronecode.org.uk>
Subject: [PATCH setup 05/16] Don't call Antivirus::AtExit() directly from Logger::exit()
Date: Fri,  8 Mar 2024 18:34:24 +0000	[thread overview]
Message-ID: <20240308183440.4263-6-jon.turney@dronecode.org.uk> (raw)
In-Reply-To: <20240308183440.4263-1-jon.turney@dronecode.org.uk>

The call to Antivirus::AtExit() needs to be take place before we write
the log, so we see in the log if it failed. But calling it directly from
Logger::exit() is a horrible layering violation, which makes it
impossible to use the logger in other executables...

Add LogFile::atexit() method, which registers atexit handlers which are
run by LogFile::exit() before the log is closed.

The real solution here is probably not to exit via Logger::exit() all
over the place. And also perhaps to switch logfile writing from
"defered" to "immediate" once the root directory has been selected
(which establishes where the logfile should be written).

Also update a comment, out of date since 5fa64c3c.
---
 AntiVirus.cc |  4 ++--
 LogFile.cc   | 18 +++++++++++++-----
 LogFile.h    |  8 ++++++--
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/AntiVirus.cc b/AntiVirus.cc
index cc416cc..cb8e8ee 100644
--- a/AntiVirus.cc
+++ b/AntiVirus.cc
@@ -16,8 +16,7 @@
 #include "AntiVirus.h"
 
 #include "getopt++/BoolOption.h"
-
-#include "LogSingleton.h"
+#include "LogFile.h"
 
 #include "win32.h"
 #include <stdio.h>
@@ -77,6 +76,7 @@ bool
 AntiVirusPage::Create ()
 {
     detect();
+    Logger().atexit(AntiVirus::AtExit);
     return PropertyPage::Create (NULL, dialog_cmd, IDD_VIRUS);
 }
 
diff --git a/LogFile.cc b/LogFile.cc
index ab2e3ec..0022eff 100644
--- a/LogFile.cc
+++ b/LogFile.cc
@@ -28,7 +28,6 @@
 #include <time.h>
 #include <string>
 #include <stdexcept>
-#include "AntiVirus.h"
 #include "filemanip.h"
 #include "String++.h"
 #include "getopt++/BoolOption.h"
@@ -115,12 +114,21 @@ LogFile::getFileName (int level) const
   return "<no log was in use>";
 }
 
+void
+LogFile::atexit(void (*func)(void))
+{
+  exit_fns.push_back(func);
+}
+
 void
 LogFile::exit (int exit_code, bool show_end_install_msg)
 {
-  AntiVirus::AtExit();
+  /* Execute any functions we want to run at exit (we don't use stdlib atexit()
+     because we want to allow them to potentially write to the log) */
+  for (auto i = exit_fns.rbegin(); i != exit_fns.rend(); ++i)
+      (*i)();
+
   static int been_here = 0;
-  /* Exitcode -1 is special... */
   if (been_here)
     ::exit (exit_code);
   been_here = 1;
@@ -132,8 +140,8 @@ LogFile::exit (int exit_code, bool show_end_install_msg)
       Log (LOG_PLAIN) << "note: " << wstring_to_string(buf) << endLog;
     }
 
-  /* ... in that it skips the boring log messages.  Exit code -1 is used when
-     just printing the help output and when we're self-elevating. */
+  /* Skip the log messages when just printing the help/version output, and when
+     we're self-elevating. */
   if (show_end_install_msg)
     Log (LOG_TIMESTAMP) << "Ending cygwin install" << endLog;
 
diff --git a/LogFile.h b/LogFile.h
index ddbc2dc..8efa1b0 100644
--- a/LogFile.h
+++ b/LogFile.h
@@ -18,6 +18,7 @@
 
 #include "LogSingleton.h"
 #include <sstream>
+#include <vector>
 
 // Logging class. Default logging level is PLAIN.
 class LogFile : public LogSingleton {
@@ -36,18 +37,21 @@ public:
    * but doesn't call generic C++ destructors
    */
   virtual void exit (int exit_code, bool show_end_install_msg = true)
-	  __attribute__ ((noreturn));
+          __attribute__ ((noreturn));
+  virtual void atexit( void (*func)(void));
+
   virtual void flushAll ();
   virtual ~LogFile();
   // get a specific verbosity stream.
   virtual std::ostream &operator() (enum log_level level);
-  
+
 protected:
   LogFile(std::stringbuf *aStream);
   LogFile (LogFile const &); // no copy constructor
   LogFile &operator = (LogFile const&); // no assignment operator
   virtual void endEntry(); // the current in-progress entry is complete.
   static int exit_msg;
+  std::vector <void (*)(void)> exit_fns;
 private:
   void log_save (int babble, const std::string& filename, bool append);
 };
-- 
2.43.0


  parent reply	other threads:[~2024-03-08 18:35 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-08 18:34 [PATCH setup 00/16] Groundwork for a GUI-less installation tool Jon Turney
2024-03-08 18:34 ` [PATCH setup 01/16] Drop forward declaration of non-existent class IniState Jon Turney
2024-03-08 18:34 ` [PATCH setup 02/16] Move setup_exts[] to the only place it's used Jon Turney
2024-03-08 18:34 ` [PATCH setup 03/16] Split GuiParseFeedback out from ini fetcher Jon Turney
2024-03-08 18:34 ` [PATCH setup 04/16] Split out site into SiteSettings and SitePage Jon Turney
2024-03-08 18:34 ` Jon Turney [this message]
2024-03-08 18:34 ` [PATCH setup 06/16] Simplify invocation of UserSettings::open_settings() Jon Turney
2024-03-08 18:34 ` [PATCH setup 07/16] Split out URL fetching progress reporting Jon Turney
2024-03-08 18:34 ` [PATCH setup 08/16] Instantiate found_ini_list in ini.cc Jon Turney
2024-03-08 18:34 ` [PATCH setup 09/16] Move is_64bit to state Jon Turney
2024-03-08 18:34 ` [PATCH setup 10/16] Move setup.ini pathame components to ini.cc Jon Turney
2024-03-08 18:34 ` [PATCH setup 11/16] Drop hinstance global Jon Turney
2024-03-08 18:34 ` [PATCH setup 12/16] Spit out GetNetAuth from NetIO Jon Turney
2024-03-08 18:34 ` [PATCH setup 13/16] Split out hash checking progress reporting Jon Turney
2024-03-08 18:34 ` [PATCH setup 14/16] Push check_for_cached into package_source Jon Turney
2024-03-08 18:34 ` [PATCH setup 15/16] Put various shared subcomponents into a convenience library Jon Turney
2024-03-08 18:34 ` [PATCH setup 16/16] Add beginnings of a command line installation tool Jon Turney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240308183440.4263-6-jon.turney@dronecode.org.uk \
    --to=jon.turney@dronecode.org.uk \
    --cc=cygwin-apps@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).