32#if defined(__sun__) && defined(__GNUC__)
59#include <sys/socket.h>
61#include <netinet/in.h>
65 #define EXT_SO "dylib"
66 #include <mach-o/dyld.h>
99 (void) ::close(STDIN_FILENO);
106 (void) ::dup2(STDERR_FILENO, STDOUT_FILENO);
130 inline bool accept()
const
134 item_.size() && item_ !=
"." && item_ !=
".."
135 && (hidden_ || item_[0] !=
'.')
149 hidden_(allowHidden),
152 if (!dirName.empty())
154 dirptr_ = ::opendir(dirName.c_str());
155 exists_ = (dirptr_ !=
nullptr);
205 while (dirptr_ && (list = ::readdir(dirptr_)) !=
nullptr)
207 item_ = list->d_name;
269 return !envName.empty() && ::getenv(envName.c_str()) !=
nullptr;
276 char*
env = envName.empty() ? nullptr : ::getenv(envName.c_str());
292 const std::string& value,
300 && ::setenv(envName.c_str(), value.c_str(), overwrite) == 0
308 ::gethostname(buf,
sizeof(buf));
320 ::gethostname(buf,
sizeof(buf));
322 struct hostent *hp = ::gethostbyname(buf);
338 ::gethostname(buf,
sizeof(buf));
341 struct hostent *hp = ::gethostbyname(buf);
344 char *
p = ::strchr(hp->h_name,
'.');
358 struct passwd* pw = ::getpwuid(::getuid());
370 return (::geteuid() == 0);
376 char*
env = ::getenv(
"HOME");
379 return fileName(env);
382 struct passwd* pw = ::getpwuid(::getuid());
400 struct passwd* pw = ::getpwnam(
userName.c_str());
420 while (pathLengthLimit ==
path.size())
422 if (::getcwd(
path.data(),
path.size()))
426 else if (errno == ERANGE)
436 <<
"Attempt to increase path length beyond limit of "
441 path.resize(pathLengthLimit);
450 <<
"Couldn't get the current working directory"
461 const char*
env = ::getenv(
"PWD");
464 if (!
env ||
env[0] !=
'/')
467 <<
"PWD is invalid - reverting to physical description"
478 std::string::size_type
pos = 0;
479 std::string::npos != (
pos = dir.find(
"/.",
pos));
488 !dir[
pos] || dir[
pos] ==
'/'
491 || (dir[
pos] ==
'.' && (!dir[
pos+1] || dir[
pos+1] ==
'/'))
495 <<
"PWD contains /. or /.. - reverting to physical description"
506 <<
"PWD is not the cwd() - reverting to physical description"
539 return !dir.empty() && ::chdir(dir.c_str()) == 0;
543bool Foam::mkDir(
const fileName& pathName, mode_t mode)
549 if ((POSIX::debug & 2) && !Pstream::master())
551 error::printStack(Pout);
556 if (pathName.empty())
562 if (::mkdir(pathName.c_str(), mode) == 0)
573 <<
"The filesystem containing " << pathName
574 <<
" does not support the creation of directories."
589 <<
" points outside your accessible address space."
597 <<
"The parent directory does not allow write "
598 "permission to the process,"<<
nl
599 <<
" or one of the directories in " << pathName
600 <<
" did not allow search (execute) permission."
608 <<
"" << pathName <<
" is too long."
616 if (pathName.path().size() &&
mkDir(pathName.path(), mode))
618 return mkDir(pathName, mode);
622 <<
"Couldn't create directory " << pathName
630 <<
"A component used as a directory in " << pathName
631 <<
" is not, in fact, a directory."
639 <<
"Insufficient kernel memory was available to make directory "
649 <<
" refers to a file on a read-only filesystem."
657 <<
"Too many symbolic links were encountered in resolving "
666 <<
"The device containing " << pathName
667 <<
" has no room for the new directory or "
668 <<
"the user's disk quota is exhausted."
676 <<
"Couldn't create directory " << pathName
686bool Foam::chMod(
const fileName& name,
const mode_t m)
691 if ((POSIX::debug & 2) && !Pstream::master())
693 error::printStack(Pout);
698 return !
name.empty() && ::chmod(
name.c_str(), m) == 0;
702mode_t
Foam::mode(
const fileName& name,
const bool followLink)
707 if ((POSIX::debug & 2) && !Pstream::master())
709 error::printStack(Pout);
716 fileStat fileStatus(name, followLink);
717 if (fileStatus.valid())
719 return fileStatus.status().st_mode;
729 const fileName& name,
730 const bool followLink
736 return fileName::Type::UNDEFINED;
744 mode_t m =
mode(name, followLink);
748 return fileName::Type::FILE;
752 return fileName::Type::SYMLINK;
756 return fileName::Type::DIRECTORY;
759 return fileName::Type::UNDEFINED;
765 const fileName& name,
766 const bool checkGzip,
767 const bool followLink
774 if ((POSIX::debug & 2) && !Pstream::master())
776 error::printStack(Pout);
784 && (
mode(name, followLink) ||
isFile(name, checkGzip, followLink))
789bool Foam::isDir(
const fileName& name,
const bool followLink)
794 if ((POSIX::debug & 2) && !Pstream::master())
796 error::printStack(Pout);
801 return !
name.empty() && S_ISDIR(
mode(name, followLink));
807 const fileName& name,
808 const bool checkGzip,
809 const bool followLink
816 if ((POSIX::debug & 2) && !Pstream::master())
818 error::printStack(Pout);
827 S_ISREG(
mode(name, followLink))
828 || (checkGzip && S_ISREG(
mode(name +
".gz", followLink)))
839 if ((POSIX::debug & 2) && !Pstream::master())
841 error::printStack(Pout);
848 fileStat fileStatus(name, followLink);
849 if (fileStatus.valid())
851 return fileStatus.status().st_size;
864 if ((POSIX::debug & 2) && !Pstream::master())
866 error::printStack(Pout);
871 return name.empty() ? 0 : fileStat(name, followLink).modTime();
880 if ((POSIX::debug & 2) && !Pstream::master())
882 error::printStack(Pout);
887 return name.empty() ? 0 : fileStat(name, followLink).dmodTime();
893 const fileName& directory,
894 const fileName::Type type,
896 const bool followLink
900 constexpr int maxNnames = 100;
903 const bool stripgz = filtergz && (
type != fileName::DIRECTORY);
904 const word extgz(
"gz");
910 POSIX::directoryIterator dirIter(directory);
911 if (!dirIter.exists())
916 <<
"cannot open directory " << directory <<
endl;
926 if ((POSIX::debug & 2) && !Pstream::master())
928 error::printStack(Pout);
934 dirEntries.resize(maxNnames);
937 for (; dirIter; ++dirIter)
939 const std::string& item = *dirIter;
944 const fileName
name(fileName::validate(item));
951 (type == fileName::DIRECTORY)
952 || (type == fileName::FILE && !fileName::isBackup(name))
955 if ((directory/name).
type(followLink) == type)
957 if (nEntries >= dirEntries.size())
959 dirEntries.resize(dirEntries.size() + maxNnames);
968 dirEntries[nEntries++] =
name;
975 dirEntries.resize(nEntries);
977 if (nFailed && POSIX::debug)
980 <<
"Foam::readDir() : reading directory " << directory <<
nl
981 << nFailed <<
" entries with invalid characters in their name"
989bool Foam::cp(
const fileName& src,
const fileName& dest,
const bool followLink)
994 if ((POSIX::debug & 2) && !Pstream::master())
996 error::printStack(Pout);
1006 const fileName::Type srcType = src.type(followLink);
1008 fileName destFile(dest);
1011 if (srcType == fileName::FILE)
1014 if (destFile.type() == fileName::DIRECTORY)
1016 destFile /= src.name();
1020 if (!
isDir(destFile.path()) && !
mkDir(destFile.path()))
1040 while (srcStream.get(ch))
1046 if (!srcStream.eof() || !destStream)
1051 else if (srcType == fileName::SYMLINK)
1054 if (destFile.type() == fileName::DIRECTORY)
1056 destFile /= src.name();
1060 if (!
isDir(destFile.path()) && !
mkDir(destFile.path()))
1067 else if (srcType == fileName::DIRECTORY)
1069 if (destFile.type() == fileName::DIRECTORY)
1078 const word srcDirName = src.name();
1079 if (destFile.name() != srcDirName)
1081 destFile /= srcDirName;
1091 char* realSrcPath = realpath(src.c_str(),
nullptr);
1092 char* realDestPath = realpath(destFile.c_str(),
nullptr);
1093 const bool samePath = strcmp(realSrcPath, realDestPath) == 0;
1095 if (POSIX::debug && samePath)
1098 <<
"Attempt to copy " << realSrcPath <<
" to itself" <<
endl;
1119 for (
const fileName& item : files)
1124 <<
"Copying : " << src/item
1125 <<
" to " << destFile/item <<
endl;
1129 Foam::cp(src/item, destFile/item, followLink);
1136 fileName::DIRECTORY,
1141 for (
const fileName& item : dirs)
1146 <<
"Copying : " << src/item
1147 <<
" to " << destFile <<
endl;
1151 Foam::cp(src/item, destFile, followLink);
1163bool Foam::ln(
const fileName& src,
const fileName& dst)
1169 <<
" : Create softlink from : " << src <<
" to " << dst <<
endl;
1170 if ((POSIX::debug & 2) && !Pstream::master())
1172 error::printStack(Pout);
1179 <<
"source name is empty: not linking." <<
endl;
1186 <<
"destination name is empty: not linking." <<
endl;
1193 <<
"destination " << dst <<
" already exists. Not linking."
1198 if (src.isAbsolute() && !
exists(src))
1201 <<
"source " << src <<
" does not exist." <<
endl;
1205 if (::symlink(src.c_str(), dst.c_str()) == 0)
1211 <<
"symlink from " << src <<
" to " << dst <<
" failed." <<
endl;
1216bool Foam::mv(
const fileName& src,
const fileName& dst,
const bool followLink)
1222 if ((POSIX::debug & 2) && !Pstream::master())
1224 error::printStack(Pout);
1229 if (src.empty() || dst.empty())
1236 dst.type() == fileName::DIRECTORY
1237 && src.type(followLink) != fileName::DIRECTORY
1240 const fileName dstName(dst/src.name());
1242 return (0 == std::rename(src.c_str(), dstName.c_str()));
1245 return (0 == std::rename(src.c_str(), dst.c_str()));
1249bool Foam::mvBak(
const fileName& src,
const std::string& ext)
1255 <<
" : moving : " << src <<
" to extension " << ext <<
endl;
1256 if ((POSIX::debug & 2) && !Pstream::master())
1258 error::printStack(Pout);
1263 if (src.empty() || ext.empty())
1270 constexpr const int maxIndex = 99;
1273 for (
int n = 0;
n <= maxIndex; ++
n)
1275 fileName dstName(src +
"." + ext);
1278 ::sprintf(index,
"%02d",
n);
1284 if (!
exists(dstName,
false) ||
n == maxIndex)
1286 return (0 == std::rename(src.c_str(), dstName.c_str()));
1302 if ((POSIX::debug & 2) && !Pstream::master())
1304 error::printStack(Pout);
1318 0 == ::remove(file.c_str())
1319 || 0 == ::remove((file +
".gz").c_str())
1324bool Foam::rmDir(
const fileName& directory,
const bool silent)
1329 POSIX::directoryIterator dirIter(directory,
true);
1330 if (!dirIter.exists())
1335 <<
"cannot open directory " << directory <<
endl;
1345 if ((POSIX::debug & 2) && !Pstream::master())
1347 error::printStack(Pout);
1354 for (; dirIter; ++dirIter)
1356 const std::string& item = *dirIter;
1362 const fileName
path(fileName::concat(directory, item));
1364 if (
path.type(
false) == fileName::DIRECTORY)
1385 <<
"failed to remove directory " << directory <<
nl
1386 <<
"could not remove " << nErrors <<
" sub-entries" <<
endl;
1397 <<
"failed to remove directory " << directory <<
endl;
1409 return ::sleep(sec);
1418 <<
"close error on " << fd <<
endl
1419 <<
abort(FatalError);
1426 const std::string& destName,
1427 const label destPort,
1431 struct hostent *hostPtr;
1432 volatile int sockfd;
1433 struct sockaddr_in destAddr;
1436 if ((hostPtr = ::gethostbyname(destName.c_str())) ==
nullptr)
1439 <<
"gethostbyname error " << h_errno <<
" for host " << destName
1440 <<
abort(FatalError);
1444 addr = (
reinterpret_cast<struct in_addr*
>(*(hostPtr->h_addr_list)))->s_addr;
1447 sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1452 <<
abort(FatalError);
1456 std::memset(
reinterpret_cast<char *
>(&destAddr),
'\0',
sizeof(destAddr));
1457 destAddr.sin_family = AF_INET;
1458 destAddr.sin_port = htons(ushort(destPort));
1459 destAddr.sin_addr.s_addr = addr;
1462 timer myTimer(timeOut);
1476 reinterpret_cast<struct sockaddr*
>(&destAddr),
1477 sizeof(
struct sockaddr)
1483 int connectErr = errno;
1487 if (connectErr == ECONNREFUSED)
1502bool Foam::ping(
const std::string& host,
const label timeOut)
1504 return ping(host, 222, timeOut) ||
ping(host, 22, timeOut);
1511static int waitpid(
const pid_t
pid)
1522 pid_t wpid = ::waitpid(
pid, &status, WUNTRACED);
1527 <<
"some error occurred in child"
1532 if (WIFEXITED(status))
1535 return WEXITSTATUS(status);
1538 if (WIFSIGNALED(status))
1541 return WTERMSIG(status);
1544 if (WIFSTOPPED(status))
1547 return WSTOPSIG(status);
1551 <<
"programming error, status from waitpid() not handled: "
1562int Foam::system(
const std::string& command,
const bool bg)
1564 if (command.empty())
1573 const pid_t child_pid = ::vfork();
1575 if (child_pid == -1)
1578 <<
"vfork() failed for system command " << command
1579 <<
exit(FatalError);
1583 else if (child_pid == 0)
1597 reinterpret_cast<char*
>(0)
1602 <<
"exec failed: " << command
1603 <<
exit(FatalError);
1612 return (bg ? 0 : waitpid(child_pid));
1616int Foam::system(
const CStringList& command,
const bool bg)
1618 if (command.empty())
1632 const pid_t child_pid = ::vfork();
1634 if (child_pid == -1)
1637 <<
"vfork() failed for system command " << command[0]
1638 <<
exit(FatalError);
1642 else if (child_pid == 0)
1650 (void) ::execvp(command[0], command.strings());
1654 <<
"exec(" << command[0] <<
", ...) failed"
1655 <<
exit(FatalError);
1664 return (bg ? 0 : waitpid(child_pid));
1670 if (command.
empty())
1677 const CStringList cmd(command);
1682void*
Foam::dlOpen(
const fileName& libName,
const bool check)
1684 constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
1689 <<
"dlOpen(const fileName&)"
1690 <<
" : dlopen of " << libName << std::endl;
1693 void* handle = ::dlopen(libName.c_str(), ldflags);
1701 libName.find(
'/') == std::string::npos
1702 && !libName.starts_with(
"lib")
1706 libso =
"lib" + libName;
1707 handle = ::dlopen(libso.c_str(), ldflags);
1712 <<
"dlOpen(const fileName&)"
1713 <<
" : dlopen of " << libso << std::endl;
1723 if (!handle && !libso.hasExt(
EXT_SO))
1725 libso = libso.lessExt().ext(
EXT_SO);
1726 handle = ::dlopen(libso.c_str(), ldflags);
1731 <<
"dlOpen(const fileName&)"
1732 <<
" : dlopen of " << libso << std::endl;
1737 if (!handle && check)
1740 <<
"dlopen error : " << ::dlerror() <<
endl;
1746 <<
"dlOpen(const fileName&)"
1747 <<
" : dlopen of " << libName
1748 <<
" handle " << handle << std::endl;
1755void*
Foam::dlOpen(
const fileName& libName, std::string& errorMsg)
1763 errorMsg = ::dlerror();
1777 std::initializer_list<fileName> libNames,
1783 for (
const fileName& libName : libNames)
1801 <<
" : dlclose of handle " << handle << std::endl;
1803 return ::dlclose(handle) == 0;
1807void*
Foam::dlSymFind(
void* handle,
const std::string& symbol,
bool required)
1809 if (!required && (!handle || symbol.empty()))
1817 <<
"dlSymFind(void*, const std::string&, bool)"
1818 <<
" : dlsym of " << symbol << std::endl;
1825 void* fun = ::dlsym(handle, symbol.c_str());
1828 char *err = ::dlerror();
1838 <<
"Cannot lookup symbol " << symbol <<
" : " << err
1849 struct dl_phdr_info *info,
1856 ptr->
append(info->dlpi_name);
1864 DynamicList<fileName> libs;
1866 for (uint32_t i=0; i < _dyld_image_count(); ++i)
1868 libs.
append(_dyld_get_image_name(i));
1878 <<
" : determined loaded libraries :" << libs.size() << std::endl;
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
#define timedOut(x)
Check if timeout has occurred.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
static bool cwdPreference_(Foam::debug::optimisationSwitch("cwd", 0))
static void redirects(const bool bg)
static int collectLibsCallback(struct dl_phdr_info *info, size_t size, void *data)
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void append(const T &val)
Copy append an element to the end of this list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void append(const T &val)
Append an element at the end of the list.
A simple directory contents iterator.
~directoryIterator()
Destructor.
bool exists() const noexcept
Directory open succeeded.
bool good() const noexcept
Directory pointer is valid.
void close()
Close directory.
directoryIterator(const std::string &dirName, bool allowHidden=false)
Construct for dirName, optionally allowing hidden files/dirs.
const std::string & val() const noexcept
The current item.
bool next()
Read next item, always ignoring "." and ".." entries.
directoryIterator & operator++()
Same as next()
const std::string & operator*() const noexcept
Same as val()
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
A class for handling file names.
Type
Enumerations to handle directory entry types.
Wrapper for stat() and lstat() system calls.
A class for handling character strings derived from std::string.
word lessExt() const
Return word without extension (part before last .)
bool hasExt() const
Various checks for extensions.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
#define InfoInFunction
Report an information message using Foam::Info.
constexpr label pathLengthChunk
constexpr label pathLengthMax
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
static Foam::fileName cwd_P()
The physical current working directory path name (pwd -P).
fileName cwd()
The physical or logical current working directory path name.
dimensionedScalar pos(const dimensionedScalar &ds)
string getEnv(const std::string &envName)
Get environment value for given envName.
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable, return true on success.
List< fileName > fileNameList
A List of fileNames.
time_t lastModified(const fileName &name, const bool followLink=true)
Return time of last file modification (normally follows symbolic links).
void fdClose(const int fd)
Close file descriptor.
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
bool isAdministrator()
Is the current user the administrator (root)
bool dlClose(void *handle)
Close a dlopened library using handle. Return true if successful.
bool env(const std::string &envName)
Deprecated(2020-05) check for existence of environment variable.
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
unsigned int sleep(const unsigned int sec)
Sleep for the specified number of seconds.
bool chMod(const fileName &name, const mode_t mode)
Set the file/directory mode, return true on success.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
string userName()
Return the user's login name.
pid_t pgid()
Return the group PID of this process.
Ostream & endl(Ostream &os)
Add newline and flush stream.
string hostName()
Return the system's host name, as per hostname(1)
bool rmDir(const fileName &directory, const bool silent=false)
Remove a directory and its contents (optionally silencing warnings)
void * dlSymFind(void *handle, const std::string &symbol, bool required=false)
Look for symbol in a dlopened library.
bool ping(const std::string &destName, const label port, const label timeOut)
Check if machine is up by pinging given port.
pid_t ppid()
Return the parent PID of this process.
errorManip< error > abort(error &err)
off_t fileSize(const fileName &name, const bool followLink=true)
Return size of file or -1 on failure (normally follows symbolic links).
double highResLastModified(const fileName &, const bool followLink=true)
Return time of last file modification.
void * dlOpen(const fileName &libName, const bool check=true)
Open a shared library and return handle to library.
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
pid_t pid()
Return the PID of this process.
int infoDetailLevel
Global for selective suppression of Info output.
bool mvBak(const fileName &src, const std::string &ext="bak")
Rename to a corresponding backup file.
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
bool cp(const fileName &src, const fileName &dst, const bool followLink=true)
Copy the source to the destination (recursively if necessary).
fileNameList dlLoaded()
Return all loaded libraries.
static Foam::fileName cwd_L()
The logical current working directory path name.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
errorManipArg< error, int > exit(error &err, const int errNo=1)
fileName home()
Return home directory path name for the current user.
string domainName()
Deprecated(2022-01) domain name resolution may be unreliable.
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
bool hasEnv(const std::string &envName)
True if environment variable of given name is defined.
constexpr char nl
The newline '\n' character (0x0a)
bool chDir(const fileName &dir)
Change current directory to the one specified and return true on success.