/* Messages logging.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008 Free Software Foundation, Inc.
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GNU Wget.
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include "utils.h"
#include "log.h"
-/* This file impplement support for "logging". Logging means printing
+/* 2005-10-25 SMS.
+ VMS log files are often VFC record format, not stream, so fputs() can
+ produce multiple records, even when there's no newline terminator in
+ the buffer. The result is unsightly output with spurious newlines.
+ Using fprintf() instead of fputs(), along with inhibiting some
+ fflush() activity below, seems to solve the problem.
+*/
+#ifdef __VMS
+# define FPUTS( s, f) fprintf( (f), "%s", (s))
+#else /* def __VMS */
+# define FPUTS( s, f) fputs( (s), (f))
+#endif /* def __VMS [else] */
+
+/* This file implements support for "logging". Logging means printing
output, plus several additional features:
- Cataloguing output by importance. You can specify that a log
logging is inhibited, logfp is set back to NULL. */
static FILE *logfp;
+/* A second file descriptor pointing to the temporary log file for the
+ WARC writer. If WARC writing is disabled, this is NULL. */
+static FILE *warclogfp;
+
/* If true, it means logging is inhibited, i.e. nothing is printed or
stored. */
static bool inhibit_logging;
return logfp;
return stderr;
}
+
+/* Returns the file descriptor for the secondary log file. This is
+ WARCLOGFP, except if called before log_init, in which case it
+ returns stderr. This is useful in case someone calls a logging
+ function before log_init.
+
+ If logging is inhibited, return NULL. */
+
+static FILE *
+get_warc_log_fp (void)
+{
+ if (inhibit_logging)
+ return NULL;
+ if (warclogfp)
+ return warclogfp;
+ return NULL;
+}
+
+/* Sets the file descriptor for the secondary log file. */
+
+void
+log_set_warc_log_fp (FILE * fp)
+{
+ warclogfp = fp;
+}
\f
/* Log a literal string S. The string is logged as-is, without a
newline appended. */
logputs (enum log_options o, const char *s)
{
FILE *fp;
+ FILE *warcfp;
check_redirect_output ();
if ((fp = get_log_fp ()) == NULL)
return;
+ warcfp = get_warc_log_fp ();
CHECK_VERBOSE (o);
- fputs (s, fp);
+ FPUTS (s, fp);
+ if (warcfp != NULL)
+ FPUTS (s, warcfp);
if (save_context_p)
saved_append (s);
if (flush_log_p)
int available_size = sizeof (smallmsg);
int numwritten;
FILE *fp = get_log_fp ();
+ FILE *warcfp = get_warc_log_fp ();
- if (!save_context_p)
+ if (!save_context_p && warcfp == NULL)
{
/* In the simple case just call vfprintf(), to avoid needless
allocation and games with vsnprintf(). */
}
/* Writing succeeded. */
- saved_append (write_ptr);
- fputs (write_ptr, fp);
+ if (save_context_p)
+ saved_append (write_ptr);
+ FPUTS (write_ptr, fp);
+ if (warcfp != NULL)
+ FPUTS (write_ptr, warcfp);
if (state->bigmsg)
xfree (state->bigmsg);
logflush (void)
{
FILE *fp = get_log_fp ();
+ FILE *warcfp = get_warc_log_fp ();
if (fp)
- fflush (fp);
+ {
+/* 2005-10-25 SMS.
+ On VMS, flush only for a terminal. See note at FPUTS macro, above.
+*/
+#ifdef __VMS
+ if (isatty( fileno( fp)))
+ {
+ fflush (fp);
+ }
+#else /* def __VMS */
+ fflush (fp);
+#endif /* def __VMS [else] */
+ }
+
+ if (warcfp != NULL)
+ fflush (warcfp);
+
needs_flushing = false;
}
va_start (args, fmt);
done = log_vprintf_internal (&lpstate, fmt, args);
va_end (args);
+
+ if (done && errno == EPIPE)
+ exit (1);
}
while (!done);
}
}
}
-/* Close LOGFP, inhibit further logging and free the memory associated
- with it. */
+/* Close LOGFP (only if we opened it, not if it's stderr), inhibit
+ further logging and free the memory associated with it. */
void
log_close (void)
{
int i;
- if (logfp)
+ if (logfp && (logfp != stderr))
fclose (logfp);
logfp = NULL;
inhibit_logging = true;
{
int num = log_line_current;
FILE *fp = get_log_fp ();
+ FILE *warcfp = get_warc_log_fp ();
if (!fp)
return;
{
struct log_ln *ln = log_lines + num;
if (ln->content)
- fputs (ln->content, fp);
+ {
+ FPUTS (ln->content, fp);
+ if (warcfp != NULL)
+ FPUTS (ln->content, warcfp);
+ }
ROT_ADVANCE (num);
}
while (num != log_line_current);
if (trailing_line)
if (log_lines[log_line_current].content)
- fputs (log_lines[log_line_current].content, fp);
+ {
+ FPUTS (log_lines[log_line_current].content, fp);
+ if (warcfp != NULL)
+ FPUTS (log_lines[log_line_current].content, warcfp);
+ }
fflush (fp);
+ fflush (warcfp);
}
\f
/* String escape functions. */