ENH: make cwd() behaviour user-adjustable (issue #1007)
- with the 'cwd' optimization switch it is possible to select the preferred behaviour for the cwd() function. A value of 0 causes cwd() to return the physical directory, which is what getcwd() and `pwd -P` return. Until now, this was always the standard behaviour. With a value of 1, cwd() instead returns the logical directory, which what $PWD contains and `pwd -L` returns. If any of the sanity checks fail (eg, PWD points to something other than ".", etc), a warning is emitted and the physical cwd() is returned instead. Apart from the optical difference in the output, this additional control helps workaround file systems with whitespace or other characters in the directory that normally cause OpenFOAM to balk. Using a cleaner symlink elsewhere should skirt this issue. Eg, cd $HOME ln -s "/mounted volume/user/workdir" workdir cd workdir # start working with OpenFOAM
This commit is contained in:
parent
50852b3392
commit
7864672c78
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,10 @@ using namespace Foam;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Info<<"cwd() " << cwd() << nl;
|
||||
Info<<"cwd(-P) " << cwd(false) << nl;
|
||||
Info<<"cwd(-L) " << cwd(true) << nl;
|
||||
|
||||
Info<<"rmDir" << nl;
|
||||
rmDir("hmm");
|
||||
|
||||
|
@ -69,6 +69,9 @@ InfoSwitches
|
||||
|
||||
OptimisationSwitches
|
||||
{
|
||||
// Use physical (0) or logical (1) value for the cwd.
|
||||
cwd 0;
|
||||
|
||||
// On NFS mounted file system: maximum wait for files to appear/get
|
||||
// updated. Set to 0 on distributed case.
|
||||
fileModificationSkew 10;
|
||||
|
@ -74,6 +74,8 @@ namespace Foam
|
||||
defineTypeNameAndDebug(POSIX, 0);
|
||||
}
|
||||
|
||||
static bool cwdPreference_(Foam::debug::optimisationSwitch("cwd", 0));
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
@ -280,7 +282,11 @@ Foam::fileName Foam::home(const std::string& userName)
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::cwd()
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
//- The physical current working directory path name (pwd -P).
|
||||
static Foam::fileName cwd_P()
|
||||
{
|
||||
label pathLengthLimit = POSIX::pathLengthChunk;
|
||||
List<char> path(pathLengthLimit);
|
||||
@ -307,7 +313,7 @@ Foam::fileName Foam::cwd()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
path.setSize(pathLengthLimit);
|
||||
path.resize(pathLengthLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -319,7 +325,86 @@ Foam::fileName Foam::cwd()
|
||||
<< "Couldn't get the current working directory"
|
||||
<< exit(FatalError);
|
||||
|
||||
return fileName::null;
|
||||
return fileName();
|
||||
}
|
||||
|
||||
|
||||
//- The logical current working directory path name.
|
||||
// From the PWD environment, same as pwd -L.
|
||||
static Foam::fileName cwd_L()
|
||||
{
|
||||
const char* env = ::getenv("PWD");
|
||||
|
||||
// Basic check
|
||||
if (!env || env[0] != '/')
|
||||
{
|
||||
WarningInFunction
|
||||
<< "PWD is invalid - reverting to physical description"
|
||||
<< nl;
|
||||
|
||||
return cwd_P();
|
||||
}
|
||||
|
||||
fileName dir(env);
|
||||
|
||||
// Check for "/."
|
||||
for
|
||||
(
|
||||
std::string::size_type pos = 0;
|
||||
std::string::npos != (pos = dir.find("/.", pos));
|
||||
/*nil*/
|
||||
)
|
||||
{
|
||||
pos += 2;
|
||||
|
||||
if
|
||||
(
|
||||
// Ends in "/." or has "/./"
|
||||
!dir[pos] || dir[pos] == '/'
|
||||
|
||||
// Ends in "/.." or has "/../"
|
||||
|| (dir[pos] == '.' && (!dir[pos+1] || dir[pos+1] == '/'))
|
||||
)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "PWD contains /. or /.. - reverting to physical description"
|
||||
<< nl;
|
||||
|
||||
return cwd_P();
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, verify that PWD actually corresponds to the "." directory
|
||||
if (!fileStat(dir, true).sameINode(fileStat(".", true)))
|
||||
{
|
||||
WarningInFunction
|
||||
<< "PWD is not the cwd() - reverting to physical description"
|
||||
<< nl;
|
||||
|
||||
return cwd_P();
|
||||
}
|
||||
|
||||
|
||||
return fileName(dir);
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
Foam::fileName Foam::cwd()
|
||||
{
|
||||
return cwd(cwdPreference_);
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::cwd(bool logical)
|
||||
{
|
||||
if (logical)
|
||||
{
|
||||
return cwd_L();
|
||||
}
|
||||
|
||||
return cwd_P();
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,14 +43,14 @@ Foam::fileStat::fileStat()
|
||||
|
||||
Foam::fileStat::fileStat
|
||||
(
|
||||
const fileName& fName,
|
||||
const char* fName,
|
||||
const bool followLink,
|
||||
const unsigned int maxTime
|
||||
)
|
||||
:
|
||||
isValid_(false)
|
||||
{
|
||||
if (fName.empty())
|
||||
if (!fName || !fName[0])
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -64,11 +64,11 @@ Foam::fileStat::fileStat
|
||||
{
|
||||
if (followLink)
|
||||
{
|
||||
locIsValid = (::stat(fName.c_str(), &status_) == 0);
|
||||
locIsValid = (::stat(fName, &status_) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
locIsValid = (::lstat(fName.c_str(), &status_) == 0);
|
||||
locIsValid = (::lstat(fName, &status_) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +77,17 @@ Foam::fileStat::fileStat
|
||||
}
|
||||
|
||||
|
||||
Foam::fileStat::fileStat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool followLink,
|
||||
const unsigned int maxTime
|
||||
)
|
||||
:
|
||||
fileStat(fName.c_str(), followLink, maxTime)
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileStat::fileStat(Istream& is)
|
||||
{
|
||||
is >> *this;
|
||||
|
@ -28,7 +28,7 @@ Description
|
||||
Wrapper for stat() and lstat() system calls.
|
||||
|
||||
Warning
|
||||
on Linux (an maybe on others) a stat() of an nfs mounted (remote)
|
||||
On Linux (an maybe on others) a stat() of an nfs mounted (remote)
|
||||
file does never timeout and cannot be interrupted!
|
||||
So e.g. Foam::ping first and hope nfs is running.
|
||||
|
||||
@ -79,16 +79,28 @@ public:
|
||||
fileStat();
|
||||
|
||||
//- Construct from components.
|
||||
// \param fName \n
|
||||
// The file name or directory name to stat.
|
||||
//
|
||||
// \param followLink \n
|
||||
// If it is a link, get the status of the source file/directory.
|
||||
// \param fName The file name or directory name to stat.
|
||||
// \param followLink If it is a link, get the status of the source
|
||||
// file/directory.
|
||||
// \param maxTime The timeout value.
|
||||
//
|
||||
// \param maxTime \n
|
||||
// The timeout value.
|
||||
// \note An empty filename is a no-op.
|
||||
fileStat
|
||||
(
|
||||
const char* fName,
|
||||
const bool followLink = true,
|
||||
const unsigned int maxTime = 0
|
||||
);
|
||||
|
||||
//- Construct from components.
|
||||
//
|
||||
// \note an empty filename is a no-op.
|
||||
// \param fName The file name or directory name to stat.
|
||||
// \param followLink If it is a link, get the status of the source
|
||||
// file/directory.
|
||||
// \param maxTime The timeout value.
|
||||
//
|
||||
// \note An empty filename is a no-op.
|
||||
fileStat
|
||||
(
|
||||
const fileName& fName,
|
||||
|
@ -92,9 +92,17 @@ fileName home();
|
||||
//- Return home directory path name for a particular user
|
||||
fileName home(const std::string& userName);
|
||||
|
||||
//- Return current working directory path name
|
||||
//- The physical or logical current working directory path name.
|
||||
// The behaviour is controlled by the \c cwd optimisation Switch
|
||||
// A value of 0 corresponds to the physical value, which is identical
|
||||
// to what getcwd and pwd -P would deliver.
|
||||
// A value of 1 corresponds to the logical value, which corresponds
|
||||
// to the PWD environment value and to what pwd -L would deliver.
|
||||
fileName cwd();
|
||||
|
||||
//- The physical or logical current working directory path name.
|
||||
fileName cwd(bool logical);
|
||||
|
||||
//- Change current directory to the one specified and return true on success.
|
||||
// Using an empty name is a no-op and always returns false.
|
||||
bool chDir(const fileName& dir);
|
||||
|
Loading…
Reference in New Issue
Block a user