diff --git a/applications/test/POSIX/Test-POSIX.C b/applications/test/POSIX/Test-POSIX.C
index e38899ec929deef39d74a567036a063794578a89..ad7639825fe524e272848c702110a7b7d2b36279 100644
--- a/applications/test/POSIX/Test-POSIX.C
+++ b/applications/test/POSIX/Test-POSIX.C
@@ -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");
 
diff --git a/etc/controlDict b/etc/controlDict
index 950e5adc2b08b9d9242954ceff0c3224ea165166..c5b0c7cd0a05bc94ad77cc7bfa7cee2a128ffe2a 100644
--- a/etc/controlDict
+++ b/etc/controlDict
@@ -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;
diff --git a/src/OSspecific/POSIX/POSIX.C b/src/OSspecific/POSIX/POSIX.C
index 1953935f3c70f699bcc69f2d797d9ab82af81b03..05e134d9c48b90855dcfddd174f99f3560f14f9b 100644
--- a/src/OSspecific/POSIX/POSIX.C
+++ b/src/OSspecific/POSIX/POSIX.C
@@ -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();
 }
 
 
diff --git a/src/OSspecific/POSIX/fileStat.C b/src/OSspecific/POSIX/fileStat.C
index 0d50a72186262825ef1bd43d4dfcb1e88216af4e..706640a1a0917b731195abd613aadc657cadae47 100644
--- a/src/OSspecific/POSIX/fileStat.C
+++ b/src/OSspecific/POSIX/fileStat.C
@@ -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;
diff --git a/src/OSspecific/POSIX/fileStat.H b/src/OSspecific/POSIX/fileStat.H
index 62a61afbbf1fd5ad2cabf25f6455666154726f14..e1a997b2053dce62b1f8923f96def4c6bfd97f65 100644
--- a/src/OSspecific/POSIX/fileStat.H
+++ b/src/OSspecific/POSIX/fileStat.H
@@ -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.
+        //
+        //  \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.
+        //  \note An empty filename is a no-op.
         fileStat
         (
             const fileName& fName,
diff --git a/src/OpenFOAM/include/OSspecific.H b/src/OpenFOAM/include/OSspecific.H
index 85c84c1ae5e1e5bc88806ca35c6e33865883ba7c..d8535cf8e9a124b9a6c898b76b317356a65723bd 100644
--- a/src/OpenFOAM/include/OSspecific.H
+++ b/src/OpenFOAM/include/OSspecific.H
@@ -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);