summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qlogging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qlogging.cpp')
-rw-r--r--src/corelib/global/qlogging.cpp112
1 files changed, 63 insertions, 49 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 323c86f511..2a4f2dd4d6 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
+** Copyright (C) 2014 Intel Corporation.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -46,6 +47,7 @@
#include "qcoreapplication.h"
#include "qthread.h"
#include "private/qloggingregistry_p.h"
+#include "private/qcoreapplication_p.h"
#endif
#ifdef Q_OS_WIN
#include <qt_windows.h>
@@ -62,7 +64,12 @@
# define SD_JOURNAL_SUPPRESS_LOCATION
# include <systemd/sd-journal.h>
# include <syslog.h>
+#endif
+#ifdef Q_OS_UNIX
+# include <sys/types.h>
+# include <sys/stat.h>
# include <unistd.h>
+# include "private/qcore_unix_p.h"
#endif
#if !defined QT_NO_REGULAREXPRESSION && !defined(QT_BOOTSTRAPPED)
@@ -109,32 +116,54 @@ static bool isFatal(QtMsgType msgType)
return false;
}
-#ifdef Q_OS_WIN
-
-// Do we have stderr for QDebug? - Either there is a console or we are running
-// with redirected stderr.
-# if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
-static inline bool hasStdErr()
+static bool willLogToConsole()
{
- if (GetConsoleWindow())
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
+ // these systems have no stderr, so always log to the system log
+ return false;
+#elif defined(QT_BOOTSTRAPPED)
+ return true;
+#else
+ // rules to determine if we'll log preferably to the console:
+ // 1) if QT_LOGGING_TO_CONSOLE is set, it determines behavior:
+ // - if it's set to 0, we will not log to console
+ // - if it's set to 1, we will log to console
+ // 2) otherwise, we will log to console if we have a console window (Windows)
+ // or a controlling TTY (Unix). This is done even if stderr was redirected
+ // to the blackhole device (NUL or /dev/null).
+
+ bool ok = true;
+ uint envcontrol = qgetenv("QT_LOGGING_TO_CONSOLE").toUInt(&ok);
+ if (ok)
+ return envcontrol;
+
+# ifdef Q_OS_WIN
+ return GetConsoleWindow();
+# elif defined(Q_OS_UNIX)
+ // if /dev/tty exists, we can only open it if we have a controlling TTY
+ int devtty = qt_safe_open("/dev/tty", O_RDONLY);
+ if (devtty == -1 && (errno == ENOENT || errno == EPERM)) {
+ // no /dev/tty, fall back to isatty on stderr
+ return isatty(STDERR_FILENO);
+ } else if (devtty != -1) {
+ // there is a /dev/tty and we could open it: we have a controlling TTY
+ qt_safe_close(devtty);
return true;
- STARTUPINFO info;
- GetStartupInfo(&info);
- return (info.dwFlags & STARTF_USESTDHANDLES) && info.hStdError
- && info.hStdError != INVALID_HANDLE_VALUE;
-}
-# endif // !Q_OS_WINCE && !Q_OS_WINRT
+ }
-Q_CORE_EXPORT bool qWinLogToStderr()
-{
-# if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
- static const bool result = hasStdErr();
- return result;
-# else
+ // no controlling TTY
return false;
+# else
+# error "Not Unix and not Windows?"
# endif
+#endif
+}
+
+Q_CORE_EXPORT bool qt_logging_to_console()
+{
+ static const bool logToConsole = willLogToConsole();
+ return logToConsole;
}
-#endif // Q_OS_WIN
/*!
\class QMessageLogContext
@@ -145,6 +174,9 @@ Q_CORE_EXPORT bool qWinLogToStderr()
The class provides information about the source code location a qDebug(), qWarning(),
qCritical() or qFatal() message was generated.
+ \note By default, this information is recorded only in debug builds. You can overwrite
+ this explicitly by defining \c QT_MESSAGELOGCONTEXT or \c{QT_NO_MESSAGELOGCONTEXT}.
+
\sa QMessageLogger, QtMessageHandler, qInstallMessageHandler()
*/
@@ -156,8 +188,9 @@ Q_CORE_EXPORT bool qWinLogToStderr()
QMessageLogger is used to generate messages for the Qt logging framework. Usually one uses
it through qDebug(), qWarning(), qCritical, or qFatal() functions,
- which are actually macros that expand to QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()
- et al.
+ which are actually macros: For example qDebug() expands to
+ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()
+ for debug builds, and QMessageLogger(0, 0, 0).debug() for release builds.
One example of direct use is to forward errors that stem from a scripting language, e.g. QML:
@@ -977,7 +1010,7 @@ void QMessagePattern::setPattern(const QString &pattern)
OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16()));
if (0)
#elif defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
- if (!qWinLogToStderr()) {
+ if (!qt_logging_to_console()) {
OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16()));
} else
#endif
@@ -1269,44 +1302,25 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
{
QString logMessage = qFormatLogMessage(type, context, buf);
-#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
- if (!qWinLogToStderr()) {
+ if (!qt_logging_to_console()) {
+#if defined(Q_OS_WIN)
OutputDebugString(reinterpret_cast<const wchar_t *>(logMessage.utf16()));
return;
- }
-#endif // Q_OS_WIN
-
- static const bool logToConsole = qEnvironmentVariableIsSet("QT_LOGGING_TO_CONSOLE");
-#if defined(QT_USE_SLOG2)
- if (!logToConsole) {
+#elif defined(QT_USE_SLOG2)
slog2_default_handler(type, logMessage.toLocal8Bit().constData());
- } else {
- fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
- fflush(stderr);
- }
+ return;
#elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
- // We support environment variables for Qt Creator use, or more complicated cases
- // like subprocesses.
- if (!logToConsole) {
// remove trailing \n, systemd appears to want them newline-less
logMessage.chop(1);
systemd_default_message_handler(type, context, logMessage);
- } else {
- fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
- fflush(stderr);
- }
+ return;
#elif defined(Q_OS_ANDROID)
- if (!logToConsole) {
android_default_message_handler(type, context, logMessage);
- } else {
- fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
- fflush(stderr);
+ return;
+#endif
}
-#else
fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
fflush(stderr);
-#endif
- Q_UNUSED(logToConsole);
}
/*!