diff --git a/src/OSspecific/MSwindows/Allwmake b/src/OSspecific/MSwindows/Allwmake
new file mode 100755
index 0000000000..24fb418826
--- /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 0000000000..30fb55792f
--- /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 .
+
+\*---------------------------------------------------------------------------*/
+
+#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
+#include
+#include
+#include
+
+// Windows headers
+#define WIN32_LEAN_AND_MEAN
+#include
+#include // For _close
+#include
+
+
+// * * * * * * * * * * * * * * 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(&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(lpMsgBuf));
+
+ if (n > 0)
+ {
+ output.resize(n+1);
+
+ // Print directly into buffer
+ n = ::snprintf(&(output[0]), n+1, fmt, static_cast(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& 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 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(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
+ (
+ ::GetProcAddress(static_cast(handle), symbol.c_str())
+ );
+
+ // Any error?
+ if (!fun && required)
+ {
+ WarningInFunction
+ << "Cannot lookup symbol " << symbol << " : "
+ << MSwindows::lastError() << endl;
+ }
+
+ return fun;
+}
+
+
+Foam::fileNameList Foam::dlLoaded()
+{
+ DynamicList 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 0000000000..e0f7c317b2
--- /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 .
+
+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 0000000000..964f34106e
--- /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 0000000000..3f86d412a6
--- /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 0000000000..d20330b78e
--- /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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "cpuInfo.H"
+#include "IOstreams.H"
+
+#include
+
+// * * * * * * * * * * * * * 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("cpu_family", -1, cpu_family);
+ os.writeEntryIfDifferent("model", -1, model);
+ os.writeEntryIfDifferent("cpu_MHz", 0, cpu_MHz);
+ os.writeEntryIfDifferent("cpu_cores", 0, cpu_cores);
+ os.writeEntryIfDifferent("siblings", 0, siblings);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/MSwindows/cpuInfo/cpuInfo.H b/src/OSspecific/MSwindows/cpuInfo/cpuInfo.H
new file mode 100644
index 0000000000..1dbba0b6ee
--- /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 .
+
+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
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+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 0000000000..3af1aa192e
--- /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 .
+
+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 0000000000..bc7d1885f3
--- /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 .
+
+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 0000000000..425a0c333d
--- /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 .
+
+\*---------------------------------------------------------------------------*/
+
+#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
+ #include
+ #include
+ #include
+ #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