diff --git a/src/OSspecific/MSwindows/Allwmake b/src/OSspecific/MSwindows/Allwmake
new file mode 100755
index 0000000000000000000000000000000000000000..24fb418826f8f9b7d44c745e5fb780a4df187d5b
--- /dev/null
+++ b/src/OSspecific/MSwindows/Allwmake
@@ -0,0 +1,12 @@
+#!/bin/sh
+cd ${0%/*} || exit 1                        # Run from this directory
+targetType=libo                             # Preferred library type
+. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments $*
+
+#------------------------------------------------------------------------------
+unset COMP_FLAGS LINK_FLAGS
+
+# Make object (non-shared by default)
+wmake $targetType
+
+#------------------------------------------------------------------------------
diff --git a/src/OSspecific/MSwindows/MSwindows.C b/src/OSspecific/MSwindows/MSwindows.C
new file mode 100644
index 0000000000000000000000000000000000000000..30fb55792f446ebd29941765b459de2cceff4e43
--- /dev/null
+++ b/src/OSspecific/MSwindows/MSwindows.C
@@ -0,0 +1,1288 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2017 OpenFOAM Foundation
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "OSspecific.H"
+#include "MSwindows.H"
+#include "fileName.H"
+#include "fileStat.H"
+#include "DynamicList.H"
+#include "CStringList.H"
+#include "IOstreams.H"
+#include "Pstream.H"
+#undef DebugInfo    // Windows name clash with OpenFOAM messageStream
+
+#include <cassert>
+#include <cstdlib>
+#include <fstream>
+#include <unordered_map>
+
+// Windows headers
+#define WIN32_LEAN_AND_MEAN
+#include <csignal>
+#include <io.h>     // For _close
+#include <windows.h>
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(MSwindows, 0);
+}
+
+
+namespace Foam
+{
+    // Don't abort under windows, causes abort dialog to popup.
+    // Instead just exit with exitCode.
+    static void sigAbortHandler(int exitCode)
+    {
+        ::exit(exitCode);
+    }
+
+    static bool installAbortHandler()
+    {
+        // If it didn't succeed there's not much we can do,
+        // so don't check result.
+        ::signal(SIGABRT, &sigAbortHandler);
+        return true;
+    }
+
+    static bool const abortHandlerInstalled = installAbortHandler();
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace MSwindows
+{
+
+//- A simple directory contents iterator
+class directoryIterator
+{
+    HANDLE handle_;
+
+    bool exists_;
+
+    bool hidden_;
+
+    std::string item_;
+
+    //- Accept file/dir name
+    inline bool accept() const
+    {
+        return
+        (
+            item_.size() && item_ != "." && item_ != ".."
+         && (hidden_ || item_[0] != '.')
+        );
+    }
+
+
+public:
+
+    //- Construct for dirName, optionally allowing hidden files/dirs
+    directoryIterator(const fileName& dirName, bool allowHidden = false)
+    :
+        handle_(INVALID_HANDLE_VALUE),
+        exists_(false),
+        hidden_(allowHidden),
+        item_()
+    {
+        if (!dirName.empty())
+        {
+            WIN32_FIND_DATA findData;
+
+            handle_ = ::FindFirstFile((dirName/"*").c_str(), &findData);
+
+            if (good())
+            {
+                exists_ = true;
+                item_ = findData.cFileName;
+
+                // If first element is not acceptable, get another one
+                if (!accept())
+                {
+                    next();
+                }
+            }
+        }
+    }
+
+
+    //- Destructor
+    ~directoryIterator()
+    {
+        close();
+    }
+
+
+    // Member Functions
+
+        //- Directory existed for opening
+        bool exists() const
+        {
+            return exists_;
+        }
+
+        //- Directory pointer is valid
+        bool good() const
+        {
+            return (INVALID_HANDLE_VALUE != handle_);
+        }
+
+        //- Close directory
+        void close()
+        {
+            if (good())
+            {
+                ::FindClose(handle_);
+                handle_ = INVALID_HANDLE_VALUE;
+            }
+        }
+
+        //- The current item
+        const std::string& val() const
+        {
+            return item_;
+        }
+
+        //- Read next item, always ignoring "." and ".." entries.
+        //  Normally also ignore hidden files/dirs (beginning with '.')
+        //  Automatically close when it runs out of items
+        bool next()
+        {
+            if (good())
+            {
+                WIN32_FIND_DATA findData;
+
+                while (::FindNextFile(handle_, &findData))
+                {
+                    item_ = findData.cFileName;
+
+                    if (accept())
+                    {
+                        return true;
+                    }
+                }
+                close();  // No more items
+            }
+
+            return false;
+        }
+
+
+    // Member Operators
+
+        //- Same as good()
+        operator bool() const
+        {
+            return good();
+        }
+
+        //- Same as val()
+        const std::string& operator*() const
+        {
+            return val();
+        }
+
+        //- Same as next()
+        directoryIterator& operator++()
+        {
+            next();
+            return *this;
+        }
+};
+
+} // End namespace MSwindows
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+std::string Foam::MSwindows::lastError()
+{
+    // Retrieve the system error message for the last-error code
+
+    // Based on an example at:
+    // http://msdn2.microsoft.com/en-us/library/ms680582(VS.85).aspx
+
+    LPVOID lpMsgBuf;
+    DWORD dw = GetLastError();
+
+    FormatMessage
+    (
+        FORMAT_MESSAGE_ALLOCATE_BUFFER |
+        FORMAT_MESSAGE_FROM_SYSTEM |
+        FORMAT_MESSAGE_IGNORE_INSERTS,
+        NULL,  // source
+        dw,    // message-id
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  // language-id
+        reinterpret_cast<LPTSTR>(&lpMsgBuf),
+        0, NULL
+    );
+
+    const char* fmt = "Error %d: %s";
+
+    // Use snprintf with zero to establish the size (without '\0') required
+    std::string output;
+
+    int n = ::snprintf(nullptr, 0, fmt, static_cast<LPCTSTR>(lpMsgBuf));
+
+    if (n > 0)
+    {
+        output.resize(n+1);
+
+        // Print directly into buffer
+        n = ::snprintf(&(output[0]), n+1, fmt, static_cast<LPCTSTR>(lpMsgBuf));
+        output.resize(n);
+    }
+
+    LocalFree(lpMsgBuf);
+
+    return output;
+}
+
+
+std::string Foam::MSwindows::userName()
+{
+    const DWORD bufLen = 256;
+    TCHAR buf[bufLen];
+    DWORD len = bufLen;
+
+    if (::GetUserName(buf, &len))
+    {
+        return buf;
+    }
+
+    std::string str;
+
+    if
+    (
+        ERROR_INSUFFICIENT_BUFFER == ::GetLastError()
+     && len < 2048
+    )
+    {
+        // The len is with trailing '\0'
+        str.resize(len);
+
+        // Retrieve directly into buffer
+        ::GetUserName(&(str[0]), &len);
+
+        // Without trailing '\0'
+        str.resize(len-1);
+    }
+
+    return str;
+}
+
+
+pid_t Foam::pid()
+{
+    const DWORD processId = ::GetCurrentProcessId();
+    return processId;
+}
+
+
+pid_t Foam::ppid()
+{
+    // No equivalent under windows.
+
+    if (MSwindows::debug)
+    {
+        Info<< "ppid not supported under MSwindows" << endl;
+    }
+
+    return 0;
+}
+
+
+pid_t Foam::pgid()
+{
+    // No equivalent under windows.
+
+    if (MSwindows::debug)
+    {
+        Info<< "pgid not supported under MSwindows" << endl;
+    }
+
+    return 0;
+}
+
+
+bool Foam::env(const std::string& envName)
+{
+    // An empty envName => always false
+    return !envName.empty() &&
+        ::GetEnvironmentVariable(envName.c_str(), nullptr, 0);
+}
+
+
+Foam::string Foam::getEnv(const std::string& envName)
+{
+    std::string env;
+
+    const auto len = ::GetEnvironmentVariable(envName.c_str(), nullptr, 0);
+
+    if (len)
+    {
+        env.resize(len+1);
+        ::GetEnvironmentVariable(envName.c_str(), &(env[0]), len+1);
+
+        env.resize(len);
+        return fileName::validate(env);
+    }
+
+    return env;
+}
+
+
+bool Foam::setEnv
+(
+    const word& envName,
+    const std::string& value,
+    const bool overwrite
+)
+{
+    // Ignore an empty envName => always false
+    return
+    (
+        !envName.empty()
+     && ::SetEnvironmentVariable(envName.c_str(), value.c_str())
+    );
+}
+
+
+Foam::string Foam::hostName(bool)
+{
+    const DWORD bufLen = MAX_COMPUTERNAME_LENGTH + 1;
+    TCHAR buf[bufLen];
+    DWORD len = bufLen;
+
+    return ::GetComputerName(buf, &len) ? buf : string();
+}
+
+
+Foam::string Foam::domainName()
+{
+    // Could use ::gethostname and ::gethostbyname like POSIX.C, but would
+    // then need to link against ws_32. Prefer to minimize dependencies.
+
+    return string::null;
+}
+
+
+Foam::string Foam::userName()
+{
+    string name = Foam::getEnv("USERNAME");
+
+    if (name.empty())
+    {
+        name = MSwindows::userName();
+    }
+
+    return name;
+}
+
+
+bool Foam::isAdministrator()
+{
+    // Assume worst case
+    return true;
+}
+
+
+Foam::fileName Foam::home()
+{
+    fileName env = Foam::getEnv("HOME");
+
+    if (env.empty())
+    {
+        env  = Foam::getEnv("USERPROFILE");
+    }
+
+    return env;
+}
+
+
+Foam::fileName Foam::home(const std::string& userName)
+{
+    return Foam::home();
+}
+
+
+Foam::fileName Foam::cwd()
+{
+    string path;
+    const DWORD len = ::GetCurrentDirectory(0, nullptr);
+
+    if (len)
+    {
+        path.resize(len+1);
+
+        ::GetCurrentDirectory(len+1, &(path[0]));
+
+        path.resize(len);
+
+        return fileName::validate(path);
+    }
+
+    FatalErrorInFunction
+        << "Couldn't get the current working directory"
+        << exit(FatalError);
+
+    return fileName();
+}
+
+
+Foam::fileName Foam::cwd(bool logical)
+{
+    return Foam::cwd();
+}
+
+
+bool Foam::chDir(const fileName& dir)
+{
+    // Ignore an empty dir name => always false
+    return !dir.empty() && ::SetCurrentDirectory(dir.c_str());;
+}
+
+
+bool Foam::mkDir(const fileName& pathName, const mode_t mode)
+{
+    // empty names are meaningless
+    if (pathName.empty())
+    {
+        return false;
+    }
+
+    bool ok = ::CreateDirectory(pathName.c_str(), NULL);
+
+    if (ok)
+    {
+        Foam::chMod(pathName, mode);
+        return true;
+    }
+
+    const DWORD error = ::GetLastError();
+    switch (error)
+    {
+        case ERROR_ALREADY_EXISTS:
+        {
+            ok = true;
+            break;
+        }
+
+        case ERROR_PATH_NOT_FOUND:
+        {
+            // Part of the path does not exist so try to create it
+            const fileName& parentName = pathName.path();
+
+            if (parentName.size() && mkDir(parentName, mode))
+            {
+                ok = mkDir(pathName, mode);
+            }
+            break;
+        }
+    }
+
+    if (!ok)
+    {
+        FatalErrorInFunction
+            << "Couldn't create directory: " << pathName
+            << " " << MSwindows::lastError()
+            << exit(FatalError);
+    }
+
+    return ok;
+}
+
+
+bool Foam::chMod(const fileName& name, const mode_t m)
+{
+    // Ignore an empty name => always false
+    return !name.empty() && _chmod(name.c_str(), m) == 0;
+}
+
+
+mode_t Foam::mode(const fileName& name, const bool followLink)
+{
+    // Ignore an empty name => always 0
+    if (!name.empty())
+    {
+        fileStat fileStatus(name, followLink);
+        if (fileStatus.valid())
+        {
+            return fileStatus.status().st_mode;
+        }
+    }
+
+    return 0;
+}
+
+
+// Windows equivalent to S_ISDIR
+#define ms_isdir(a) \
+    ((m != INVALID_FILE_ATTRIBUTES) && (m & FILE_ATTRIBUTE_DIRECTORY))
+
+// Windows equivalent to S_ISREG
+#define ms_isreg(s) \
+    ((m != INVALID_FILE_ATTRIBUTES) && !(m & FILE_ATTRIBUTE_DIRECTORY))
+
+
+Foam::fileName::Type Foam::type
+(
+    const fileName& name,
+    const bool /* followLink */
+)
+{
+    // Ignore an empty name => always UNDEFINED
+    if (name.empty())
+    {
+        return fileName::UNDEFINED;
+    }
+
+    const DWORD m = ::GetFileAttributes(name.c_str());
+
+    if (ms_isreg(m))
+    {
+        return fileName::FILE;
+    }
+    else if (ms_isdir(m))
+    {
+        return fileName::DIRECTORY;
+    }
+
+    return fileName::UNDEFINED;
+}
+
+
+// Local check for gz file
+static bool isGzFile(const std::string& name)
+{
+    const DWORD m = ::GetFileAttributes((name + ".gz").c_str());
+    return ms_isreg(m);
+}
+
+
+bool Foam::exists
+(
+    const fileName& name,
+    const bool checkGzip,
+    const bool followLink
+)
+{
+    // Ignore an empty name => always false
+    if (name.empty())
+    {
+        return false;
+    }
+
+    const DWORD m = ::GetFileAttributes(name.c_str());
+
+    return (ms_isdir(m) || ms_isreg(m) || (checkGzip && isGzFile(name)));
+}
+
+
+bool Foam::isDir(const fileName& name, const bool followLink)
+{
+    // Ignore an empty name => always false
+    if (name.empty())
+    {
+        return false;
+    }
+
+    const DWORD m = ::GetFileAttributes(name.c_str());
+
+    return ms_isdir(m);
+}
+
+
+bool Foam::isFile
+(
+    const fileName& name,
+    const bool checkGzip,
+    const bool followLink
+)
+{
+    // Ignore an empty name => always false
+    if (name.empty())
+    {
+        return false;
+    }
+
+    const DWORD m = ::GetFileAttributes(name.c_str());
+
+    return (ms_isreg(m) || (!ms_isdir(m) && checkGzip && isGzFile(name)));
+}
+
+
+off_t Foam::fileSize(const fileName& name, const bool followLink)
+{
+    // Ignore an empty name
+    if (!name.empty())
+    {
+        fileStat fileStatus(name, followLink);
+        if (fileStatus.valid())
+        {
+            return fileStatus.status().st_size;
+        }
+    }
+
+    return -1;
+}
+
+
+time_t Foam::lastModified(const fileName& name, const bool followLink)
+{
+    // Ignore an empty name
+    return name.empty() ? 0 : fileStat(name, followLink).modTime();
+}
+
+
+double Foam::highResLastModified(const fileName& name, const bool followLink)
+{
+    // Ignore an empty name
+    return name.empty() ? 0 : fileStat(name, followLink).dmodTime();
+}
+
+
+Foam::fileNameList Foam::readDir
+(
+    const fileName& directory,
+    const fileName::Type type,
+    const bool filtergz,
+    const bool followLink
+)
+{
+    // Initial filename list size
+    // also used as increment if initial size found to be insufficient
+    static constexpr int maxNnames = 100;
+
+    // Basic sanity: cannot strip '.gz' from directory names
+    const bool stripgz = filtergz && (type != fileName::DIRECTORY);
+    const word extgz("gz");
+
+    fileNameList dirEntries;
+
+    // Iterate contents (ignores an empty directory name)
+
+    MSwindows::directoryIterator dirIter(directory);
+
+    if (!dirIter.exists())
+    {
+        if (MSwindows::debug)
+        {
+            InfoInFunction
+                << "cannot open directory " << directory << endl;
+        }
+
+        return dirEntries;
+    }
+
+    if (MSwindows::debug)
+    {
+        InfoInFunction
+            << " : reading directory " << directory << endl;
+    }
+
+    label nFailed = 0;     // Entries with invalid characters
+    label nEntries = 0;    // Number of selected entries
+    dirEntries.resize(maxNnames);
+
+    // Process all the directory entries
+    for (/*nil*/; dirIter; ++dirIter)
+    {
+        const std::string& item = *dirIter;
+
+        // Validate filename without quotes, etc in the name.
+        // No duplicate slashes to strip - dirent will not have them anyhow.
+
+        const fileName name(fileName::validate(item));
+        if (name != item)
+        {
+            ++nFailed;
+        }
+        else if
+        (
+            (type == fileName::DIRECTORY)
+         || (type == fileName::FILE && !fileName::isBackup(name))
+        )
+        {
+            if ((directory/name).type() == type)
+            {
+                if (nEntries >= dirEntries.size())
+                {
+                    dirEntries.resize(dirEntries.size() + maxNnames);
+                }
+
+                if (stripgz && name.hasExt(extgz))
+                {
+                    dirEntries[nEntries++] = name.lessExt();
+                }
+                else
+                {
+                    dirEntries[nEntries++] = name;
+                }
+            }
+        }
+    }
+
+    // Finalize the length of the entries list
+    dirEntries.resize(nEntries);
+
+    if (nFailed && MSwindows::debug)
+    {
+        std::cerr
+            << "Foam::readDir() : reading directory " << directory << nl
+            << nFailed << " entries with invalid characters in their name"
+            << std::endl;
+    }
+
+    return dirEntries;
+}
+
+
+bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
+{
+    // Make sure source exists - this also handles an empty source name
+    if (!exists(src))
+    {
+        return false;
+    }
+
+    fileName destFile(dest);
+
+    const fileName::Type srcType = src.type(followLink);
+
+    // Check type of source file.
+    if (srcType == fileName::FILE)
+    {
+        // If dest is a directory, create the destination file name.
+        if (destFile.type() == fileName::DIRECTORY)
+        {
+            destFile = destFile/src.name();
+        }
+
+        // Make sure the destination directory exists.
+        if (!isDir(destFile.path()) && !mkDir(destFile.path()))
+        {
+            return false;
+        }
+
+        // Open and check streams.
+        // - use binary mode to avoid any issues
+        std::ifstream srcStream(src, ios_base::in | ios_base::binary);
+        if (!srcStream)
+        {
+            return false;
+        }
+
+        // - use binary mode to avoid any issues
+        std::ofstream destStream(destFile, ios_base::out | ios_base::binary);
+        if (!destStream)
+        {
+            return false;
+        }
+
+        // Copy character data.
+        char ch;
+        while (srcStream.get(ch))
+        {
+            destStream.put(ch);
+        }
+
+        // Final check.
+        if (!srcStream.eof() || !destStream)
+        {
+            return false;
+        }
+    }
+    else if (srcType == fileName::DIRECTORY)
+    {
+        // If dest is a directory, create the destination file name.
+        if (destFile.type() == fileName::DIRECTORY)
+        {
+            destFile /= src.components().last();
+        }
+
+        // Make sure the destination directory extists.
+        if (!isDir(destFile) && !mkDir(destFile))
+        {
+            return false;
+        }
+
+        // Copy files
+        fileNameList files = readDir(src, fileName::FILE, false, followLink);
+        for (const fileName& item : files)
+        {
+            if (MSwindows::debug)
+            {
+                Info<< "Copying : " << src/item
+                    << " to " << destFile/item << endl;
+            }
+
+            // File to file.
+            Foam::cp(src/item, destFile/item);
+        }
+
+        // Copy sub directories.
+        fileNameList dirs = readDir
+        (
+            src,
+            fileName::DIRECTORY,
+            false,
+            followLink
+        );
+
+        for (const fileName& item : dirs)
+        {
+            if (MSwindows::debug)
+            {
+                Info<< "Copying : " << src/item
+                    << " to " << destFile << endl;
+            }
+
+            // Dir to Dir.
+            Foam::cp(src/item, destFile);
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+
+bool Foam::ln(const fileName& src, const fileName& dst)
+{
+    // links are poorly supported, or need adminstrator privileges.
+    // Skip for now.
+
+    if (MSwindows::debug)
+    {
+        Info<< "MSwindows does not support ln - softlinking" << endl;
+    }
+
+    return false;
+}
+
+
+bool Foam::mv(const fileName& src, const fileName& dst, const bool followLink)
+{
+    if (MSwindows::debug)
+    {
+        Info<< "Move : " << src << " to " << dst << endl;
+    }
+
+    // Ignore an empty names => always false
+    if (src.empty() || dst.empty())
+    {
+        return false;
+    }
+
+
+    if
+    (
+        dst.type() == fileName::DIRECTORY
+     && src.type(followLink) != fileName::DIRECTORY
+    )
+    {
+        const fileName dstName(dst/src.name());
+
+        return 0 == std::rename(src.c_str(), dstName.c_str());
+    }
+
+    return 0 == std::rename(src.c_str(), dst.c_str());
+}
+
+
+bool Foam::mvBak(const fileName& src, const std::string& ext)
+{
+    // Ignore an empty name or extension => always false
+    if (src.empty() || ext.empty())
+    {
+        return false;
+    }
+
+    if (exists(src, false))
+    {
+        const int maxIndex = 99;
+        char index[3];
+
+        for (int n = 0; n <= maxIndex; n++)
+        {
+            fileName dstName(src + "." + ext);
+            if (n)
+            {
+                sprintf(index, "%02d", n);
+                dstName += index;
+            }
+
+            // avoid overwriting existing files, except for the last
+            // possible index where we have no choice
+            if (!exists(dstName, false) || n == maxIndex)
+            {
+                return (0 == std::rename(src.c_str(), dstName.c_str()));
+            }
+        }
+    }
+
+    // fall-through: nothing to do
+    return false;
+}
+
+
+bool Foam::rm(const fileName& file)
+{
+    if (MSwindows::debug)
+    {
+        Info<< "Removing : " << file << endl;
+    }
+
+    // Ignore an empty name => always false
+    if (file.empty())
+    {
+        return false;
+    }
+
+
+    // If removal of plain file name failed, try with .gz
+
+    return
+    (
+        0 == std::remove(file.c_str())
+     || 0 == std::remove((file + ".gz").c_str())
+    );
+}
+
+
+bool Foam::rmDir(const fileName& directory, const bool silent)
+{
+    // Iterate contents (ignores an empty directory name)
+    // Also retain hidden files/dirs for removal
+
+    MSwindows::directoryIterator dirIter(directory, true);
+
+    if (!dirIter.exists())
+    {
+        if (!silent)
+        {
+            WarningInFunction
+                << "cannot open directory " << directory << endl;
+        }
+    }
+
+    if (MSwindows::debug)
+    {
+        InfoInFunction
+            << " : removing directory " << directory << endl;
+    }
+
+
+    // Process each directory entry, counting any errors encountered
+    label nErrors = 0;
+
+    for (/*nil*/; dirIter; ++dirIter)
+    {
+        const std::string& item = *dirIter;
+
+        // Allow invalid characters (spaces, quotes, etc),
+        // otherwise we cannot remove subdirs with these types of names.
+        // -> const fileName path = directory/name; <-
+
+        const fileName path(fileName::concat(directory, item));
+
+        if (path.type(false) == fileName::DIRECTORY)
+        {
+            if (!rmDir(path, true))  // Only report errors at the top-level
+            {
+                ++nErrors;
+            }
+        }
+        else
+        {
+            if (!rm(path))
+            {
+                ++nErrors;
+            }
+        }
+    }
+
+    if (nErrors)
+    {
+        if (!silent)
+        {
+            WarningInFunction
+                << "failed to remove directory " << directory << nl
+                << "could not remove " << nErrors << " sub-entries" << endl;
+        }
+    }
+    else
+    {
+        if (!::RemoveDirectory(directory.c_str()))
+        {
+            ++nErrors;
+            if (!silent)
+            {
+                WarningInFunction
+                    << "failed to remove directory " << directory << endl;
+            }
+        }
+    }
+
+    return !nErrors;
+}
+
+
+unsigned int Foam::sleep(const unsigned int sec)
+{
+    ::Sleep(1000*sec);  // in milliseconds
+
+    return 0;
+}
+
+
+void Foam::fdClose(const int fd)
+{
+    if (::_close(fd) != 0)
+    {
+        FatalErrorInFunction
+            << "close error on " << fd << endl
+            << abort(FatalError);
+    }
+}
+
+
+bool Foam::ping
+(
+    const std::string& destName,
+    const label destPort,
+    const label timeOut
+)
+{
+    // Appears that socket calls require adminstrator privileges.
+    // Skip for now.
+
+    if (MSwindows::debug)
+    {
+        Info<< "MSwindows does not support ping" << endl;
+    }
+
+    return false;
+}
+
+
+bool Foam::ping(const std::string& host, const label timeOut)
+{
+    return ping(host, 222, timeOut) || ping(host, 22, timeOut);
+}
+
+
+int Foam::system(const std::string& command, const bool bg)
+{
+    if (MSwindows::debug && bg)
+    {
+        InfoInFunction
+            << "MSwindows does not support background (fork) tasks" << endl;
+    }
+
+    return std::system(command.c_str());
+}
+
+
+int Foam::system(const CStringList& command, const bool bg)
+{
+    if (command.empty())
+    {
+        // Treat an empty command as a successful no-op.
+        // For consistency with POSIX (man sh) behaviour for (sh -c command),
+        // which is what is mostly being replicated here.
+        return 0;
+    }
+
+    const int count = command.size();
+
+    std::string cmd;
+
+    for (int i = 0; i < count; ++i)
+    {
+        if (i) cmd += ' ';
+        cmd += command[i];
+    }
+
+    return system(cmd, bg);
+}
+
+
+int Foam::system(const UList<Foam::string>& command, const bool bg)
+{
+    if (command.empty())
+    {
+        // Treat an empty command as a successful no-op.
+        return 0;
+    }
+
+    const int count = command.size();
+
+    std::string cmd;
+
+    for (int i = 0; i < count; ++i)
+    {
+        if (i) cmd += ' ';
+        cmd += command[i];
+    }
+
+    return system(cmd, bg);
+}
+
+
+// Explicitly track loaded libraries, rather than use
+// EnumerateLoadedModules64 and have to link against
+// Dbghelp.dll
+// Details at http://msdn.microsoft.com/en-us/library/ms679316(v=vs.85).aspx
+
+static std::unordered_map<void*, std::string> libsLoaded;
+
+
+void* Foam::dlOpen(const fileName& libName, const bool check)
+{
+    if (MSwindows::debug)
+    {
+        std::cout
+            << "dlOpen(const fileName&)"
+            << " : dlopen of " << libName << std::endl;
+    }
+
+    // Map "libXX.so" and "libXX" to "libXX.dll"
+
+    fileName winLibName(libName.lessExt().ext("dll"));
+    void* handle = ::LoadLibrary(winLibName.c_str());
+
+    if (handle)
+    {
+        libsLoaded[handle] = libName.lessExt();
+    }
+    else if (check)
+    {
+        WarningInFunction
+            << "dlopen error : " << MSwindows::lastError()
+            << endl;
+    }
+
+    if (MSwindows::debug)
+    {
+        std::cout
+            << "dlOpen(const fileName&)"
+            << " : dlopen of " << libName
+            << " handle " << handle << std::endl;
+    }
+
+    return handle;
+}
+
+
+bool Foam::dlClose(void* const handle)
+{
+    if (MSwindows::debug)
+    {
+        std::cout
+            << "dlClose(void*)"
+            << " : dlclose of handle " << handle << std::endl;
+    }
+
+    const bool ok = ::FreeLibrary(static_cast<HMODULE>(handle));
+
+    if (ok)
+    {
+        libsLoaded.erase(handle);
+    }
+
+    return ok;
+}
+
+
+void* Foam::dlSymFind(void* handle, const std::string& symbol, bool required)
+{
+    if (!required && (!handle || symbol.empty()))
+    {
+        return nullptr;
+    }
+
+    if (MSwindows::debug)
+    {
+        std::cout
+            << "dlSymFind(void*, const std::string&, bool)"
+            << " : dlsym of " << symbol << std::endl;
+    }
+
+    // Get address of symbol, or nullptr on failure
+    void* fun =
+        reinterpret_cast<void *>
+        (
+            ::GetProcAddress(static_cast<HMODULE>(handle), symbol.c_str())
+        );
+
+    // Any error?
+    if (!fun && required)
+    {
+        WarningInFunction
+            << "Cannot lookup symbol " << symbol << " : "
+            << MSwindows::lastError() << endl;
+    }
+
+    return fun;
+}
+
+
+Foam::fileNameList Foam::dlLoaded()
+{
+    DynamicList<fileName> libs(libsLoaded.size());
+
+    for (const auto& item : libsLoaded)
+    {
+        libs.append(item.second);
+    }
+
+    if (MSwindows::debug)
+    {
+        std::cout
+            << "dlLoaded()"
+            << " : determined loaded libraries :" << libs.size() << std::endl;
+    }
+
+    return libs;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/MSwindows.H b/src/OSspecific/MSwindows/MSwindows.H
new file mode 100644
index 0000000000000000000000000000000000000000..e0f7c317b2e6f6892570d6fdbdd355e944532665
--- /dev/null
+++ b/src/OSspecific/MSwindows/MSwindows.H
@@ -0,0 +1,69 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Namespace
+    Foam::MSwindows
+
+Description
+    OS-specific functions implemented for MS-windows.
+
+SourceFiles
+    MSwindows.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef MSwindows_H
+#define MSwindows_H
+
+#include "className.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace MSwindows
+{
+    //- Declare namespace and its debug switch
+    NamespaceName("MSwindows");
+
+    //- The last Windows API error from GetLastError
+    std::string lastError();
+
+    //- The user-name from Windows API GetUserName
+    std::string userName();
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/Make/files b/src/OSspecific/MSwindows/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..964f34106e07b8b50f443ead9bfd90ef2d26df2b
--- /dev/null
+++ b/src/OSspecific/MSwindows/Make/files
@@ -0,0 +1,21 @@
+MSwindows.C
+
+cpuInfo/cpuInfo.C
+memInfo/memInfo.C
+
+signals/sigFpe.C
+signals/sigInt.C
+signals/sigQuit.C
+signals/sigSegv.C
+signals/sigStopAtWriteNow.C
+signals/sigWriteNow.C
+signals/timer.C
+
+fileStat/fileStat.C
+
+/* Without inotify */
+fileMonitor/fileMonitor.C
+
+printStack/dummyPrintStack.C
+
+LIB = $(FOAM_LIBBIN)/libOSspecific
diff --git a/src/OSspecific/MSwindows/Make/options b/src/OSspecific/MSwindows/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..3f86d412a62b7c58d486f100cbde05dcc9de5827
--- /dev/null
+++ b/src/OSspecific/MSwindows/Make/options
@@ -0,0 +1 @@
+EXE_INC = $(COMP_FLAGS)
diff --git a/src/OSspecific/MSwindows/cpuInfo/cpuInfo.C b/src/OSspecific/MSwindows/cpuInfo/cpuInfo.C
new file mode 100644
index 0000000000000000000000000000000000000000..d20330b78e4ab82c0e7acfe15d1707c8c1f1c6b7
--- /dev/null
+++ b/src/OSspecific/MSwindows/cpuInfo/cpuInfo.C
@@ -0,0 +1,68 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "cpuInfo.H"
+#include "IOstreams.H"
+
+#include <thread>
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::cpuInfo::cpuInfo()
+:
+    vendor_id(),
+    model_name(),
+    cpu_family(-1),
+    model(-1),
+    cpu_MHz(0),
+    siblings(0),
+    cpu_cores(std::thread::hardware_concurrency())
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::cpuInfo::write(Ostream& os) const
+{
+    if (!vendor_id.empty())
+    {
+        os.writeEntry("vendor_id", vendor_id);
+    }
+    if (!model_name.empty())
+    {
+        os.writeEntry("model_name", model_name);
+    }
+
+    os.writeEntryIfDifferent<int>("cpu_family", -1, cpu_family);
+    os.writeEntryIfDifferent<int>("model", -1, model);
+    os.writeEntryIfDifferent<float>("cpu_MHz", 0, cpu_MHz);
+    os.writeEntryIfDifferent<int>("cpu_cores", 0, cpu_cores);
+    os.writeEntryIfDifferent<int>("siblings", 0, siblings);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/cpuInfo/cpuInfo.H b/src/OSspecific/MSwindows/cpuInfo/cpuInfo.H
new file mode 100644
index 0000000000000000000000000000000000000000..1dbba0b6ee5e2383de33042a7f98920320d76390
--- /dev/null
+++ b/src/OSspecific/MSwindows/cpuInfo/cpuInfo.H
@@ -0,0 +1,111 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::cpuInfo
+
+Description
+    General CPU characteristics.
+
+    If the machine has multiple cpus/cores, only the characteristics
+    of the first core are used.
+
+Note
+    Windows variant only provides the number of cores.
+
+SourceFiles
+    cpuInfo.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef cpuInfo_H
+#define cpuInfo_H
+
+#include <string>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class Ostream;
+
+/*---------------------------------------------------------------------------*\
+                           Class cpuInfo Declaration
+\*---------------------------------------------------------------------------*/
+
+class cpuInfo
+{
+    // Private data
+
+        // Various bits from /proc/cpuinfo
+
+        std::string vendor_id;
+        std::string model_name;
+        int cpu_family;
+        int model;
+        float cpu_MHz;
+        int siblings;
+        int cpu_cores;
+
+
+    // Private Member Functions
+
+        //- Parse /proc/cpuinfo
+        void parse();
+
+        //- No copy construct
+        cpuInfo(const cpuInfo&) = delete;
+
+        //- No copy assignment
+        void operator=(const cpuInfo&) = delete;
+
+public:
+
+    // Constructors
+
+        //- Construct and populate with information
+        cpuInfo();
+
+    //- Destructor
+    ~cpuInfo() = default;
+
+
+    // Member Functions
+
+        //- Write content as dictionary entries
+        void write(Ostream& os) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/cpuTime/cpuTime.H b/src/OSspecific/MSwindows/cpuTime/cpuTime.H
new file mode 100644
index 0000000000000000000000000000000000000000..3af1aa192e926c01aded267faa0cd5d8f3c6e8ae
--- /dev/null
+++ b/src/OSspecific/MSwindows/cpuTime/cpuTime.H
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::cpuTime
+
+Description
+    Selection of preferred clock mechanism for the elapsed cpu time.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef cpuTime_H
+#define cpuTime_H
+
+#include "cpuTimeCxx.H"
+#include "cpuTimeFwd.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/cpuTime/cpuTimeFwd.H b/src/OSspecific/MSwindows/cpuTime/cpuTimeFwd.H
new file mode 100644
index 0000000000000000000000000000000000000000..bc7d1885f3bc83ac4e46643683220ddbcb845caa
--- /dev/null
+++ b/src/OSspecific/MSwindows/cpuTime/cpuTimeFwd.H
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::cpuTime
+
+Description
+    Selection of preferred clock mechanism for the elapsed cpu time.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef cpuTimeFwd_H
+#define cpuTimeFwd_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    class cpuTimeCxx;
+
+    typedef cpuTimeCxx cpuTime;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/fileMonitor/fileMonitor.C b/src/OSspecific/MSwindows/fileMonitor/fileMonitor.C
new file mode 100644
index 0000000000000000000000000000000000000000..425a0c333d006645d06d87c4fbf2de751ea3d76a
--- /dev/null
+++ b/src/OSspecific/MSwindows/fileMonitor/fileMonitor.C
@@ -0,0 +1,625 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2011, 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "fileMonitor.H"
+#include "IOstreams.H"
+#include "Pstream.H"
+#include "PackedList.H"
+#include "PstreamReduceOps.H"
+#include "OSspecific.H"
+#include "regIOobject.H"     // for fileModificationSkew symbol
+
+#ifdef _WIN32
+#undef FOAM_USE_INOTIFY
+#endif
+
+#ifdef FOAM_USE_INOTIFY
+    #include <unistd.h>
+    #include <sys/inotify.h>
+    #include <sys/ioctl.h>
+    #include <errno.h>
+    #define EVENT_SIZE  ( sizeof (struct inotify_event) )
+    #define EVENT_LEN   (EVENT_SIZE + 16)
+    #define EVENT_BUF_LEN     ( 1024 * EVENT_LEN )
+#endif
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::Enum
+<
+    Foam::fileMonitor::fileState
+>
+Foam::fileMonitor::fileStateNames_
+({
+    { fileState::UNMODIFIED, "unmodified" },
+    { fileState::MODIFIED, "modified" },
+    { fileState::DELETED, "deleted" },
+});
+
+
+namespace Foam
+{
+    defineTypeNameAndDebug(fileMonitor, 0);
+
+    //- Reduction operator for PackedList of fileState
+    class reduceFileStates
+    {
+        public:
+        unsigned int operator()(const unsigned int x, const unsigned int y)
+        const
+        {
+            // x,y are sets of 2bits representing fileState
+
+            unsigned int mask = 3u;
+            unsigned int shift = 0;
+            unsigned int result = 0;
+
+            while (mask)
+            {
+                // Combine state
+                unsigned int xState = (x & mask) >> shift;
+                unsigned int yState = (y & mask) >> shift;
+
+                // Combine and add to result. Combine is such that UNMODIFIED
+                // wins.
+                unsigned int state = min(xState, yState);
+                result |= (state << shift);
+
+                shift += 2;
+                mask <<= 2;
+            }
+            return result;
+        }
+    };
+
+    //- Combine operator for PackedList of fileState
+    class combineReduceFileStates
+    {
+        public:
+        void operator()(unsigned int& x, const unsigned int y) const
+        {
+            x = reduceFileStates()(x, y);
+        }
+    };
+
+
+
+    //-  Internal tracking via stat(3p) or inotify(7)
+    class fileMonitorWatcher
+    {
+    public:
+
+        const bool useInotify_;
+
+        // For inotify
+
+            //- File descriptor for the inotify instance
+            int inotifyFd_;
+
+            //- Current watchIDs and corresponding directory id
+            DynamicList<label> dirWatches_;
+            DynamicList<fileName> dirFiles_;
+
+        // For stat
+
+            //- From watch descriptor to modified time
+            DynamicList<double> lastMod_;
+
+
+
+        //- Initialise inotify
+        inline fileMonitorWatcher(const bool useInotify, const label sz = 20)
+        :
+            useInotify_(useInotify),
+            inotifyFd_(-1)
+        {
+            if (useInotify_)
+            {
+                #ifdef FOAM_USE_INOTIFY
+                inotifyFd_ = inotify_init();
+                dirWatches_.setCapacity(sz);
+                dirFiles_.setCapacity(sz);
+
+                if (inotifyFd_ < 0)
+                {
+                    static bool hasWarned = false;
+                    if (!hasWarned)
+                    {
+                        hasWarned = true;
+                        WarningInFunction
+                            << "Failed allocating an inotify descriptor : "
+                            << string(strerror(errno)) << endl
+                            << "    Please increase the number of allowable "
+                            << "inotify instances" << endl
+                            << "    (/proc/sys/fs/inotify/max_user_instances"
+                            << " on Linux)" << endl
+                            << "    , switch off runTimeModifiable." << endl
+                            << "    or compile this file without "
+                            << "FOAM_USE_INOTIFY"
+                            << " to use time stamps instead of inotify." << endl
+                            << "    Continuing without additional file"
+                            << " monitoring."
+                            << endl;
+                    }
+                }
+                #else
+                    FatalErrorInFunction
+                        << "You selected inotify but this file was compiled"
+                        << " without FOAM_USE_INOTIFY"
+                        << " Please select another fileModification test method"
+                        << exit(FatalError);
+                #endif
+            }
+            else
+            {
+                lastMod_.setCapacity(sz);
+            }
+        }
+
+        //- Remove all watches
+        inline ~fileMonitorWatcher()
+        {
+            #ifdef FOAM_USE_INOTIFY
+            if (useInotify_ && inotifyFd_ >= 0)
+            {
+                forAll(dirWatches_, i)
+                {
+                    if (dirWatches_[i] >= 0)
+                    {
+                        if (inotify_rm_watch(inotifyFd_, int(dirWatches_[i])))
+                        {
+                            WarningInFunction
+                                << "Failed deleting directory watch "
+                                << dirWatches_[i] << endl;
+                        }
+                    }
+                }
+            }
+            #endif
+        }
+
+        inline bool addWatch(const label watchFd, const fileName& fName)
+        {
+            if (useInotify_)
+            {
+                if (inotifyFd_ < 0)
+                {
+                    return false;
+                }
+
+                #ifdef FOAM_USE_INOTIFY
+                // Add/retrieve watch on directory containing file.
+                // Note that fName might be non-existing in special situations
+                // (master-only reading for IODictionaries)
+
+                const fileName dir = fName.path();
+
+                label dirWatchID = -1;
+                if (isDir(dir))
+                {
+                    dirWatchID = inotify_add_watch
+                    (
+                        inotifyFd_,
+                        dir.c_str(),
+                        IN_CLOSE_WRITE
+                    );
+
+                    if (dirWatchID < 0)
+                    {
+                        FatalErrorInFunction
+                            << "Failed adding watch " << watchFd
+                            << " to directory " << fName << " due to "
+                            << string(strerror(errno))
+                            << exit(FatalError);
+                    }
+                }
+
+                if (watchFd < dirWatches_.size() && dirWatches_[watchFd] != -1)
+                {
+                    // Reuse of watchFd : should have dir watchID set to -1.
+                    FatalErrorInFunction
+                        << "Problem adding watch " << watchFd
+                        << " to file " << fName
+                        << abort(FatalError);
+                }
+
+                dirWatches_(watchFd) = dirWatchID;
+                dirFiles_(watchFd) = fName.name();
+                #endif
+            }
+            else
+            {
+                if (watchFd < lastMod_.size() && lastMod_[watchFd] != 0)
+                {
+                    // Reuse of watchFd : should have lastMod set to 0.
+                    FatalErrorInFunction
+                        << "Problem adding watch " << watchFd
+                        << " to file " << fName
+                        << abort(FatalError);
+                }
+
+                lastMod_(watchFd) = highResLastModified(fName);
+            }
+
+            return true;
+        }
+
+        inline bool removeWatch(const label watchFd)
+        {
+            if (useInotify_)
+            {
+                if (inotifyFd_ < 0)
+                {
+                    return false;
+                }
+
+                dirWatches_[watchFd] = -1;
+            }
+            else
+            {
+                lastMod_[watchFd] = 0;
+            }
+            return true;
+        }
+
+    };
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::fileMonitor::checkFiles() const
+{
+    if (useInotify_)
+    {
+        #ifdef FOAM_USE_INOTIFY
+        // Large buffer for lots of events
+        char buffer[EVENT_BUF_LEN];
+
+        while (true)
+        {
+            struct timeval zeroTimeout = {0, 0};
+
+            //- Pre-allocated structure containing file descriptors
+            fd_set fdSet;
+            // Add notify descriptor to select fd_set
+            FD_ZERO(&fdSet);
+            FD_SET(watcher_->inotifyFd_, &fdSet);
+
+            int ready = select
+            (
+                watcher_->inotifyFd_+1,     // num filedescriptors in fdSet
+                &fdSet,             // fdSet with only inotifyFd
+                nullptr,               // No writefds
+                nullptr,               // No errorfds
+                &zeroTimeout        // eNo timeout
+            );
+
+            if (ready < 0)
+            {
+                FatalErrorInFunction
+                    << "Problem in issuing select."
+                    << abort(FatalError);
+            }
+            else if (FD_ISSET(watcher_->inotifyFd_, &fdSet))
+            {
+                // Read events
+                ssize_t nBytes = ::read
+                (
+                    watcher_->inotifyFd_,
+                    buffer,
+                    EVENT_BUF_LEN
+                );
+
+                if (nBytes < 0)
+                {
+                    FatalErrorInFunction
+                        << "read of " << watcher_->inotifyFd_
+                        << " failed with " << label(nBytes)
+                        << abort(FatalError);
+                }
+
+                // Go through buffer, consuming events
+                int i = 0;
+                while (i < nBytes)
+                {
+                    const struct inotify_event* inotifyEvent =
+                        reinterpret_cast<const struct inotify_event*>
+                        (
+                            &buffer[i]
+                        );
+
+                    //Pout<< "watchFd:" << inotifyEvent->wd << nl
+                    //    << "mask:" << inotifyEvent->mask << nl
+                    //  << endl;
+                    //Pout<< "file:" << fileName(inotifyEvent->name) << endl;
+                    //Pout<< "len:" << inotifyEvent->len << endl;
+
+                    if
+                    (
+                        (inotifyEvent->mask & IN_CLOSE_WRITE)
+                     && inotifyEvent->len
+                    )
+                    {
+                        // Search for file
+                        forAll(watcher_->dirWatches_, i)
+                        {
+                            label id = watcher_->dirWatches_[i];
+                            if
+                            (
+                                id == inotifyEvent->wd
+                             && inotifyEvent->name == watcher_->dirFiles_[i]
+                            )
+                            {
+                                // Correct directory and name
+                                localState_[i] = MODIFIED;
+                            }
+                        }
+                    }
+
+                    i += EVENT_SIZE + inotifyEvent->len;
+                }
+            }
+            else
+            {
+                // No data
+                return;
+            }
+        }
+        #endif
+    }
+    else
+    {
+        forAll(watcher_->lastMod_, watchFd)
+        {
+            double oldTime = watcher_->lastMod_[watchFd];
+
+            if (oldTime != 0)
+            {
+                const fileName& fName = watchFile_[watchFd];
+                double newTime = highResLastModified(fName);
+
+                if (newTime == 0)
+                {
+                    localState_[watchFd] = DELETED;
+                }
+                else
+                {
+                    if (newTime > (oldTime + regIOobject::fileModificationSkew))
+                    {
+                        localState_[watchFd] = MODIFIED;
+                    }
+                    else
+                    {
+                        localState_[watchFd] = UNMODIFIED;
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+
+Foam::fileMonitor::fileMonitor(const bool useInotify)
+:
+    useInotify_(useInotify),
+    localState_(20),
+    state_(20),
+    watchFile_(20),
+    freeWatchFds_(2),
+    watcher_(new fileMonitorWatcher(useInotify_, 20))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fileMonitor::~fileMonitor()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+// Note: fName might not exist (on slaves if in master-only mode for
+// regIOobject)
+Foam::label Foam::fileMonitor::addWatch(const fileName& fName)
+{
+    label watchFd;
+
+    label sz = freeWatchFds_.size();
+
+    if (sz)
+    {
+        watchFd = freeWatchFds_[sz-1];
+        freeWatchFds_.setSize(sz-1);
+    }
+    else
+    {
+        watchFd = state_.size();
+    }
+
+    watcher_->addWatch(watchFd, fName);
+
+    if (debug)
+    {
+        Pout<< "fileMonitor : added watch " << watchFd << " on file "
+            << fName << endl;
+    }
+
+    if (watchFd < 0)
+    {
+        WarningInFunction
+            << "could not add watch for file " << fName << endl;
+    }
+    else
+    {
+        localState_(watchFd) = UNMODIFIED;
+        state_(watchFd) = UNMODIFIED;
+        watchFile_(watchFd) = fName;
+    }
+    return watchFd;
+}
+
+
+bool Foam::fileMonitor::removeWatch(const label watchFd)
+{
+    if (debug)
+    {
+        Pout<< "fileMonitor : removing watch " << watchFd << " on file "
+            << watchFile_[watchFd] << endl;
+    }
+
+    freeWatchFds_.append(watchFd);
+    return watcher_->removeWatch(watchFd);
+}
+
+
+const Foam::fileName& Foam::fileMonitor::getFile(const label watchFd) const
+{
+    return watchFile_[watchFd];
+}
+
+
+Foam::fileMonitor::fileState Foam::fileMonitor::getState(const label watchFd)
+const
+{
+    return state_[watchFd];
+}
+
+
+void Foam::fileMonitor::updateStates
+(
+    const bool masterOnly,
+    const bool syncPar
+) const
+{
+    if (Pstream::master() || !masterOnly)
+    {
+        // Update the localState_
+        checkFiles();
+    }
+
+    if (syncPar)
+    {
+        // Pack local state (might be on master only)
+        PackedList<2> stats(state_.size(), MODIFIED);
+        if (Pstream::master() || !masterOnly)
+        {
+            forAll(state_, watchFd)
+            {
+                stats.set
+                (
+                    watchFd,
+                    static_cast<unsigned int>(localState_[watchFd])
+                );
+            }
+        }
+
+
+        // Scatter or reduce to synchronise state
+        if (masterOnly)
+        {
+            // Scatter
+            if (stats.storage().size() == 1)
+            {
+                Pstream::scatter(stats.storage()[0]);
+            }
+            else
+            {
+                Pstream::listCombineScatter(stats.storage());
+            }
+        }
+        else
+        {
+            // Reduce
+            if (stats.storage().size() == 1)
+            {
+                // Optimisation valid for most cases.
+                reduce(stats.storage()[0], reduceFileStates());
+            }
+            else
+            {
+                Pstream::listCombineGather
+                (
+                    stats.storage(),
+                    combineReduceFileStates()
+                );
+            }
+        }
+
+
+        // Update synchronised state
+        forAll(state_, watchFd)
+        {
+            // Assign synchronised state
+            unsigned int stat = stats[watchFd];
+            state_[watchFd] = fileState(stat);
+
+            if (!masterOnly)
+            {
+                // Give warning for inconsistent state
+                if (state_[watchFd] != localState_[watchFd])
+                {
+                    if (debug)
+                    {
+                        Pout<< "fileMonitor : Delaying reading "
+                            << watchFile_[watchFd]
+                            << " due to inconsistent "
+                               "file time-stamps between processors"
+                            << endl;
+                    }
+
+                    WarningInFunction
+                        << "Delaying reading " << watchFile_[watchFd]
+                        << " due to inconsistent "
+                           "file time-stamps between processors" << endl;
+                }
+            }
+        }
+    }
+    else
+    {
+        state_ = localState_;
+    }
+}
+
+
+void Foam::fileMonitor::setUnmodified(const label watchFd)
+{
+    state_[watchFd] = UNMODIFIED;
+    localState_[watchFd] = UNMODIFIED;
+
+    if (!useInotify_)
+    {
+        watcher_->lastMod_[watchFd] = highResLastModified(watchFile_[watchFd]);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/fileMonitor/fileMonitor.H b/src/OSspecific/MSwindows/fileMonitor/fileMonitor.H
new file mode 100644
index 0000000000000000000000000000000000000000..38673a7d0ba80fdedd5d20e0da2f715bb91a6899
--- /dev/null
+++ b/src/OSspecific/MSwindows/fileMonitor/fileMonitor.H
@@ -0,0 +1,165 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010, 2017-2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::fileMonitor
+
+Description
+    Checking for changes to files.
+
+Note
+    The default is to use stat to get the timestamp.
+
+    Compile with FOAM_USE_INOTIFY to use the inotify
+    (Linux specific, since 2.6.13) framework. The problem is that inotify does
+    not work on nfs3 mounted directories!!
+
+SourceFiles
+    fileMonitor.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fileMonitor_H
+#define fileMonitor_H
+
+#include <sys/types.h>
+#include "Enum.H"
+#include "className.H"
+#include "DynamicList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+class fileMonitor;
+class fileMonitorWatcher;
+
+/*---------------------------------------------------------------------------*\
+                         Class fileMonitor Declaration
+\*---------------------------------------------------------------------------*/
+
+class fileMonitor
+{
+public:
+
+    // Public data types
+
+        //- Enumeration defining the file state.
+        enum fileState
+        {
+            UNMODIFIED = 0,
+            MODIFIED = 1,
+            DELETED = 2
+        };
+
+        static const Enum<fileState> fileStateNames_;
+
+private:
+
+    // Private data
+
+        //- Whether to use inotify (requires -DFOAM_USE_INOTIFY, see above)
+        const bool useInotify_;
+
+        //- State for all watchFds based on local files
+        mutable DynamicList<fileState> localState_;
+
+        //- State for all watchFds - synchronised
+        mutable DynamicList<fileState> state_;
+
+        //- Filename for all watchFds
+        DynamicList<fileName> watchFile_;
+
+        //- Free watchFds
+        DynamicList<label> freeWatchFds_;
+
+        //- Watch mechanism (stat or inotify)
+        mutable autoPtr<fileMonitorWatcher> watcher_;
+
+
+    // Private Member Functions
+
+        //- Update localState_ from any events.
+        void checkFiles() const;
+
+        //- No copy construct
+        fileMonitor(const fileMonitor&) = delete;
+
+        //- No copy assignment
+        void operator=(const fileMonitor&) = delete;
+
+
+public:
+
+    // Declare name of the class and its debug switch
+    ClassName("fileMonitor");
+
+    // Constructors
+
+        //- Construct null
+        fileMonitor(const bool useInotify);
+
+
+    //- Destructor
+    ~fileMonitor();
+
+
+    // Member Functions
+
+        //- Add file to watch. Return watch descriptor
+        label addWatch(const fileName&);
+
+        //- Remove file to watch. Return true if successful
+        bool removeWatch(const label watchFd);
+
+        //- Get name of file being watched
+        const fileName& getFile(const label watchFd) const;
+
+        //- Check state using handle
+        fileState getState(const label watchFd) const;
+
+        //- Check state of all files. Updates state_.
+        void updateStates
+        (
+            const bool masterOnly,
+            const bool syncPar
+        ) const;
+
+        //- Reset state (e.g. after having read it) using handle
+        void setUnmodified(const label watchFd);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/fileStat/fileStat.C b/src/OSspecific/MSwindows/fileStat/fileStat.C
new file mode 100644
index 0000000000000000000000000000000000000000..2293653ad12cb5eae789803133f7b3e5f10940ba
--- /dev/null
+++ b/src/OSspecific/MSwindows/fileStat/fileStat.C
@@ -0,0 +1,214 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "fileStat.H"
+#include "IOstreams.H"
+#include "timer.H"
+
+#include <unistd.h>
+
+#undef major
+#undef minor
+#undef makedev
+
+#define major(dev)  int(((dev) >> 8) & 0xff)
+#define minor(dev)  int((dev) & 0xff)
+#define makedev(majNum, minNum) (((unsigned(majNum)) << 8) | (unsigned(minNum)))
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileStat::fileStat()
+:
+    valid_(false)
+{}
+
+
+Foam::fileStat::fileStat
+(
+    const char* fName,
+    const bool followLink,
+    const unsigned int maxTime
+)
+:
+    valid_(false)
+{
+    if (!fName || !fName[0])
+    {
+        return;
+    }
+
+    // Work on volatile
+    volatile bool locIsValid = false;
+
+    timer myTimer(maxTime);
+
+    if (!timedOut(myTimer))
+    {
+        #ifdef _WIN32
+        locIsValid = (::stat(fName, &status_) == 0);
+        #else
+        if (followLink)
+        {
+            locIsValid = (::stat(fName, &status_) == 0);
+        }
+        else
+        {
+            locIsValid = (::lstat(fName, &status_) == 0);
+        }
+        #endif
+    }
+
+    // Copy into (non-volatile, possible register based) member var
+    valid_ = locIsValid;
+}
+
+
+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;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::label Foam::fileStat::size() const
+{
+    return valid_ ? label(status_.st_size) : 0;
+}
+
+
+time_t Foam::fileStat::modTime() const
+{
+    return valid_ ? status_.st_mtime : 0;
+}
+
+
+double Foam::fileStat::dmodTime() const
+{
+    return
+    (
+        valid_
+      ?
+        #ifdef __APPLE__
+        (status_.st_mtime + 1e-9*status_.st_mtimespec.tv_nsec)
+        #elif defined (_WIN32)
+        (status_.st_mtime)
+        #else
+        (status_.st_mtime + 1e-9*status_.st_mtim.tv_nsec)
+        #endif
+      : 0
+    );
+}
+
+
+bool Foam::fileStat::sameDevice(const fileStat& other) const
+{
+    return
+        valid_
+     && (
+            major(status_.st_dev) == major(other.status_.st_dev)
+         && minor(status_.st_dev) == minor(other.status_.st_dev)
+        );
+}
+
+
+bool Foam::fileStat::sameINode(const fileStat& other) const
+{
+    return valid_ && (status_.st_ino == other.status_.st_ino);
+}
+
+
+bool Foam::fileStat::sameINode(const label iNode) const
+{
+    return valid_ && (status_.st_ino == ino_t(iNode));
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, fileStat& fs)
+{
+    FixedList<label, 13> list(is);
+
+    fs.valid_ = list[0];
+
+    dev_t st_dev = makedev(list[1], list[2]);
+    fs.status_.st_dev = st_dev;
+
+    fs.status_.st_ino = list[3];
+    fs.status_.st_mode = list[4];
+    fs.status_.st_uid = list[5];
+    fs.status_.st_gid = list[6];
+
+    dev_t st_rdev = makedev(list[7], list[8]);
+    fs.status_.st_rdev = st_rdev;
+
+    fs.status_.st_size = list[9];
+    fs.status_.st_atime = list[10];
+    fs.status_.st_mtime = list[11];
+    fs.status_.st_ctime = list[12];
+
+    is.check(FUNCTION_NAME);
+    return is;
+}
+
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const fileStat& fs)
+{
+    FixedList<label, 13> list;
+
+    list[0] = label(fs.valid_);
+    list[1] = label(major(fs.status_.st_dev));
+    list[2] = label(minor(fs.status_.st_dev));
+    list[3] = label(fs.status_.st_ino);
+    list[4] = label(fs.status_.st_mode);
+    list[5] = label(fs.status_.st_uid);
+    list[6] = label(fs.status_.st_gid);
+    list[7] = label(major(fs.status_.st_rdev));
+    list[8] = label(minor(fs.status_.st_rdev));
+    list[9] = label(fs.status_.st_size);
+    list[10] = label(fs.status_.st_atime);
+    list[11] = label(fs.status_.st_mtime);
+    list[12] = label(fs.status_.st_ctime);
+
+    return os << list;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/fileStat/fileStat.H b/src/OSspecific/MSwindows/fileStat/fileStat.H
new file mode 100644
index 0000000000000000000000000000000000000000..bd736322774d87fc17cf04c60460f82916d34bfc
--- /dev/null
+++ b/src/OSspecific/MSwindows/fileStat/fileStat.H
@@ -0,0 +1,180 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2010, 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::fileStat
+
+Description
+    Wrapper for stat() and lstat() system calls.
+
+Warning
+    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.
+
+SourceFiles
+    fileStat.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fileStat_H
+#define fileStat_H
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "label.H"
+#include "fileName.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class fileStat;
+
+Istream& operator>>(Istream& is, fileStat& fs);
+Ostream& operator<<(Ostream& os, const fileStat& fs);
+
+
+/*---------------------------------------------------------------------------*\
+                          Class fileStat Declaration
+\*---------------------------------------------------------------------------*/
+
+class fileStat
+{
+    // Private data
+
+        struct stat status_;
+
+        bool valid_;
+
+
+public:
+
+    // Constructors
+
+        //- Empty constructor
+        fileStat();
+
+        //- 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.
+        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.
+        fileStat
+        (
+            const fileName& fName,
+            const bool followLink = true,
+            const unsigned int maxTime = 0
+        );
+
+        //- Construct from Istream
+        explicit fileStat(Istream& is);
+
+
+    // Member Functions
+
+    // Access
+
+        //- Raw status
+        const struct stat& status() const
+        {
+            return status_;
+        }
+
+        //- Was file-stat successful?
+        bool valid() const
+        {
+            return valid_;
+        }
+
+        //- Size in bytes. Zero for an invalid file-stat.
+        label size() const;
+
+        //- Return the modification time in seconds.
+        //  Zero for an invalid file-stat.
+        time_t modTime() const;
+
+        //- Return the modification time in seconds (nanosecond resolution)
+        //  Zero for an invalid file-stat.
+        double dmodTime() const;
+
+
+    // Check
+
+        //- Compare two fileStats for same device
+        bool sameDevice(const fileStat& other) const;
+
+        //- Compare two fileStats for same Inode
+        bool sameINode(const fileStat& other) const;
+
+        //- Compare state against inode
+        bool sameINode(const label iNode) const;
+
+
+    // IOstream Operators
+
+        friend Istream& operator>>(Istream& is, fileStat& fs);
+        friend Ostream& operator<<(Ostream& os, const fileStat& fs);
+
+
+    // Housekeeping
+
+        //- Deprecated(2019-04) Was file-stat successful?
+        //  \deprecated(2019-04) - use valid() method
+        bool isValid() const { return valid_; }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/memInfo/memInfo.C b/src/OSspecific/MSwindows/memInfo/memInfo.C
new file mode 100644
index 0000000000000000000000000000000000000000..62f86568a8c3a1159e43b42ce24daa959ec2744a
--- /dev/null
+++ b/src/OSspecific/MSwindows/memInfo/memInfo.C
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010, 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "memInfo.H"
+#include "OSspecific.H"
+#include "IOstreams.H"
+
+#include <fstream>
+#include <string>
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::memInfo::memInfo()
+:
+    peak_(0),
+    size_(0),
+    rss_(0),
+    free_(0)
+{
+    update();
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+bool Foam::memInfo::valid() const
+{
+    return peak_ > 0;
+}
+
+
+void Foam::memInfo::clear()
+{
+    peak_ = size_ = rss_ = 0;
+    free_ = 0;
+}
+
+
+const Foam::memInfo& Foam::memInfo::update()
+{
+    clear();
+
+    // Not supported under Windows
+
+    return *this;
+}
+
+
+void Foam::memInfo::write(Ostream& os) const
+{
+    os.writeEntry("size", size_);
+    os.writeEntry("peak", peak_);
+    os.writeEntry("rss", rss_);
+    os.writeEntry("free", free_);
+}
+
+
+// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, memInfo& m)
+{
+    is.readBegin("memInfo");
+    is  >> m.peak_ >> m.size_ >> m.rss_ >> m.free_;
+    is.readEnd("memInfo");
+
+    is.check(FUNCTION_NAME);
+    return is;
+}
+
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const memInfo& m)
+{
+    os  << token::BEGIN_LIST
+        << m.peak_ << token::SPACE
+        << m.size_ << token::SPACE
+        << m.rss_  << token::SPACE
+        << m.free_
+        << token::END_LIST;
+
+    os.check(FUNCTION_NAME);
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/memInfo/memInfo.H b/src/OSspecific/MSwindows/memInfo/memInfo.H
new file mode 100644
index 0000000000000000000000000000000000000000..9e2621033823ce760d63c7699fa4d6020115b4c9
--- /dev/null
+++ b/src/OSspecific/MSwindows/memInfo/memInfo.H
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010, 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::memInfo
+
+Description
+    Memory usage information for the current process, and the system memory
+    that is free.
+
+Note
+    Windows variant does nothing.
+
+SourceFiles
+    memInfo.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef memInfo_H
+#define memInfo_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of friend functions and operators
+class memInfo;
+class Istream;
+class Ostream;
+
+Istream& operator>>(Istream& is, memInfo& m);
+Ostream& operator<<(Ostream& os, const memInfo& m);
+
+
+/*---------------------------------------------------------------------------*\
+                           Class memInfo Declaration
+\*---------------------------------------------------------------------------*/
+
+class memInfo
+{
+    // Private data
+
+        //- Peak memory used by the process (VmPeak in /proc/PID/status)
+        int peak_;
+
+        //- Memory used by the process (VmSize in /proc/PID/status)
+        int size_;
+
+        //- Resident set size of the process (VmRSS in /proc/PID/status)
+        int rss_;
+
+        //- System memory free (MemFree in /proc/meminfo)
+        int free_;
+
+public:
+
+    // Constructors
+
+        //- Construct and populate with values
+        memInfo();
+
+
+    //- Destructor
+    ~memInfo() = default;
+
+
+    // Member Functions
+
+        //- True if the memory information appears valid
+        bool valid() const;
+
+        //- Reset to zero
+        void clear();
+
+        //- Update according to /proc/PID/status and /proc/memory contents
+        const memInfo& update();
+
+
+        //- Peak memory (VmPeak in /proc/PID/status) at last update()
+        inline int peak() const
+        {
+            return peak_;
+        }
+
+        //- Memory size (VmSize in /proc/PID/status) at last update()
+        inline int size() const
+        {
+            return size_;
+        }
+
+        //- Resident set size (VmRSS in /proc/PID/status) at last update()
+        inline int rss() const
+        {
+            return rss_;
+        }
+
+        //- System memory free (MemFree in /proc/meminfo)
+        inline int free() const
+        {
+            return free_;
+        }
+
+
+      // Write
+
+        //- Write content as dictionary entries
+        void write(Ostream& os) const;
+
+
+    // IOstream Operators
+
+        //- Read peak/size/rss from stream
+        friend Istream& operator>>(Istream& is, memInfo& m);
+
+        //- Write peak/size/rss to stream
+        friend Ostream& operator<<(Ostream& os, const memInfo& m);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/printStack/dummyPrintStack.C b/src/OSspecific/MSwindows/printStack/dummyPrintStack.C
new file mode 100644
index 0000000000000000000000000000000000000000..fbbf9d8278c6c14e9c51ce5ab494ae540df92128
--- /dev/null
+++ b/src/OSspecific/MSwindows/printStack/dummyPrintStack.C
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2017 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "error.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+void Foam::error::safePrintStack(std::ostream& os)
+{}
+
+
+void Foam::error::printStack(Ostream& os)
+{}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/regExp/regExp.H b/src/OSspecific/MSwindows/regExp/regExp.H
new file mode 100644
index 0000000000000000000000000000000000000000..b608dd298a4aaad4b84bea73afe6b971fa052f9d
--- /dev/null
+++ b/src/OSspecific/MSwindows/regExp/regExp.H
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::regExp
+
+Description
+    Selection of preferred regular expression implementation
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef regExp_H
+#define regExp_H
+
+#include "regExpCxx.H"
+#include "regExpFwd.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/regExp/regExpFwd.H b/src/OSspecific/MSwindows/regExp/regExpFwd.H
new file mode 100644
index 0000000000000000000000000000000000000000..ff16d90118277f50b83b4cd713e3d1faa51e0c57
--- /dev/null
+++ b/src/OSspecific/MSwindows/regExp/regExpFwd.H
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::regExp
+
+Description
+    Selection of preferred regular expression implementation
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef regExpFwd_H
+#define regExpFwd_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    class regExpCxx;
+
+    typedef regExpCxx regExp;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigFpe.C b/src/OSspecific/MSwindows/signals/sigFpe.C
new file mode 100644
index 0000000000000000000000000000000000000000..177dafc1619177072c8b8479a1c3db2f6463eb9e
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigFpe.C
@@ -0,0 +1,235 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2016-2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigFpe.H"
+#include "error.H"
+#include "JobInfo.H"
+#include "OSspecific.H"
+#include "IOstreams.H"
+#include "Switch.H"
+#include "UList.H"
+
+#include <float.h>  // For *fp functions
+#include <limits>
+
+// File-local functions
+#include "signalMacros.C"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+bool Foam::sigFpe::switchFpe_(Foam::debug::optimisationSwitch("trapFpe", 0));
+bool Foam::sigFpe::switchNan_(Foam::debug::optimisationSwitch("setNaN", 0));
+
+bool Foam::sigFpe::sigActive_ = false;
+bool Foam::sigFpe::nanActive_ = false;
+
+// Saved old FPE signal trapping setting (file-local variable)
+static unsigned int oldFpe_ = 0u;
+
+
+static void clearFpe()
+{
+    #ifndef Foam_no_sigFpe
+    _clearfp();
+    _controlfp(oldFpe_, 0xFFFFFFFF);
+    #endif
+}
+
+
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+// Can turn on/off via env variable containing a bool (true|false|on|off ...)
+// or by the specified flag
+static bool isTrue(const char* envName, bool deflt)
+{
+    const auto str(Foam::getEnv(envName));
+
+    if (str.size())
+    {
+        Foam::Switch sw(str, true);  // Silently ignores bad input
+
+        if (sw.valid())
+        {
+            return sw;
+        }
+    }
+
+    // Env was not set or did not contain a valid bool value
+    return deflt;
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sigFpe::sigHandler(int)
+{
+    resetHandler("SIGFPE", SIGFPE);
+
+    jobInfo.signalEnd();        // Update jobInfo file
+    error::printStack(Perr);
+    clearFpe();
+    ::raise(SIGFPE);            // Throw signal (to old handler)
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sigFpe::sigFpe()
+{
+    set(false);
+}
+
+
+Foam::sigFpe::ignore::ignore()
+:
+    wasActive_(sigFpe::active())
+{
+    if (wasActive_)
+    {
+        sigFpe::unset();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sigFpe::~sigFpe()
+{
+    unset(false);
+}
+
+
+Foam::sigFpe::ignore::~ignore()
+{
+    restore();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::sigFpe::ignore::restore()
+{
+    if (wasActive_)
+    {
+        sigFpe::set();
+    }
+    wasActive_ = false;
+}
+
+
+bool Foam::sigFpe::requested()
+{
+    return isTrue("FOAM_SIGFPE", switchFpe_);
+}
+
+
+void Foam::sigFpe::set(bool verbose)
+{
+    if (!sigActive_ && requested())
+    {
+        #ifdef Foam_no_sigFpe
+
+        if (verbose)
+        {
+            Info<< "trapFpe: Floating point exception trapping ";
+            Info<< "- disabled on this platform" << endl;
+        }
+
+        #else
+
+        oldFpe_ = _controlfp(0, 0);
+
+        const unsigned int newFpe =
+        (
+            oldFpe_ & ~(_EM_ZERODIVIDE | _EM_INVALID | _EM_OVERFLOW)
+        );
+
+        _controlfp(newFpe, _MCW_EM);
+
+        setHandler("SIGFPE", SIGFPE, sigHandler);
+
+        sigActive_ = true;
+
+        if (verbose)
+        {
+            Info<< "trapFpe: Floating point exception trapping ";
+
+            if (sigActive_)
+            {
+                Info<< "enabled (FOAM_SIGFPE)." << endl;
+            }
+            else
+            {
+                Info<< "- not supported on this platform" << endl;
+            }
+        }
+        #endif
+    }
+
+
+    nanActive_ = false;
+    if (isTrue("FOAM_SETNAN", switchNan_))
+    {
+        if (verbose)
+        {
+            Info<< "setNaN : Initialise allocated memory to NaN "
+                << "- not supported on this platform" << endl;
+        }
+    }
+}
+
+
+void Foam::sigFpe::unset(bool verbose)
+{
+    if (sigActive_)
+    {
+        if (verbose)
+        {
+            Info<< "sigFpe : Disabling floating point exception trapping"
+                << endl;
+        }
+
+        sigActive_ = false;
+
+        clearFpe();
+
+        resetHandler("SIGFPE", SIGFPE);
+    }
+
+    nanActive_ = false;
+}
+
+
+void Foam::sigFpe::fillNan(UList<scalar>& list)
+{
+    list = std::numeric_limits<scalar>::signaling_NaN();
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigFpe.H b/src/OSspecific/MSwindows/signals/sigFpe.H
new file mode 100644
index 0000000000000000000000000000000000000000..67c23d4cb2eeafa1488d6e9c7ad380ed2db02bb2
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigFpe.H
@@ -0,0 +1,186 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sigFpe
+
+Description
+    Set up trapping for floating point exceptions (signal FPE).
+
+    Defined by controlDict InfoSwitch entries:
+    - \par trapFpe
+      Enable floating point exception trapping.
+
+    - \par setNaN
+      Initialization all malloced memory to NaN.
+      Combined with \c trapFpe, this causes usage of uninitialized scalars
+      to trigger an abort.
+
+    Environment variables:
+      - \par FOAM_SIGFPE (true|false)
+        overrides \c trapFpe
+      - \par FOAM_SETNAN  (true|false)
+        overrides \c setNaN
+
+    Note that trapping can be set/removed through the static member functions
+    or through the scope of the object (constructor sets trapping; destructor
+    restores original). The class behaves as a singleton.
+
+SourceFiles
+    sigFpe.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sigFpe_H
+#define sigFpe_H
+
+#include "scalar.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+template<class T> class UList;
+
+/*---------------------------------------------------------------------------*\
+                           Class sigFpe Declaration
+\*---------------------------------------------------------------------------*/
+
+class sigFpe
+{
+    // Private Data
+
+        //- Flag that floating point trapping should be used.
+        //  Can override with FOAM_SIGFPE env variable
+        static bool switchFpe_;
+
+        //- Flag that NaN initialisation should be used.
+        //  Can override with FOAM_SETNAN env variable
+        static bool switchNan_;
+
+        //- Floating point trapping currently active?
+        static bool sigActive_;
+
+        //- Flag to indicate mallocNan is currently active
+        static bool nanActive_;
+
+
+    // Private Member Functions
+
+        //- Handler for caught signals - ends job and prints stack
+        static void sigHandler(int);
+
+
+public:
+
+    // Constructors
+
+        //- Constructor calls set() to activate the FPE signal handler if it
+        //- was was not previously activate and requested() returns true.
+        sigFpe();
+
+
+    //- Destructor calls unset() to deactivate the FPE signal handler
+    //- as required.
+    ~sigFpe();
+
+
+    // Static Member Functions
+
+        //- Check if SIGFPE signals handler is to be enabled.
+        //  This is controlled by the trapFpe entry or the FOAM_SIGFPE
+        //  environment variable
+        static bool requested();
+
+        //- True if SIGFPE handling is currently active.
+        static inline bool active()
+        {
+            return sigActive_;
+        }
+
+        //- True if NaN memory initialisation is currently active.
+        static inline bool nanActive()
+        {
+            return nanActive_;
+        }
+
+        //- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
+        //  Fill memory with NaN when FOAM_SETNAN is %set
+        static void set(bool verbose=false);
+
+        //- Deactivate SIGFPE signal handler and NaN memory initialisation
+        static void unset(bool verbose=false);
+
+        //- Fill data block with NaN values
+        static void fillNan(UList<scalar>& list);
+
+
+    // Helper classes
+
+        //- Helper to locally ignore SIGFPE handling.
+        //  Restores the original state of the SIGFPE handler on destruction.
+        class ignore
+        {
+            //- The signal handler state when entering
+            bool wasActive_;
+
+            //- No copy construct
+            ignore(const ignore&) = delete;
+
+            //- No copy assignment
+            void operator=(const ignore&) = delete;
+
+            //- No move construct
+            ignore(ignore&&) = delete;
+
+            //- No move assignment
+            void operator=(ignore&&) = delete;
+
+
+        public:
+
+            //- Constructor deactivates any previously active SIGFPE handler
+            ignore();
+
+            //- Destructor restores the original state of SIGFPE handler
+            ~ignore();
+
+            //- Restore the original state of SIGFPE handler
+            void restore();
+        };
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigInt.C b/src/OSspecific/MSwindows/signals/sigInt.C
new file mode 100644
index 0000000000000000000000000000000000000000..0118051cc6ff54a21187060115f7e2f412326f55
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigInt.C
@@ -0,0 +1,96 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigInt.H"
+#include "error.H"
+#include "JobInfo.H"
+#include "IOstreams.H"
+
+// File-local functions
+#include "signalMacros.C"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+bool Foam::sigInt::sigActive_ = false;
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sigInt::sigHandler(int)
+{
+    resetHandler("SIGINT", SIGINT);
+
+    jobInfo.signalEnd();        // Update jobInfo file
+    ::raise(SIGINT);            // Throw signal (to old handler)
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sigInt::sigInt()
+{
+    set(false);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sigInt::~sigInt()
+{
+    unset(false);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::sigInt::set(bool)
+{
+    if (sigActive_)
+    {
+        return;
+    }
+    sigActive_ = true;
+
+    setHandler("SIGINT", SIGINT, sigHandler);
+}
+
+
+void Foam::sigInt::unset(const bool verbose)
+{
+    if (!sigActive_)
+    {
+        return;
+    }
+    sigActive_ = false;
+
+    resetHandler("SIGINT", SIGINT);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigInt.H b/src/OSspecific/MSwindows/signals/sigInt.H
new file mode 100644
index 0000000000000000000000000000000000000000..2e9e1758a01d9fe27bd8759dd9badc4bc2f90e03
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigInt.H
@@ -0,0 +1,102 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sigInt
+
+Description
+    Signal handler for INT interupt.
+
+    The standard interupt handler is overridden to ensure that the
+    runningJob file is removed.
+
+    Can be used either directly through the static member functions or
+    through the scope of the object (constructor sets trapping; destructor
+    restores original).
+
+See also
+    Foam::JobInfo
+
+SourceFiles
+    sigInt.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sigInt_H
+#define sigInt_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class sigInt Declaration
+\*---------------------------------------------------------------------------*/
+
+class sigInt
+{
+    // Private data
+
+        //- Signal trapping enabled?
+        static bool sigActive_;
+
+
+    // Private Member Functions
+
+        static void sigHandler(int);
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        sigInt();
+
+
+    //- Destructor
+    ~sigInt();
+
+
+    // Member functions
+
+        //- Activate SIGINT signal handler
+        static void set(bool verbose=false);
+
+        //- Deactivate SIGINT signal handler
+        static void unset(bool verbose=false);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigQuit.C b/src/OSspecific/MSwindows/signals/sigQuit.C
new file mode 100644
index 0000000000000000000000000000000000000000..2a73744d002d1467d04371efa5fde1ba3667bd1c
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigQuit.C
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigQuit.H"
+#include "error.H"
+#include "JobInfo.H"
+#include "IOstreams.H"
+
+// File-local functions
+#include "signalMacros.C"
+
+// NOTE: SIGBREAK is the best alternative to SIGQUIT on windows
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+bool Foam::sigQuit::sigActive_ = false;
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sigQuit::sigHandler(int)
+{
+    resetHandler("SIGBREAK", SIGBREAK);
+
+    jobInfo.signalEnd();        // Update jobInfo file
+    error::printStack(Perr);
+    ::raise(SIGBREAK);          // Throw signal (to old handler)
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sigQuit::sigQuit()
+{
+    set(false);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sigQuit::~sigQuit()
+{
+    unset(false);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::sigQuit::set(bool)
+{
+    if (sigActive_)
+    {
+        return;
+    }
+    sigActive_ = true;
+
+    setHandler("SIGBREAK", SIGBREAK, sigHandler);
+}
+
+
+void Foam::sigQuit::unset(bool)
+{
+    if (!sigActive_)
+    {
+        return;
+    }
+    sigActive_ = false;
+
+    resetHandler("SIGBREAK", SIGBREAK);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigQuit.H b/src/OSspecific/MSwindows/signals/sigQuit.H
new file mode 100644
index 0000000000000000000000000000000000000000..2f8888d090a03a23ad54112d14891d4f393bb55a
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigQuit.H
@@ -0,0 +1,102 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2017-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sigQuit
+
+Description
+    Signal handler for QUIT interupt.
+
+    The standard interupt handler is overridden to ensure that the
+    runningJob file is removed.
+    Can be used either directly through the static member functions or
+    through the scope of the object (constructor sets trapping; destructor
+    restores original).
+
+See also
+    Foam::JobInfo
+
+SourceFiles
+    sigQuit.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sigQuit_H
+#define sigQuit_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class sigQuit Declaration
+\*---------------------------------------------------------------------------*/
+
+class sigQuit
+{
+    // Private Data
+
+        //- Signal trapping enabled?
+        static bool sigActive_;
+
+
+    // Private Member Functions
+
+        //- Handler for caught signals
+        static void sigHandler(int);
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        sigQuit();
+
+
+    //- Destructor
+    ~sigQuit();
+
+
+    // Member Functions
+
+        //- Activate SIGQUIT signal handler
+        static void set(bool verbose=false);
+
+        //- Deactivate SIGQUIT signal handler
+        static void unset(bool verbose=false);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigSegv.C b/src/OSspecific/MSwindows/signals/sigSegv.C
new file mode 100644
index 0000000000000000000000000000000000000000..6c1a3f36324108837b1f0ff690cd9fd63f17e303
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigSegv.C
@@ -0,0 +1,96 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigSegv.H"
+#include "error.H"
+#include "JobInfo.H"
+#include "IOstreams.H"
+
+// File-local functions
+#include "signalMacros.C"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+bool Foam::sigSegv::sigActive_ = false;
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sigSegv::sigHandler(int)
+{
+    resetHandler("SIGSEGV", SIGSEGV);
+
+    jobInfo.signalEnd();        // Update jobInfo file
+    error::printStack(Perr);
+    ::raise(SIGSEGV);           // Throw signal (to old handler)
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sigSegv::sigSegv()
+{
+    set(false);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sigSegv::~sigSegv()
+{
+    unset(false);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::sigSegv::set(bool)
+{
+    if (sigActive_)
+    {
+        return;
+    }
+    sigActive_ = true;
+
+    setHandler("SIGSEGV", SIGSEGV, sigHandler);
+}
+
+
+void Foam::sigSegv::unset(bool)
+{
+    if (!sigActive_)
+    {
+        return;
+    }
+    sigActive_ = false;
+
+    resetHandler("SIGSEGV", SIGSEGV);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigSegv.H b/src/OSspecific/MSwindows/signals/sigSegv.H
new file mode 100644
index 0000000000000000000000000000000000000000..ff4a8f3ab75fa93fd541740d9e0eaea559a37314
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigSegv.H
@@ -0,0 +1,102 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sigSegv
+
+Description
+    Signal handler for SEGV interupt.
+
+    The standard interupt handler is overridden to ensure that the
+    runningJob file is removed.
+    Can be used either directly through the static member functions or
+    through the scope of the object (constructor sets trapping; destructor
+    restores original).
+
+See also
+    Foam::JobInfo
+
+SourceFiles
+    sigSegv.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sigSegv_H
+#define sigSegv_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class sigSegv Declaration
+\*---------------------------------------------------------------------------*/
+
+class sigSegv
+{
+    // Private Data
+
+        //- Signal trapping enabled?
+        static bool sigActive_;
+
+
+    // Private Member Functions
+
+        //- Handler for caught signals
+        static void sigHandler(int);
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        sigSegv();
+
+
+    //- Destructor
+    ~sigSegv();
+
+
+    // Member functions
+
+        //- Activate SIGSEGV signal handler
+        static void set(bool verbose=false);
+
+        //- Deactivate SIGSEGV signal handler
+        static void unset(bool verbose=false);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigStopAtWriteNow.C b/src/OSspecific/MSwindows/signals/sigStopAtWriteNow.C
new file mode 100644
index 0000000000000000000000000000000000000000..0a459b2721093d7e0f3236aeb90fca8e80b4ac93
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigStopAtWriteNow.C
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigWriteNow.H"
+#include "sigStopAtWriteNow.H"
+#include "error.H"
+#include "JobInfo.H"
+#include "IOstreams.H"
+#include "Time.H"
+
+// File-local functions
+#include "signalMacros.C"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+// Signal number to catch
+int Foam::sigStopAtWriteNow::signal_
+(
+    Foam::debug::optimisationSwitch("stopAtWriteNowSignal", -1)
+);
+
+// Pointer to Time (file-local variable)
+static Foam::Time const* runTimePtr_ = nullptr;
+
+
+// * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+// Register re-reader
+struct addstopAtWriteNowSignalToOpt
+:
+    public ::Foam::simpleRegIOobject
+{
+    addstopAtWriteNowSignalToOpt(const char* name)
+    :
+        ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
+    {}
+
+    virtual ~addstopAtWriteNowSignalToOpt() = default;
+
+    virtual void readData(Foam::Istream& is)
+    {
+        sigStopAtWriteNow::signal_ = readLabel(is);
+        sigStopAtWriteNow::set(true);
+    }
+
+    virtual void writeData(Foam::Ostream& os) const
+    {
+        os << sigStopAtWriteNow::signal_;
+    }
+};
+
+addstopAtWriteNowSignalToOpt addstopAtWriteNowSignalToOpt_
+(
+    "stopAtWriteNowSignal"
+);
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sigStopAtWriteNow::sigHandler(int)
+{
+    resetHandler("stopAtWriteNow", signal_);
+
+    jobInfo.signalEnd(); // Update jobInfo file
+
+    if (runTimePtr_)
+    {
+        Info<< "sigStopAtWriteNow :"
+            << " setting up write and stop at end of the next iteration"
+            << nl << endl;
+        runTimePtr_->stopAt(Time::saWriteNow);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sigStopAtWriteNow::sigStopAtWriteNow()
+{}
+
+
+Foam::sigStopAtWriteNow::sigStopAtWriteNow(const Time& runTime, bool verbose)
+{
+    runTimePtr_ = &runTime; // Store runTime
+    set(verbose);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sigStopAtWriteNow::~sigStopAtWriteNow()
+{
+    if (!active())
+    {
+        return;
+    }
+
+    resetHandler("stopAtWriteNow", signal_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::sigStopAtWriteNow::active()
+{
+    return signal_ > 0;
+}
+
+
+int Foam::sigStopAtWriteNow::signalNumber()
+{
+    return signal_;
+}
+
+
+void Foam::sigStopAtWriteNow::set(bool verbose)
+{
+    if (!active())
+    {
+        return;
+    }
+
+
+    // Check that the signal is different from the writeNowSignal
+    if (sigWriteNow::signalNumber() == signal_)
+    {
+        FatalErrorInFunction
+            << "stopAtWriteNowSignal : " << signal_
+            << " cannot be the same as the writeNowSignal."
+            << " Please change this in the etc/controlDict."
+            << exit(FatalError);
+    }
+
+    if (verbose)
+    {
+        Info<< "sigStopAtWriteNow :"
+            << " Enabling writing and stopping upon signal " << signal_
+            << endl;
+    }
+
+    setHandler("stopAtWriteNow", signal_, sigHandler);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigStopAtWriteNow.H b/src/OSspecific/MSwindows/signals/sigStopAtWriteNow.H
new file mode 100644
index 0000000000000000000000000000000000000000..0464a6d52a41dac277e23cbf939f7cc91e7a1995
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigStopAtWriteNow.H
@@ -0,0 +1,107 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sigStopAtWriteNow
+
+Description
+    Signal handler to write and stop the job.
+    The interrupt is defined by OptimisationSwitches::stopAtWriteNowSignal
+
+SourceFiles
+    sigStopAtWriteNow.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sigStopAtWriteNow_H
+#define sigStopAtWriteNow_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+class Time;
+
+/*---------------------------------------------------------------------------*\
+                      Class sigStopAtWriteNow Declaration
+\*---------------------------------------------------------------------------*/
+
+class sigStopAtWriteNow
+{
+    // Private Data
+
+        //- Signal number to use
+        static int signal_;
+
+
+    // Private Member Functions
+
+        //- Handler for caught signals
+        static void sigHandler(int);
+
+
+public:
+
+    //- Allow setter access to signal_
+    friend class addstopAtWriteNowSignalToOpt;
+
+
+    // Constructors
+
+        //- Construct null
+        sigStopAtWriteNow();
+
+        //- Construct from components
+        sigStopAtWriteNow(const Time& runTime, bool verbose=false);
+
+
+    //- Destructor
+    ~sigStopAtWriteNow();
+
+
+    // Member Functions
+
+        //- Is active?
+        static bool active();
+
+        //- Signal number being used
+        static int signalNumber();
+
+        //- Set/reset signal handler
+        static void set(bool verbose=false);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigWriteNow.C b/src/OSspecific/MSwindows/signals/sigWriteNow.C
new file mode 100644
index 0000000000000000000000000000000000000000..71d309adc5d562a16a99717858cbe1d4afab15c1
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigWriteNow.C
@@ -0,0 +1,154 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigWriteNow.H"
+#include "error.H"
+#include "JobInfo.H"
+#include "IOstreams.H"
+#include "Time.H"
+
+// File-local functions
+#include "signalMacros.C"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+// Signal number to catch
+int Foam::sigWriteNow::signal_
+(
+    Foam::debug::optimisationSwitch("writeNowSignal", -1)
+);
+
+// Pointer to Time (file-local variable)
+static Foam::Time* runTimePtr_ = nullptr;
+
+
+// * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Register re-reader
+struct addwriteNowSignalToOpt
+:
+    public ::Foam::simpleRegIOobject
+{
+    addwriteNowSignalToOpt(const char* name)
+    :
+        ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
+    {}
+
+    virtual ~addwriteNowSignalToOpt() = default;
+
+    virtual void readData(Foam::Istream& is)
+    {
+        sigWriteNow::signal_ = readLabel(is);
+        sigWriteNow::set(true);
+    }
+
+    virtual void writeData(Foam::Ostream& os) const
+    {
+        os << sigWriteNow::signal_;
+    }
+};
+
+addwriteNowSignalToOpt addwriteNowSignalToOpt_("writeNowSignal");
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sigWriteNow::sigHandler(int)
+{
+    if (runTimePtr_)
+    {
+        Info<< "sigWriteNow :"
+            << " setting up write at end of the next iteration" << nl << endl;
+        runTimePtr_->writeOnce();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sigWriteNow::sigWriteNow()
+{}
+
+
+Foam::sigWriteNow::sigWriteNow(Time& runTime, bool verbose)
+{
+    runTimePtr_ = &runTime; // Store runTime
+    set(verbose);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sigWriteNow::~sigWriteNow()
+{
+    if (!active())
+    {
+        return;
+    }
+
+    resetHandler("writeNow", signal_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::sigWriteNow::active()
+{
+    return signal_ > 0;
+}
+
+
+int Foam::sigWriteNow::signalNumber()
+{
+    return signal_;
+}
+
+
+void Foam::sigWriteNow::set(bool verbose)
+{
+    if (!active())
+    {
+        return;
+    }
+
+    if (verbose)
+    {
+        Info<< "sigWriteNow :"
+            << " Enabling writing upon signal " << signal_ << nl;
+    }
+
+    setHandler("writeNow", signal_, sigHandler);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/sigWriteNow.H b/src/OSspecific/MSwindows/signals/sigWriteNow.H
new file mode 100644
index 0000000000000000000000000000000000000000..8ba2cedc89f0122e67d74e3e0fd6b810967de8aa
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/sigWriteNow.H
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sigWriteNow
+
+Description
+    Signal handler to write once and continue.
+    The interrupt is defined by OptimisationSwitches::writeNowSignal
+
+SourceFiles
+    sigWriteNow.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sigWriteNow_H
+#define sigWriteNow_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+class Time;
+
+/*---------------------------------------------------------------------------*\
+                         Class sigWriteNow Declaration
+\*---------------------------------------------------------------------------*/
+
+class sigWriteNow
+{
+    // Private Data
+
+        //- Signal number to use
+        static int signal_;
+
+
+    // Private Member Functions
+
+        //- Handler for caught signals
+        static void sigHandler(int);
+
+
+public:
+
+    //- Allow setter access to signal_
+    friend class addwriteNowSignalToOpt;
+
+
+    // Constructors
+
+        //- Construct null
+        sigWriteNow();
+
+        //- Construct from components
+        sigWriteNow(Time& runTime, bool verbose=false);
+
+
+    //- Destructor
+    ~sigWriteNow();
+
+
+    // Member Functions
+
+        //- Is active?
+        static bool active();
+
+        //- The signal number being used
+        static int signalNumber();
+
+        //- Set/reset signal handler
+        static void set(bool verbose=false);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/signalMacros.C b/src/OSspecific/MSwindows/signals/signalMacros.C
new file mode 100644
index 0000000000000000000000000000000000000000..8950ec7b30989c9ae3a4bb6c3f14f0af760a0d0b
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/signalMacros.C
@@ -0,0 +1,77 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Description
+    File-local code for setting/resetting signal handlers.
+
+SourceFiles
+    signalMacros.C
+
+\*---------------------------------------------------------------------------*/
+
+#include "error.H"
+#include <csignal>
+
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Saved old signal trapping setting (file-local variable)
+static __p_sig_fn_t oldAction_ = SIG_DFL;
+
+
+static void resetHandler(const char *what, int sigNum)
+{
+    const __p_sig_fn_t prev = ::signal(sigNum, oldAction_);
+    oldAction_ = SIG_DFL;
+
+    if (SIG_ERR == prev)
+    {
+        FatalError
+            << "Cannot unset " << what << " signal (" << sigNum
+            << ") trapping" << endl
+            << abort(FatalError);
+    }
+}
+
+
+static void setHandler(const char *what, int sigNum, void (*handler)(int))
+{
+    oldAction_ = ::signal(sigNum, handler);
+
+    if (SIG_ERR == oldAction_)
+    {
+        FatalError
+            << "Could not set " << what << " signal (" << sigNum
+            << ") trapping" << endl
+            << abort(FatalError);
+    }
+}
+
+} // End namespace Foam
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/timer.C b/src/OSspecific/MSwindows/signals/timer.C
new file mode 100644
index 0000000000000000000000000000000000000000..36a0a2af61645864b6b2fd485f5135225cbf076e
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/timer.C
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2010, 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+                            | Copyright (C) 2011 Symscape
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "timer.H"
+#include "error.H"
+#include "MSwindows.H"
+#undef DebugInfo        // Windows name clash with OpenFOAM messageStream
+
+#define WIN32_LEAN_AND_MEAN
+#undef  WINVER
+#define WINVER 0x0500   // To access CreateTimerQueueTimer
+#include <windows.h>
+
+// File-local functions
+#include "signalMacros.C"
+
+#define SIGALRM 14
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(timer, 0);
+}
+
+jmp_buf Foam::timer::envAlarm;
+
+unsigned int Foam::timer::oldTimeOut_ = 0;
+
+static HANDLE hTimer_ = nullptr;
+
+
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+static VOID CALLBACK timerExpired(PVOID lpParam, BOOLEAN TimerOrWaitFired)
+{
+    ::raise(SIGALRM);
+}
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+void Foam::timer::sigHandler(int)
+{
+    DebugInFunction << "Timed out. Jumping." << endl;
+
+    longjmp(envAlarm, 1);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::timer::timer(unsigned int seconds)
+:
+    timeOut_(seconds)
+{
+    if (!timeOut_)
+    {
+        return;
+    }
+
+    // Singleton since handler is static function
+    if (hTimer_)
+    {
+        FatalErrorInFunction
+            << "timer already used."
+            << abort(FatalError);
+    }
+
+    // Set alarm signal handler
+    setHandler("SIGALRM", SIGALRM, sigHandler);
+
+    // Set alarm timer
+    const bool ok = ::CreateTimerQueueTimer
+    (
+        &hTimer_,
+        nullptr,
+        static_cast<WAITORTIMERCALLBACK>(timerExpired),
+        nullptr,
+        timeOut_ * 1000,
+        0,
+        0
+    );
+
+    if (!ok)
+    {
+        hTimer_ = nullptr;
+        FatalErrorInFunction
+            << "CreateTimerQueueTimer, "
+            << MSwindows::lastError() << nl
+            << abort(FatalError);
+    }
+
+    DebugInFunction
+        << "Installing timeout " << int(timeOut_) << " seconds"
+        << " (overriding old timeout " << int(oldTimeOut_) << ")." << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::timer::~timer()
+{
+    if (!timeOut_)
+    {
+        return;
+    }
+
+    DebugInFunction
+        << "timeOut=" << int(timeOut_)
+        << " : resetting timeOut to " << int(oldTimeOut_) << endl;
+
+    // Reset alarm timer
+    const bool ok = ::DeleteTimerQueueTimer(nullptr, hTimer_, nullptr);
+
+    hTimer_ = nullptr;
+
+    if (!ok)
+    {
+        FatalErrorInFunction
+            << "DeleteTimerQueueTimer, "
+            << MSwindows::lastError() << nl
+            << abort(FatalError);
+    }
+
+    resetHandler("SIGALRM", SIGALRM);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/signals/timer.H b/src/OSspecific/MSwindows/signals/timer.H
new file mode 100644
index 0000000000000000000000000000000000000000..823267bb5b9ef9afb4b2cc3eef02474589f98ba9
--- /dev/null
+++ b/src/OSspecific/MSwindows/signals/timer.H
@@ -0,0 +1,130 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2011, 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::timer
+
+Description
+    Implements a timeout mechanism via sigalarm.
+
+    Example usage:
+    \code
+        timer myTimer(5);     // 5 sec
+        ..
+        if (timedOut(myTimer))
+        {
+            // timed out
+        }
+        else
+        {
+            // do something possible blocking
+        }
+    \endcode
+
+    Constructor set signal handler on sigalarm and alarm(). Destructor
+    clears these.
+
+Warning
+    The setjmp restores complete register state so including local vars
+    held in regs. So if in blocking part something gets calced in a stack
+    based variable make sure it is declared 'volatile'.
+
+Note
+    timedOut is macro because setjmp can't be in member function of timer.
+    ?something to do with stack frames.
+
+SourceFiles
+    timer.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef timer_H
+#define timer_H
+
+#include "className.H"
+#include <csetjmp>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//- Check if timeout has occurred
+//  keep setjmp in same stack frame so no function calls
+#define timedOut(x) \
+    ((x).timeOut_ ? setjmp(Foam::timer::envAlarm) : false)
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class timer Declaration
+\*---------------------------------------------------------------------------*/
+
+class timer
+{
+    // Private Data
+
+        //- Old alarm() value
+        static unsigned int oldTimeOut_;
+
+
+    // Private Member Functions
+
+        //- Alarm handler
+        static void sigHandler(int);
+
+
+public:
+
+    // Public Data
+
+        //- Declare name of the class and its debug switch
+        ClassName("timer");
+
+        //- The time-out value (seconds). Needed by macro timedOut
+        unsigned int timeOut_;
+
+        //- State for setjmp. Needed by macro timedOut
+        static jmp_buf envAlarm;
+
+
+    // Constructors
+
+        //- Construct with specified time-out, a value of 0 makes it a no-op.
+        timer(unsigned int seconds);
+
+
+    //- Destructor. Restores the alarm and signal handler as required.
+    ~timer();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //