Commit 6390c183 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: suppress Info output for some cases (issue #722, #893)

- add additional control via a Foam::infoDetailLevel flag, which is
  supported by a 'DetailLevel' macro.  Eg,

      DetailLevel << "some information" << nl

- When infoDetailLevel is zero, the stdout for all Foam::system() calls
  are also redirected to stderr to prevent child output from
  appearing on the parent.

- close stdin before exec in system call.
parent 83c9d3b2
......@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
{
if (nProcs)
{
// Info<< "Remove " << timeDirs.size()
// Serr<< "Remove " << timeDirs.size()
// << " processor time directories" << nl;
forAllReverse(timeDirs, timei)
......@@ -153,7 +153,7 @@ int main(int argc, char *argv[])
}
else
{
// Info<< "Remove " << timeDirs.size()
// Serr<< "Remove " << timeDirs.size()
// << " time directories" << nl;
forAllReverse(timeDirs, timei)
......
......@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
const scalar scaling = args.lookupOrDefault<scalar>("scale", -1);
if (scaling > 0)
{
Info<< " -scale " << scaling << nl;
DetailInfo << " -scale " << scaling << nl;
surf.scalePoints(scaling);
}
......
......@@ -56,9 +56,6 @@ notTest()
# Extract 'numberOfSubdomains' from system/decomposeParDict
# (or alternative location).
#
# Note that '#include' and other directives are disabled - only entries that
# are in the dictionary are considered.
#
# On failure:
# return '1'
# exit status 1
......@@ -68,14 +65,14 @@ getNumberOfProcessors()
local dict="${1:-system/decomposeParDict}"
# Re-use positional parameters for automatic whitespace elimination
set -- $(foamDictionary -disableFunctionEntries -entry numberOfSubdomains -value "$dict" 2>/dev/null)
set -- $(foamDictionary -entry numberOfSubdomains -value "$dict" 2>/dev/null)
if [ "$#" -eq 1 ]
then
echo "$1"
else
echo "Error getting 'numberOfSubdomains' from '$dict'" 1>&2
echo 1 # serial as fallback
echo 1 # Fallback is 1 proc (serial)
return 1
fi
}
......@@ -84,9 +81,6 @@ getNumberOfProcessors()
#
# Extract 'application' from system/controlDict
#
# Note that '#include' and other directives are disabled - only entries that
# are in the dictionary are considered.
#
# On failure:
# return 'false' which is also a command (ie, shell builtin or /bin/false)
# exit status 1
......@@ -94,14 +88,14 @@ getNumberOfProcessors()
getApplication()
{
# Re-use positional parameters for automatic whitespace elimination
set -- $(foamDictionary -disableFunctionEntries -entry application -value system/controlDict 2>/dev/null)
set -- $(foamDictionary -entry application -value system/controlDict 2>/dev/null)
if [ "$#" -eq 1 ]
then
echo "$1"
else
echo "Error getting 'application' from system/controlDict" 1>&2
echo false
echo false # Fallback
return 1
fi
}
......
......@@ -66,6 +66,7 @@ Description
#include <link.h>
#endif
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
......@@ -74,9 +75,7 @@ namespace Foam
}
// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
//! \cond fileScope
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
// Like fileName "/" global operator, but retain any invalid characters
static inline Foam::fileName fileNameConcat
......@@ -106,7 +105,23 @@ static inline Foam::fileName fileNameConcat
// Both strings are empty
return Foam::fileName();
}
//! \endcond
// After a fork in system(), before the exec() do the following
// 1. close stdin
// 2. redirect stdout to stderr when infoDetailLevel == 0
static inline void redirects()
{
// Close stdin(0) - unchecked return value
(void) ::close(STDIN_FILENO);
// Redirect stdout(1) to stderr(2) '1>&2'
if (Foam::infoDetailLevel == 0)
{
// This is correct. 1>&2 means dup2(2, 1);
(void) ::dup2(STDERR_FILENO, STDOUT_FILENO);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -1312,6 +1327,7 @@ static int waitpid(const pid_t pid)
// in parent - blocking wait
// modest treatment of signals (in child)
// treat 'stopped' like exit (suspend/continue)
while (true)
{
pid_t wpid = ::waitpid(pid, &status, WUNTRACED);
......@@ -1354,11 +1370,7 @@ static int waitpid(const pid_t pid)
}
int Foam::system
(
const std::string& command,
const bool background
)
int Foam::system(const std::string& command, const bool bg)
{
if (command.empty())
{
......@@ -1369,17 +1381,22 @@ int Foam::system
return 0;
}
pid_t child_pid = ::vfork(); // NB: vfork, not fork!
const pid_t child_pid = ::vfork(); // NB: vfork, not fork!
if (child_pid == -1)
{
FatalErrorInFunction
<< "vfork() failed for system command " << command
<< exit(FatalError);
}
if (child_pid == 0)
return -1; // fallback error value
}
else if (child_pid == 0)
{
// in child
// In child
// Close or redirect file descriptors
redirects();
// execl uses the current environ
(void) ::execl
......@@ -1395,27 +1412,19 @@ int Foam::system
FatalErrorInFunction
<< "exec failed: " << command
<< exit(FatalError);
return -1; // fallback error value
}
// In parent:
// In parent
// - started as background process, or blocking wait for the child
if (background)
{
// Started as background process
return 0;
}
// blocking wait for the child
return waitpid(child_pid);
return (bg ? 0 : waitpid(child_pid));
}
int Foam::system
(
const CStringList& command,
const bool background
)
int Foam::system(const CStringList& command, const bool bg)
{
const int argc = command.size();
......@@ -1432,17 +1441,25 @@ int Foam::system
// triggered by fork.
// The normal system() command has a fork buried in it that causes
// issues with infiniband and openmpi etc.
pid_t child_pid = ::vfork();
const pid_t child_pid = ::vfork();
if (child_pid == -1)
{
FatalErrorInFunction
<< "vfork() failed for system command " << command[0]
<< exit(FatalError);
}
if (child_pid == 0)
return -1; // fallback error value
}
else if (child_pid == 0)
{
// In child:
// In child
// Close or redirect file descriptors
redirects();
// Need command and arguments separately.
// args is a nullptr-terminated list of c-strings
......@@ -1453,32 +1470,24 @@ int Foam::system
FatalErrorInFunction
<< "exec(" << command[0] << ", ...) failed"
<< exit(FatalError);
}
return -1; // fallback error value
}
// In parent:
if (background)
{
// Started as background process
return 0;
}
// In parent
// - started as background process, or blocking wait for the child
// blocking wait for the child
return waitpid(child_pid);
return (bg ? 0 : waitpid(child_pid));
}
int Foam::system
(
const Foam::UList<Foam::string>& command,
const bool background
)
int Foam::system(const Foam::UList<Foam::string>& command, const bool bg)
{
// In the future simply call the CStringList version:
//
// const CStringList cmd(command);
// return Foam::system(cmd, background);
// return Foam::system(cmd, bg);
const int argc = command.size();
......@@ -1495,17 +1504,25 @@ int Foam::system
// triggered by fork.
// The normal system() command has a fork buried in it that causes
// issues with infiniband and openmpi etc.
pid_t child_pid = ::vfork();
const pid_t child_pid = ::vfork();
if (child_pid == -1)
{
FatalErrorInFunction
<< "vfork() failed for system command " << command[0]
<< exit(FatalError);
}
if (child_pid == 0)
return -1; // fallback error value
}
else if (child_pid == 0)
{
// In child:
// In child
// Close or redirect file descriptors
redirects();
// Need command and arguments separately.
// args is a nullptr-terminated list of c-strings
......@@ -1522,19 +1539,15 @@ int Foam::system
FatalErrorInFunction
<< "exec(" << command[0] << ", ...) failed"
<< exit(FatalError);
}
return -1; // fallback error value
}
// In parent:
if (background)
{
// Started as background process
return 0;
}
// In parent
// - started as background process, or blocking wait for the child
// blocking wait for the child
return waitpid(child_pid);
return (bg ? 0 : waitpid(child_pid));
}
......
......@@ -47,10 +47,19 @@ Description
namespace Foam
{
//- An Istream wrapper for std::cin
extern ISstream Sin;
//- An Ostream wrapper for std::cout
extern OSstream Sout;
//- An Ostream wrapper for std::cerr
extern OSstream Serr;
//- An Ostream wrapper for parallel output to std::cout
extern prefixOSstream Pout;
//- An Ostream wrapper for parallel output to std::cerr
extern prefixOSstream Perr;
}
......
......@@ -93,8 +93,6 @@ void Foam::Time::readDict()
}
// Check for local switches and settings
// - echo values, unless the application was invoked with noBanner
const bool echo = argList::bannerEnabled();
const dictionary* localDict = nullptr;
......@@ -105,11 +103,9 @@ void Foam::Time::readDict()
&& localDict->size()
)
{
if (echo)
{
Info<< "Overriding DebugSwitches according to "
<< controlDict_.name() << nl;
}
DetailInfo
<< "Overriding DebugSwitches according to "
<< controlDict_.name() << nl;
simpleObjectRegistry& objs = debug::debugObjects();
......@@ -123,10 +119,7 @@ void Foam::Time::readDict()
{
const List<simpleRegIOobject*>& objects = *objPtr;
if (echo)
{
Info<< " " << iter() << nl;
}
DetailInfo << " " << iter() << nl;
if (iter().isDict())
{
......@@ -157,11 +150,9 @@ void Foam::Time::readDict()
&& localDict->size()
)
{
if (echo)
{
Info<< "Overriding InfoSwitches according to "
<< controlDict_.name() << nl;
}
DetailInfo
<< "Overriding InfoSwitches according to "
<< controlDict_.name() << nl;
simpleObjectRegistry& objs = debug::infoObjects();
......@@ -175,10 +166,7 @@ void Foam::Time::readDict()
{
const List<simpleRegIOobject*>& objects = *objPtr;
if (echo)
{
Info<< " " << iter() << nl;
}
DetailInfo << " " << iter() << nl;
if (iter().isDict())
{
......@@ -208,11 +196,9 @@ void Foam::Time::readDict()
&& localDict->size()
)
{
if (echo)
{
Info<< "Overriding OptimisationSwitches according to "
<< controlDict_.name() << nl;
}
DetailInfo
<< "Overriding OptimisationSwitches according to "
<< controlDict_.name() << nl;
simpleObjectRegistry& objs = debug::optimisationObjects();
......@@ -224,10 +210,7 @@ void Foam::Time::readDict()
if (objPtr)
{
if (echo)
{
Info<< " " << iter() << nl;
}
DetailInfo << " " << iter() << nl;
const List<simpleRegIOobject*>& objects = *objPtr;
......@@ -263,10 +246,7 @@ void Foam::Time::readDict()
&& fileHandler().type() != fileHandlerName
)
{
if (echo)
{
Info<< "Overriding fileHandler to " << fileHandlerName << nl;
}
DetailInfo << "Overriding fileHandler to " << fileHandlerName << nl;
// Remove old watches since destroying the file
fileNameList oldWatched(controlDict_.watchIndices().size());
......@@ -304,11 +284,9 @@ void Foam::Time::readDict()
&& localDict->size()
)
{
if (echo)
{
Info<< "Overriding DimensionedConstants according to "
<< controlDict_.name() << nl;
}
DetailInfo
<< "Overriding DimensionedConstants according to "
<< controlDict_.name() << nl;
simpleObjectRegistry& objs = debug::dimensionedConstantObjects();
......@@ -325,7 +303,7 @@ void Foam::Time::readDict()
{
obj->readData(dummyIs);
if (echo)
if (Foam::infoDetailLevel > 0)
{
Info<< " ";
obj->writeData(Info);
......@@ -343,11 +321,9 @@ void Foam::Time::readDict()
&& localDict->size()
)
{
if (echo)
{
Info<< "Overriding DimensionSets according to "
<< controlDict_.name() << nl;
}
DetailInfo
<< "Overriding DimensionSets according to "
<< controlDict_.name() << nl;
simpleObjectRegistry& objs = debug::dimensionSetObjects();
......@@ -358,10 +334,7 @@ void Foam::Time::readDict()
if (objPtr)
{
if (echo)
{
Info<< *localDict << nl;
}
DetailInfo << *localDict << nl;
const List<simpleRegIOobject*>& objects = *objPtr;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -66,7 +66,8 @@ bool Foam::functionEntries::calcEntry::execute
Istream& is
)
{
Info<< "Using #calc at line " << is.lineNumber()
DetailInfo
<< "Using #calc at line " << is.lineNumber()
<< " in file " << parentDict.name() << endl;
dynamicCode::checkSecurity
......@@ -110,7 +111,8 @@ bool Foam::functionEntries::calcEntry::execute
Istream& is
)
{
Info<< "Using #calc at line " << is.lineNumber()
DetailInfo
<< "Using #calc at line " << is.lineNumber()
<< " in file " << parentDict.name() << endl;
dynamicCode::checkSecurity
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -147,7 +147,8 @@ Foam::functionEntries::codeStream::getFunction
if (!lib)
{
Info<< "Using #codeStream with " << libPath << endl;
DetailInfo
<< "Using #codeStream with " << libPath << endl;
}
......@@ -372,7 +373,8 @@ bool Foam::functionEntries::codeStream::execute
Istream& is
)
{
Info<< "Using #codeStream at line " << is.lineNumber()
DetailInfo
<< "Using #codeStream at line " << is.lineNumber()
<< " in file " << parentDict.name() << endl;
dynamicCode::checkSecurity
......@@ -405,7 +407,8 @@ bool Foam::functionEntries::codeStream::execute
Istream& is
)
{
Info<< "Using #codeStream at line " << is.lineNumber()
DetailInfo
<< "Using #codeStream at line " << is.lineNumber()
<< " in file " << parentDict.name() << endl;
dynamicCode::checkSecurity
......
......@@ -141,7 +141,7 @@ bool Foam::functionEntries::includeEntry::execute
{
if (Foam::functionEntries::includeEntry::log)
{
Info<< fName << endl;
DetailInfo << fName << endl;
}
// Add watch on included file
......@@ -188,7 +188,7 @@ bool Foam::functionEntries::includeEntry::execute
{
if (Foam::functionEntries::includeEntry::log)
{
Info<< fName << endl;
DetailInfo << fName << endl;
}
// Add watch on included file
......@@ -234,7 +234,7 @@ bool Foam::functionEntries::sincludeEntry::execute
{
if (Foam::functionEntries::includeEntry::log)
{
Info<< fName << endl;
DetailInfo << fName << endl;
}
// Add watch on included file
......@@ -272,7 +272,7 @@ bool Foam::functionEntries::sincludeEntry::execute
{
if (Foam::functionEntries::includeEntry::log)
{
Info<< fName << endl;
DetailInfo << fName << endl;
}
// Add watch on included file
......
......@@ -102,7 +102,7 @@ bool Foam::functionEntries::includeEtcEntry::execute
{
if (Foam::functionEntries::includeEtcEntry::log)
{
Info<< fName << endl;
DetailInfo << fName << endl;
}
parentDict.read(ifs);
return true;
......@@ -137,7 +137,7 @@ bool Foam::functionEntries::includeEtcEntry::execute
{
if (Foam::functionEntries::includeEtcEntry::log)
{
Info<< fName << endl;
DetailInfo << fName << endl;
}
entry.read(parentDict, ifs);
return true;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -350,7 +350,8 @@ void Foam::codedBase::updateLibrary
return;
}