From 876da2249715aa8495343d8a9b1dd9b4a08fc91d Mon Sep 17 00:00:00 2001 From: John Darrington Date: Wed, 30 Oct 2013 20:47:07 +0100 Subject: [PATCH] Fix problem with non-reentrant journal driver --- src/output/journal.c | 100 +++++++++++++++++------------- src/output/journal.h | 1 + src/ui/gui/psppire.c | 2 +- src/ui/terminal/terminal-reader.c | 2 +- 4 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/output/journal.c b/src/output/journal.c index c1d246360f..84d0cd9222 100644 --- a/src/output/journal.c +++ b/src/output/journal.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2010, 2012 Free Software Foundation, Inc. + Copyright (C) 2007, 2010, 2012, 2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include #include #include +#include #include "data/file-name.h" #include "libpspp/cast.h" @@ -44,12 +45,13 @@ struct journal_driver /* Name of journal file. */ char *file_name; + bool destroyed; }; static const struct output_driver_class journal_class; /* Journal driver, if journaling is enabled. */ -static struct journal_driver *journal; +static struct journal_driver journal; static struct journal_driver * @@ -62,13 +64,14 @@ journal_driver_cast (struct output_driver *driver) static void journal_close (void) { - if (journal != NULL && journal->file != NULL) + if (journal.file != NULL) { - if (fwriteerror (journal->file)) + if (fwriteerror (journal.file)) msg_error (errno, _("error writing output file `%s'"), - journal->file_name); - journal->file = NULL; - } + journal.file_name); + + } + journal.file = NULL; } static void @@ -76,27 +79,20 @@ journal_destroy (struct output_driver *driver) { struct journal_driver *j = journal_driver_cast (driver); - journal_close (); - free (j->command_name); - free (j); + if ( !j->destroyed) + { + journal_close (); + free (j->command_name); + } - journal = NULL; + j->destroyed = true; } static void journal_output (struct journal_driver *j, const char *s) { - if (j->file == NULL) - { - j->file = fopen (journal_get_file_name (), "a"); - if (j->file == NULL) - { - msg_error (errno, _("error opening output file `%s'"), - journal_get_file_name ()); - output_driver_destroy (&j->driver); - return; - } - } + if ( j->file == NULL) + return; fprintf (j->file, "%s\n", s); @@ -138,38 +134,56 @@ static const struct output_driver_class journal_class = journal_submit, NULL /* flush */ }; + + /* Enables journaling. */ void -journal_enable (void) +journal_init (void) { - if (journal == NULL) - { - /* Create journal driver. */ - journal = xzalloc (sizeof *journal); - output_driver_init (&journal->driver, &journal_class, "journal", - SETTINGS_DEVICE_UNFILTERED); - journal->file = NULL; - journal->command_name = NULL; - - /* Register journal driver. */ - output_driver_register (&journal->driver); - } + /* Create journal driver. */ + output_driver_init (&journal.driver, &journal_class, "journal", + SETTINGS_DEVICE_UNFILTERED); + journal.file = NULL; + journal.command_name = NULL; + + /* Register journal driver. */ + output_driver_register (&journal.driver); + + journal_enable (); + journal.destroyed = false; } /* Disables journaling. */ void journal_disable (void) { - if (journal != NULL) - output_driver_destroy (&journal->driver); + journal_close (); +} + + +/* Enable journaling. */ +void +journal_enable (void) +{ + if (journal.file == NULL) + { + journal.file = fopen (journal_get_file_name (), "a"); + if (journal.file == NULL) + { + msg_error (errno, _("error opening output file `%s'"), + journal_get_file_name ()); + journal_close (); + } + } } + /* Returns true if journaling is enabled, false otherwise. */ bool journal_is_enabled (void) { - return journal != NULL; + return journal.file != NULL ; } /* Sets the name of the journal file to FILE_NAME. */ @@ -177,8 +191,8 @@ void journal_set_file_name (const char *file_name) { journal_close (); - free (journal->file_name); - journal->file_name = xstrdup (file_name); + free (journal.file_name); + journal.file_name = xstrdup (file_name); } /* Returns the name of the journal file. The caller must not modify or free @@ -186,10 +200,10 @@ journal_set_file_name (const char *file_name) const char * journal_get_file_name (void) { - if (journal->file_name == NULL) + if (journal.file_name == NULL) { const char *output_path = default_output_path (); - journal->file_name = xasprintf ("%s%s", output_path, "pspp.jnl"); + journal.file_name = xasprintf ("%s%s", output_path, "pspp.jnl"); } - return journal->file_name; + return journal.file_name; } diff --git a/src/output/journal.h b/src/output/journal.h index 377152d5ce..6571e95272 100644 --- a/src/output/journal.h +++ b/src/output/journal.h @@ -26,6 +26,7 @@ #include +void journal_init (void); void journal_enable (void); void journal_disable (void); bool journal_is_enabled (void); diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 512239e92a..91640fe9cf 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -94,7 +94,7 @@ initialize (const char *data_file) psppire_output_window_setup (); - journal_enable (); + journal_init (); textdomain (PACKAGE); psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry); diff --git a/src/ui/terminal/terminal-reader.c b/src/ui/terminal/terminal-reader.c index 2f11279bf4..c80a6131de 100644 --- a/src/ui/terminal/terminal-reader.c +++ b/src/ui/terminal/terminal-reader.c @@ -99,7 +99,7 @@ welcome (void) "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show " "warranty.\" for details.\n", stdout); puts (stat_version); - journal_enable (); + journal_init (); } static struct terminal_reader * -- 2.30.2