Loading...
Searching...
No Matches
POSIX.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2016-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27Description
28 POSIX versions of the functions declared in OSspecific.H
29
30\*---------------------------------------------------------------------------*/
31
32#if defined(__sun__) && defined(__GNUC__)
33 // Not certain if this is still required
34 #define _SYS_VNODE_H
35#endif
36
37#include "OSspecific.H"
38#include "POSIX.H"
39#include "fileName.H"
40#include "fileStat.H"
41#include "timer.H"
42#include "DynamicList.H"
43#include "CStringList.H"
44#include "stringOps.H"
45#include "IOstreams.H"
46#include "Pstream.H"
47
48#include <fstream>
49#include <cstdlib>
50#include <cctype>
51
52#include <cstdio>
53#include <unistd.h>
54#include <dirent.h>
55#include <pwd.h>
56#include <errno.h>
57#include <sys/types.h>
58#include <sys/wait.h>
59#include <sys/stat.h>
60#include <sys/socket.h>
61#include <netdb.h>
62#include <netinet/in.h>
63#include <dlfcn.h>
64
65#ifdef __APPLE__
66 #define EXT_SO "dylib"
67 #include <mach-o/dyld.h>
68#else
69 #define EXT_SO "so"
70
71 // PGI does not have __int128_t
72 #ifdef __PGIC__
73 #define __ILP32__
74 #endif
75
76 #include <link.h>
77#endif
79
80// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
82namespace Foam
83{
85}
86
88
90// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
91
92// After a fork in system(), before the exec() do the following
93// - close stdin when executing in background (daemon-like)
94// - redirect stdout to stderr when infoDetailLevel == 0
95static inline void redirects(const bool bg)
96{
97 if (bg)
98 {
99 // Close stdin(0) - unchecked return value
100 (void) ::close(STDIN_FILENO);
101 }
102
103 // Redirect stdout(1) to stderr(2) '1>&2'
104 if (Foam::infoDetailLevel == 0)
105 {
106 // This is correct. 1>&2 means dup2(2, 1);
107 (void) ::dup2(STDERR_FILENO, STDOUT_FILENO);
108 }
109}
110
112// Library loading is normally simply via dlopen(),
113// but SIP (System Integrity Protection) on Apple will generally
114// clear out the DYLD_LIBRARY_PATH set from shell scripts.
115// We thus have FOAM_LD_LIBRARY_PATH as a shadow parameter and use
116// that to attempt loading ourselves
117static inline void* loadLibrary(const Foam::fileName& libName)
118{
119 constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
120
121#ifdef __APPLE__
122 using namespace Foam;
123
124 const char* normal = nullptr;
125 const char* shadow = nullptr;
126
127 if
128 (
129 !libName.isAbsolute()
130 && ((normal = ::getenv("DYLD_LIBRARY_PATH")) == nullptr || !*normal)
131 && ((shadow = ::getenv("FOAM_LD_LIBRARY_PATH")) != nullptr && *shadow)
132 )
133 {
134 // SIP appears to have cleared DYLD_LIBRARY_PATH but the
135 // shadow parameter is available
136
137 const std::string ldPaths(shadow);
138 const auto paths = Foam::stringOps::split(ldPaths, ':');
139
140 for (const auto& p : paths)
141 {
142 if (p.length()) // Split removes empty, but be paranoid
143 {
144 const Foam::fileName fullPath(p.str()/libName);
145 void* handle = ::dlopen(fullPath.c_str(), ldflags);
146 if (handle)
147 {
148 return handle;
149 }
150 }
151 }
152 }
153#endif
154
155 // Regular loading
156 return ::dlopen(libName.c_str(), ldflags);
157}
159
160// * * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * //
161
162namespace Foam
163{
164namespace POSIX
165{
166
167//- A simple directory contents iterator
169{
170 DIR* dirptr_;
171
172 bool exists_;
173
174 bool hidden_;
175
176 std::string item_;
177
178 //- Accept file/dir name
179 inline bool accept() const
180 {
181 return
182 (
183 item_.size() && item_ != "." && item_ != ".."
184 && (hidden_ || item_[0] != '.')
185 );
186 }
187
188
189public:
190
191 // Constructors
192
193 //- Construct for dirName, optionally allowing hidden files/dirs
194 directoryIterator(const std::string& dirName, bool allowHidden = false)
195 :
196 dirptr_(nullptr),
197 exists_(false),
198 hidden_(allowHidden),
199 item_()
200 {
201 if (!dirName.empty())
202 {
203 dirptr_ = ::opendir(dirName.c_str());
204 exists_ = (dirptr_ != nullptr);
205 next(); // Move to first element
206 }
207 }
208
209
210 //- Destructor
212 {
214 }
215
216
217 // Member Functions
218
219 //- Directory open succeeded
220 bool exists() const noexcept
221 {
222 return exists_;
223 }
225 //- Directory pointer is valid
226 bool good() const noexcept
227 {
228 return dirptr_;
229 }
230
231 //- Close directory
232 void close()
233 {
234 if (dirptr_)
235 {
236 ::closedir(dirptr_);
237 dirptr_ = nullptr;
238 }
239 }
241 //- The current item
242 const std::string& val() const noexcept
243 {
244 return item_;
245 }
246
247 //- Read next item, always ignoring "." and ".." entries.
248 // Normally also ignore hidden files/dirs (beginning with '.')
249 // Automatically close when there are no more items
250 bool next()
251 {
252 struct dirent *list;
253
254 while (dirptr_ && (list = ::readdir(dirptr_)) != nullptr)
255 {
256 item_ = list->d_name;
257
258 if (accept())
259 {
260 return true;
261 }
262 }
263 close(); // No more items
264
265 return false;
266 }
267
268
269 // Member Operators
270
271 //- Same as good()
272 operator bool() const noexcept
273 {
274 return good();
275 }
276
277 //- Same as val()
278 const std::string& operator*() const noexcept
279 {
280 return val();
281 }
282
283 //- Same as next()
285 {
286 next();
287 return *this;
288 }
289};
290
291} // End namespace POSIX
292} // End namespace Foam
293
294
295// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
296
297pid_t Foam::pid()
298{
299 return ::getpid();
300}
301
302
304{
305 return ::getppid();
306}
307
308
309pid_t Foam::pgid()
310{
311 return ::getpgrp();
312}
313
314
315bool Foam::hasEnv(const std::string& envName)
317 // An empty envName => always false
318 return !envName.empty() && ::getenv(envName.c_str()) != nullptr;
319}
320
321
322Foam::string Foam::getEnv(const std::string& envName)
323{
324 // Ignore an empty envName => always ""
325 char* env = envName.empty() ? nullptr : ::getenv(envName.c_str());
326
327 if (env)
329 return string(env);
330 }
331
332 // Return null-constructed string rather than string::null
333 // to avoid cyclic dependencies in the construction of globals
334 return string();
335}
336
337
338bool Foam::setEnv
339(
340 const word& envName,
341 const std::string& value,
342 const bool overwrite
343)
344{
345 // Ignore an empty envName => always false
346 return
347 (
348 !envName.empty()
349 && ::setenv(envName.c_str(), value.c_str(), overwrite) == 0
350 );
351}
352
353
355{
356 char buf[128];
357 ::gethostname(buf, sizeof(buf));
358 return buf;
359}
360
361
362// DEPRECATED (2022-01)
364{
365 // implementation as per hostname from net-tools
366 if (full)
367 {
368 char buf[128];
369 ::gethostname(buf, sizeof(buf));
370
371 struct hostent *hp = ::gethostbyname(buf);
372 if (hp)
374 return hp->h_name;
375 }
376 return buf;
377 }
378
379 return Foam::hostName();
380}
381
383// DEPRECATED (2022-01)
385{
386 char buf[128];
387 ::gethostname(buf, sizeof(buf));
388
389 // implementation as per hostname from net-tools
390 struct hostent *hp = ::gethostbyname(buf);
391 if (hp)
392 {
393 char *p = ::strchr(hp->h_name, '.');
394 if (p)
395 {
396 ++p;
397 return p;
398 }
399 }
400
401 return string();
402}
404
406{
407 struct passwd* pw = ::getpwuid(::getuid());
408 if (pw != nullptr)
409 {
410 return pw->pw_name;
411 }
412
413 return string();
414}
415
416
418{
419 return (::geteuid() == 0);
420}
421
422
425 char* env = ::getenv("HOME");
426 if (env)
427 {
428 return fileName(env);
429 }
430
431 struct passwd* pw = ::getpwuid(::getuid());
432 if (pw)
433 {
434 return pw->pw_dir;
435 }
437 return fileName();
438}
439
440
441Foam::fileName Foam::home(const std::string& userName)
443 // An empty userName => same as home()
444 if (userName.empty())
445 {
446 return Foam::home();
447 }
448
449 struct passwd* pw = ::getpwnam(userName.c_str());
450 if (pw)
451 {
452 return pw->pw_dir;
453 }
454
455 return fileName();
456}
457
458
459namespace Foam
461
462//- The physical current working directory path name (pwd -P).
463static Foam::fileName cwd_P()
464{
465 label pathLengthLimit = POSIX::pathLengthChunk;
466 List<char> path(pathLengthLimit);
467
468 // Resize path if getcwd fails with an ERANGE error
469 while (pathLengthLimit == path.size())
470 {
471 if (::getcwd(path.data(), path.size()))
472 {
473 return path.data();
474 }
475 else if (errno == ERANGE)
476 {
477 // Increment path length up to the pathLengthMax limit
478 if
479 (
480 (pathLengthLimit += POSIX::pathLengthChunk)
482 )
483 {
485 << "Attempt to increase path length beyond limit of "
487 << exit(FatalError);
488 }
489
490 path.resize(pathLengthLimit);
491 }
492 else
493 {
494 break;
495 }
496 }
497
499 << "Couldn't get the current working directory"
500 << exit(FatalError);
501
502 return fileName();
503}
504
505
506//- The logical current working directory path name.
507// From the PWD environment, same as pwd -L.
508static Foam::fileName cwd_L()
509{
510 const char* env = ::getenv("PWD");
511
512 // Basic check
513 if (!env || env[0] != '/')
514 {
516 << "PWD is invalid - reverting to physical description"
517 << nl;
518
519 return cwd_P();
520 }
521
522 fileName dir(env);
523
524 // Check for "/."
525 for
526 (
527 std::string::size_type pos = 0;
528 std::string::npos != (pos = dir.find("/.", pos));
529 /*nil*/
530 )
531 {
532 pos += 2;
533
534 if
535 (
536 // Ends in "/." or has "/./"
537 !dir[pos] || dir[pos] == '/'
538
539 // Ends in "/.." or has "/../"
540 || (dir[pos] == '.' && (!dir[pos+1] || dir[pos+1] == '/'))
541 )
542 {
544 << "PWD contains /. or /.. - reverting to physical description"
545 << nl;
546
547 return cwd_P();
548 }
549 }
550
551 // Finally, verify that PWD actually corresponds to the "." directory
552 if (!fileStat(dir, true).sameINode(fileStat(".", true)))
553 {
555 << "PWD is not the cwd() - reverting to physical description"
556 << nl;
557
558 return cwd_P();
559 }
560
561
562 return fileName(dir);
563}
564
565} // End namespace Foam
566
567
569{
570 return cwd(cwdPreference_);
571}
572
573
574Foam::fileName Foam::cwd(bool logical)
575{
576 if (logical)
577 {
578 return cwd_L();
579 }
580
581 return cwd_P();
582}
583
584
585bool Foam::chDir(const fileName& dir)
586{
587 // Ignore an empty dir name => always false
588 return !dir.empty() && ::chdir(dir.c_str()) == 0;
589}
590
591
592bool Foam::mkDir(const fileName& pathName, mode_t mode)
593{
594 if (POSIX::debug)
595 {
596 Pout<< FUNCTION_NAME << " : pathName:" << pathName << " mode:" << mode
597 << endl;
598 if ((POSIX::debug & 2) && !Pstream::master())
599 {
601 }
602 }
603
604 // empty names are meaningless
605 if (pathName.empty())
606 {
607 return false;
608 }
610 // Construct path directory if does not exist
611 if (::mkdir(pathName.c_str(), mode) == 0)
612 {
613 // Directory made OK so return true
614 return true;
615 }
617 switch (errno)
618 {
619 case EPERM:
620 {
622 << "The filesystem containing " << pathName
623 << " does not support the creation of directories."
624 << exit(FatalError);
625 break;
626 }
627
628 case EEXIST:
629 {
630 // Directory already exists so simply return true
631 return true;
632 }
633
634 case EFAULT:
635 {
637 << "" << pathName
638 << " points outside your accessible address space."
639 << exit(FatalError);
640 break;
641 }
642
643 case EACCES:
644 {
646 << "The parent directory does not allow write "
647 "permission to the process,"<< nl
648 << " or one of the directories in " << pathName
649 << " did not allow search (execute) permission."
650 << exit(FatalError);
651 break;
652 }
653
654 case ENAMETOOLONG:
655 {
657 << "" << pathName << " is too long."
658 << exit(FatalError);
659 break;
660 }
661
662 case ENOENT:
663 {
664 // Part of the path does not exist so try to create it
665 if (pathName.path().size() && mkDir(pathName.path(), mode))
666 {
667 return mkDir(pathName, mode);
668 }
669
671 << "Couldn't create directory " << pathName
672 << exit(FatalError);
673 break;
674 }
675
676 case ENOTDIR:
677 {
679 << "A component used as a directory in " << pathName
680 << " is not, in fact, a directory."
681 << exit(FatalError);
682 break;
683 }
684
685 case ENOMEM:
686 {
688 << "Insufficient kernel memory was available to make directory "
689 << pathName << '.'
690 << exit(FatalError);
691 break;
692 }
693
694 case EROFS:
695 {
697 << "" << pathName
698 << " refers to a file on a read-only filesystem."
699 << exit(FatalError);
700 break;
701 }
702
703 case ELOOP:
704 {
706 << "Too many symbolic links were encountered in resolving "
707 << pathName << '.'
708 << exit(FatalError);
709 break;
710 }
711
712 case ENOSPC:
713 {
715 << "The device containing " << pathName
716 << " has no room for the new directory or "
717 << "the user's disk quota is exhausted."
718 << exit(FatalError);
719 break;
720 }
721
722 default:
723 {
725 << "Couldn't create directory " << pathName
726 << exit(FatalError);
727 break;
728 }
729 }
730
731 return false;
732}
733
734
735bool Foam::chMod(const fileName& name, const mode_t m)
736{
737 if (POSIX::debug)
738 {
739 Pout<< FUNCTION_NAME << " : name:" << name << endl;
740 if ((POSIX::debug & 2) && !Pstream::master())
741 {
743 }
744 }
745
746 // Ignore an empty name => always false
747 return !name.empty() && ::chmod(name.c_str(), m) == 0;
748}
749
750
751mode_t Foam::mode(const fileName& name, const bool followLink)
752{
753 if (POSIX::debug)
754 {
755 Pout<< FUNCTION_NAME << " : name:" << name << endl;
756 if ((POSIX::debug & 2) && !Pstream::master())
757 {
760 }
761
762 // Ignore an empty name => always 0
763 if (!name.empty())
764 {
765 fileStat fileStatus(name, followLink);
766 if (fileStatus.good())
767 {
768 return fileStatus.status().st_mode;
769 }
770 }
771
772 return 0;
773}
774
777(
778 const fileName& name,
779 const bool followLink
780)
781{
782 // Ignore an empty name => always UNDEFINED
783 if (name.empty())
784 {
786 }
787
788 if (POSIX::debug)
789 {
790 Pout<< FUNCTION_NAME << " : name:" << name << endl;
791 }
792
793 mode_t m = mode(name, followLink);
794
795 if (S_ISREG(m))
796 {
798 }
799 else if (S_ISLNK(m))
802 }
803 else if (S_ISDIR(m))
804 {
806 }
807
809}
810
811
812bool Foam::exists
813(
814 const fileName& name,
815 const bool checkGzip,
816 const bool followLink
817)
818{
819 if (POSIX::debug)
820 {
821 Pout<< FUNCTION_NAME << " : name:" << name << " checkGzip:" << checkGzip
822 << endl;
823 if ((POSIX::debug & 2) && !Pstream::master())
824 {
826 }
827 }
828
829 // Ignore an empty name => always false
830 return
831 (
832 !name.empty()
833 && (mode(name, followLink) || isFile(name, checkGzip, followLink))
834 );
835}
837
838bool Foam::isDir(const fileName& name, const bool followLink)
839{
840 if (POSIX::debug)
841 {
842 Pout<< FUNCTION_NAME << " : name:" << name << endl;
843 if ((POSIX::debug & 2) && !Pstream::master())
844 {
846 }
847 }
848
849 // Ignore an empty name => always false
850 return !name.empty() && S_ISDIR(mode(name, followLink));
851}
852
853
854bool Foam::isFile
855(
856 const fileName& name,
857 const bool checkGzip,
858 const bool followLink
859)
860{
861 if (POSIX::debug)
863 Pout<< FUNCTION_NAME << " : name:" << name << " checkGzip:" << checkGzip
864 << endl;
865 if ((POSIX::debug & 2) && !Pstream::master())
866 {
868 }
869 }
870
871 // Ignore an empty name => always false
872 return
873 (
874 !name.empty()
875 && (
876 S_ISREG(mode(name, followLink))
877 || (checkGzip && S_ISREG(mode(name + ".gz", followLink)))
879 );
880}
881
882
883off_t Foam::fileSize(const fileName& name, const bool followLink)
884{
885 if (POSIX::debug)
886 {
887 Pout<< FUNCTION_NAME << " : name:" << name << endl;
888 if ((POSIX::debug & 2) && !Pstream::master())
889 {
891 }
892 }
893
894 // Ignore an empty name
895 if (!name.empty())
896 {
897 fileStat fileStatus(name, followLink);
898 if (fileStatus.good())
899 {
900 return fileStatus.status().st_size;
901 }
902 }
903
904 return -1;
905}
906
908time_t Foam::lastModified(const fileName& name, const bool followLink)
909{
910 if (POSIX::debug)
911 {
912 Pout<< FUNCTION_NAME << " : name:" << name << endl;
913 if ((POSIX::debug & 2) && !Pstream::master())
914 {
916 }
917 }
918
919 // Ignore an empty name
920 return name.empty() ? 0 : fileStat(name, followLink).modTime();
921}
922
923
924double Foam::highResLastModified(const fileName& name, const bool followLink)
925{
926 if (POSIX::debug)
927 {
928 Pout<< FUNCTION_NAME << " : name:" << name << endl;
929 if ((POSIX::debug & 2) && !Pstream::master())
930 {
933 }
934
935 // Ignore an empty name
936 return name.empty() ? 0 : fileStat(name, followLink).dmodTime();
937}
938
939
941(
942 const fileName& directory,
943 const fileName::Type type,
944 const bool filtergz,
945 const bool followLink
946)
947{
948 // Initial filename list size and the increment when resizing the list
949 constexpr int maxNnames = 100;
950
951 fileNameList dirEntries;
952
953 // Iterate contents (ignores an empty directory name)
954
955 POSIX::directoryIterator dirIter(directory);
956 if (!dirIter.exists())
957 {
958 if (POSIX::debug)
959 {
961 << "cannot open directory " << directory << endl;
962 }
963
964 return dirEntries;
965 }
966
967 if (POSIX::debug)
968 {
969 // InfoInFunction
970 Pout<< FUNCTION_NAME << " : reading directory " << directory << endl;
971 if ((POSIX::debug & 2) && !Pstream::master())
972 {
974 }
975 }
976
977 label nFailed = 0; // Entries with invalid characters
978 label nEntries = 0; // Number of selected entries
979 dirEntries.resize(maxNnames);
980
981 // Process the directory entries
982 for (/*nil*/; dirIter; ++dirIter)
983 {
984 const std::string& item = *dirIter;
985
986 // Validate filename without spaces, quotes, etc in the name.
987 // No duplicate slashes to strip - dirent will not have them anyhow.
988
990 if (name != item)
991 {
992 ++nFailed;
993 }
994 else if
995 (
998 )
999 {
1000 fileName::Type detected = (directory/name).type(followLink);
1001
1002 if (detected == type)
1003 {
1004 // Only strip '.gz' from non-directory names
1005 if
1006 (
1007 filtergz
1008 && (detected != fileName::Type::DIRECTORY)
1009 && name.has_ext("gz")
1010 )
1011 {
1012 name.remove_ext();
1013 }
1014
1015 if (nEntries >= dirEntries.size())
1016 {
1017 dirEntries.resize(dirEntries.size() + maxNnames);
1018 }
1019
1020 dirEntries[nEntries] = std::move(name);
1021 ++nEntries;
1022 }
1023 }
1024 }
1025
1026 // Finalize the length of the entries list
1027 dirEntries.resize(nEntries);
1028
1029 if (nFailed && POSIX::debug)
1030 {
1031 std::cerr
1032 << "Foam::readDir() : reading directory " << directory << nl
1033 << nFailed << " entries with invalid characters in their name"
1034 << std::endl;
1035 }
1036
1037 return dirEntries;
1038}
1039
1040
1041bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
1042{
1043 if (POSIX::debug)
1044 {
1045 Pout<< FUNCTION_NAME << " : src:" << src << " dest:" << dest << endl;
1046 if ((POSIX::debug & 2) && !Pstream::master())
1047 {
1049 }
1050 }
1051
1052 // Make sure source exists - this also handles an empty source name
1053 if (!exists(src))
1054 {
1055 return false;
1056 }
1057
1058 const fileName::Type srcType = src.type(followLink);
1059
1060 fileName destFile(dest);
1061
1062 // Check type of source file.
1063 if (srcType == fileName::FILE)
1064 {
1065 // If dest is a directory, create the destination file name.
1066 if (destFile.type() == fileName::DIRECTORY)
1067 {
1068 destFile /= src.name();
1069 }
1070
1071 // Make sure the destination directory exists.
1072 if (!isDir(destFile.path()) && !mkDir(destFile.path()))
1073 {
1074 return false;
1075 }
1076
1077 // Open and check streams. Enforce binary for extra safety
1078 std::ifstream srcStream(src, ios_base::in | ios_base::binary);
1079 if (!srcStream)
1080 {
1081 return false;
1082 }
1083
1084 std::ofstream destStream(destFile, ios_base::out | ios_base::binary);
1085 if (!destStream)
1086 {
1087 return false;
1088 }
1089
1090 // Copy character data.
1091 char ch;
1092 while (srcStream.get(ch))
1093 {
1094 destStream.put(ch);
1095 }
1096
1097 // Final check.
1098 if (!srcStream.eof() || !destStream)
1099 {
1100 return false;
1101 }
1102 }
1103 else if (srcType == fileName::SYMLINK)
1104 {
1105 // If dest is a directory, create the destination file name.
1106 if (destFile.type() == fileName::DIRECTORY)
1107 {
1108 destFile /= src.name();
1109 }
1110
1111 // Make sure the destination directory exists.
1112 if (!isDir(destFile.path()) && !mkDir(destFile.path()))
1113 {
1114 return false;
1115 }
1116
1117 Foam::ln(src, destFile);
1118 }
1119 else if (srcType == fileName::DIRECTORY)
1120 {
1121 if (destFile.type() == fileName::DIRECTORY)
1122 {
1123 // Both are directories. Could mean copy contents or copy
1124 // recursively. Don't actually know what the user wants,
1125 // but assume that if names are identical == copy contents.
1126 //
1127 // So: "path1/foo" "path2/foo" copy contents
1128 // So: "path1/foo" "path2/bar" copy directory
1129
1130 const word srcDirName = src.name();
1131 if (destFile.name() != srcDirName)
1132 {
1133 destFile /= srcDirName;
1134 }
1135 }
1136
1137 // Make sure the destination directory exists.
1138 if (!isDir(destFile) && !mkDir(destFile))
1139 {
1140 return false;
1141 }
1142
1143 char* realSrcPath = realpath(src.c_str(), nullptr);
1144 char* realDestPath = realpath(destFile.c_str(), nullptr);
1145 const bool samePath = strcmp(realSrcPath, realDestPath) == 0;
1146
1147 if (POSIX::debug && samePath)
1148 {
1150 << "Attempt to copy " << realSrcPath << " to itself" << endl;
1151 }
1152
1153 if (realSrcPath)
1154 {
1155 free(realSrcPath);
1156 }
1157
1158 if (realDestPath)
1159 {
1160 free(realDestPath);
1161 }
1162
1163 // Do not copy over self when src is actually a link to dest
1164 if (samePath)
1165 {
1166 return false;
1167 }
1168
1169 // Copy files
1170 fileNameList files = readDir(src, fileName::FILE, false, followLink);
1171 for (const fileName& item : files)
1172 {
1173 if (POSIX::debug)
1174 {
1176 << "Copying : " << src/item
1177 << " to " << destFile/item << endl;
1178 }
1179
1180 // File to file.
1181 Foam::cp(src/item, destFile/item, followLink);
1182 }
1183
1184 // Copy sub directories.
1185 fileNameList dirs = readDir
1186 (
1187 src,
1189 false,
1190 followLink
1191 );
1192
1193 for (const fileName& item : dirs)
1194 {
1195 if (POSIX::debug)
1196 {
1198 << "Copying : " << src/item
1199 << " to " << destFile << endl;
1200 }
1201
1202 // Dir to Dir.
1203 Foam::cp(src/item, destFile, followLink);
1204 }
1205 }
1206 else
1207 {
1208 return false;
1209 }
1210
1211 return true;
1212}
1213
1214
1215bool Foam::ln(const fileName& src, const fileName& dst)
1216{
1217 if (POSIX::debug)
1218 {
1219 //InfoInFunction
1221 << " : Create symlink from : " << src << " to " << dst << endl;
1222 if ((POSIX::debug & 2) && !Pstream::master())
1223 {
1225 }
1226 }
1227
1228 if (src.empty())
1229 {
1231 << "source name is empty: not linking." << endl;
1232 return false;
1233 }
1234
1235 if (dst.empty())
1236 {
1238 << "destination name is empty: not linking." << endl;
1239 return false;
1240 }
1241
1242 if (exists(dst))
1243 {
1245 << "destination " << dst << " already exists. Not linking."
1246 << endl;
1247 return false;
1248 }
1249
1250 if (src.isAbsolute() && !exists(src))
1251 {
1253 << "source " << src << " does not exist." << endl;
1254 return false;
1255 }
1256
1257 if (::symlink(src.c_str(), dst.c_str()) == 0)
1258 {
1259 return true;
1260 }
1261
1263 << "symlink from " << src << " to " << dst << " failed." << endl;
1264 return false;
1265}
1266
1267
1269{
1270 if (POSIX::debug)
1271 {
1272 //InfoInFunction
1274 << " : Returning symlink destination for : " << link << endl;
1275 if ((POSIX::debug & 2) && !Pstream::master())
1276 {
1278 }
1279 }
1280
1281 if (link.empty())
1282 {
1283 // Treat an empty path as a no-op.
1284 return fileName();
1285 }
1286
1287 fileName result;
1288 result.resize(1024); // Should be large enough (mostly relative anyhow)
1289
1290 ssize_t len = ::readlink(link.c_str(), &(result.front()), result.size());
1291 if (len > 0)
1293 result.resize(len);
1294 return result;
1295 }
1296
1297 // Failure: return empty result
1298 return fileName();
1299}
1300
1301
1302bool Foam::mv(const fileName& src, const fileName& dst, const bool followLink)
1303{
1304 if (POSIX::debug)
1305 {
1306 //InfoInFunction
1307 Pout<< FUNCTION_NAME << " : Move : " << src << " to " << dst << endl;
1308 if ((POSIX::debug & 2) && !Pstream::master())
1309 {
1311 }
1312 }
1313
1314 // Ignore empty names => always false
1315 if (src.empty() || dst.empty())
1316 {
1317 return false;
1318 }
1319
1320 if
1321 (
1322 dst.type() == fileName::DIRECTORY
1323 && src.type(followLink) != fileName::DIRECTORY
1324 )
1325 {
1326 const fileName dstName(dst/src.name());
1327
1328 return (0 == std::rename(src.c_str(), dstName.c_str()));
1329 }
1330
1331 return (0 == std::rename(src.c_str(), dst.c_str()));
1332}
1333
1334
1335bool Foam::mvBak(const fileName& src, const std::string& ext)
1336{
1337 if (POSIX::debug)
1338 {
1339 //InfoInFunction
1341 << " : moving : " << src << " to extension " << ext << endl;
1342 if ((POSIX::debug & 2) && !Pstream::master())
1343 {
1345 }
1346 }
1347
1348 // Ignore an empty name or extension => always false
1349 if (src.empty() || ext.empty())
1350 {
1351 return false;
1352 }
1353
1354 if (exists(src, false))
1355 {
1356 constexpr const int maxIndex = 99;
1357 char index[4];
1358
1359 for (int n = 0; n <= maxIndex; ++n)
1360 {
1361 fileName dstName(src + "." + ext);
1362 if (n)
1363 {
1364 ::snprintf(index, 4, "%02d", n);
1365 dstName += index;
1366 }
1367
1368 // avoid overwriting existing files, except for the last
1369 // possible index where we have no choice
1370 if (!exists(dstName, false) || n == maxIndex)
1371 {
1372 return (0 == std::rename(src.c_str(), dstName.c_str()));
1373 }
1374 }
1375 }
1376
1377 // fallthrough: nothing to do
1378 return false;
1379}
1380
1381
1382bool Foam::rm(const fileName& file)
1383{
1384 if (POSIX::debug)
1385 {
1386 //InfoInFunction
1387 Pout<< FUNCTION_NAME << " : Removing : " << file << endl;
1388 if ((POSIX::debug & 2) && !Pstream::master())
1389 {
1391 }
1392 }
1393
1394 // Ignore an empty name => always false
1395 if (file.empty())
1396 {
1397 return false;
1398 }
1399
1400 // If removal of plain file name fails, try with .gz
1401
1402 return
1403 (
1404 0 == ::remove(file.c_str())
1405 || 0 == ::remove((file + ".gz").c_str())
1407}
1408
1409
1410bool Foam::rmDir
1411(
1412 const fileName& directory,
1413 const bool silent,
1414 const bool emptyOnly
1415)
1416{
1417 if (directory.empty())
1418 {
1419 return false;
1420 }
1421
1422 // Iterate contents (ignores an empty directory name)
1423 // Also retain hidden files/dirs for removal
1424
1425 POSIX::directoryIterator dirIter(directory, true);
1426 if (!dirIter.exists())
1427 {
1428 if (!silent && !emptyOnly)
1429 {
1431 << "Cannot open directory " << directory << endl;
1432 }
1433
1434 return false;
1435 }
1436
1437 if (POSIX::debug)
1438 {
1439 //InfoInFunction
1440 Pout<< FUNCTION_NAME << " : removing directory " << directory << endl;
1441 if ((POSIX::debug & 2) && !Pstream::master())
1442 {
1444 }
1445 }
1446
1447 // Process each directory entry, counting any errors encountered
1448 int nErrors = 0;
1449
1450 for (/*nil*/; dirIter; ++dirIter)
1451 {
1452 const std::string& item = *dirIter;
1453
1454 // Allow invalid characters (spaces, quotes, etc),
1455 // otherwise we cannot remove subdirs with these types of names.
1456 // -> const fileName path = directory/name; <-
1457
1458 const fileName path(fileName::concat(directory, item));
1459
1460 fileName::Type detected = path.type(false); // No followLink
1461
1462 if (detected == fileName::Type::DIRECTORY)
1463 {
1464 // Call silently for lower levels
1465 if (!rmDir(path, true, emptyOnly))
1466 {
1467 ++nErrors;
1468 }
1469 }
1470 else if (emptyOnly)
1471 {
1472 // Only remove empty directories (not files)
1473 ++nErrors;
1474
1475 // Check for dead symlinks
1476 if (detected == fileName::Type::SYMLINK)
1477 {
1478 detected = path.type(true); // followLink
1479
1480 if (detected == fileName::Type::UNDEFINED)
1481 {
1482 --nErrors;
1483
1484 if (!rm(path))
1485 {
1486 ++nErrors;
1487 }
1488 }
1489 }
1490 }
1491 else
1492 {
1493 if (!rm(path))
1494 {
1495 ++nErrors;
1496 }
1497 }
1498 }
1499
1500 if (nErrors == 0)
1501 {
1502 // No errors encountered - try to remove the top-level
1503
1504 if (!rm(directory))
1505 {
1506 nErrors = -1; // A top-level error
1507 }
1508 }
1509
1510 if (nErrors && !silent && !emptyOnly)
1511 {
1513 << "Failed to remove directory " << directory << endl;
1514
1515 if (nErrors > 0)
1516 {
1517 Info<< "could not remove " << nErrors << " sub-entries" << endl;
1518 }
1519 }
1520
1521 return (nErrors == 0);
1522}
1523
1524
1525unsigned int Foam::sleep(const unsigned int sec)
1526{
1527 return ::sleep(sec);
1528}
1529
1530
1531void Foam::fdClose(const int fd)
1532{
1533 if (close(fd) != 0)
1534 {
1536 << "close error on " << fd << endl
1537 << abort(FatalError);
1538 }
1539}
1540
1541
1542bool Foam::ping
1543(
1544 const std::string& destName,
1545 const label destPort,
1546 const label timeOut
1547)
1548{
1549 struct hostent *hostPtr;
1550 volatile int sockfd;
1551 struct sockaddr_in destAddr; // will hold the destination addr
1552 u_int addr;
1553
1554 if ((hostPtr = ::gethostbyname(destName.c_str())) == nullptr)
1557 << "gethostbyname error " << h_errno << " for host " << destName
1558 << abort(FatalError);
1559 }
1560
1561 // Get first of the SLL of addresses
1562 addr = (reinterpret_cast<struct in_addr*>(*(hostPtr->h_addr_list)))->s_addr;
1563
1564 // Allocate socket
1565 sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1566 if (sockfd < 0)
1567 {
1569 << "socket error"
1570 << abort(FatalError);
1571 }
1572
1573 // Fill sockaddr_in structure with dest address and port
1574 std::memset(reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
1575 destAddr.sin_family = AF_INET;
1576 destAddr.sin_port = htons(ushort(destPort));
1577 destAddr.sin_addr.s_addr = addr;
1578
1579
1580 timer myTimer(timeOut);
1581
1582 if (timedOut(myTimer))
1583 {
1584 // Setjmp from timer jumps back to here
1585 fdClose(sockfd);
1586 return false;
1587 }
1588
1589 if
1590 (
1591 ::connect
1592 (
1593 sockfd,
1594 reinterpret_cast<struct sockaddr*>(&destAddr),
1595 sizeof(struct sockaddr)
1596 ) != 0
1597 )
1598 {
1599 // Connection refused. Check if network was actually used or not.
1600
1601 int connectErr = errno;
1602
1603 fdClose(sockfd);
1604
1605 if (connectErr == ECONNREFUSED)
1606 {
1607 return true;
1608 }
1609 //perror("connect");
1610
1611 return false;
1612 }
1613
1614 fdClose(sockfd);
1615
1616 return true;
1617}
1618
1619
1620bool Foam::ping(const std::string& host, const label timeOut)
1621{
1622 return ping(host, 222, timeOut) || ping(host, 22, timeOut);
1623}
1624
1625
1626namespace Foam
1627{
1629static int waitpid(const pid_t pid)
1630{
1631 // child status, return code from the exec etc.
1632 int status = 0;
1633
1634 // in parent - blocking wait
1635 // modest treatment of signals (in child)
1636 // treat 'stopped' like exit (suspend/continue)
1637
1638 while (true)
1639 {
1640 pid_t wpid = ::waitpid(pid, &status, WUNTRACED);
1641
1642 if (wpid == -1)
1643 {
1645 << "some error occurred in child"
1646 << exit(FatalError);
1647 break;
1648 }
1649
1650 if (WIFEXITED(status))
1651 {
1652 // child exited, get its return status
1653 return WEXITSTATUS(status);
1654 }
1655
1656 if (WIFSIGNALED(status))
1657 {
1658 // child terminated by some signal
1659 return WTERMSIG(status);
1660 }
1661
1662 if (WIFSTOPPED(status))
1663 {
1664 // child stopped by some signal
1665 return WSTOPSIG(status);
1666 }
1667
1669 << "programming error, status from waitpid() not handled: "
1670 << status
1671 << exit(FatalError);
1672 }
1673
1674 return -1; // should not happen
1675}
1677}
1678
1679
1680int Foam::system(const std::string& command, const bool bg)
1681{
1682 if (command.empty())
1683 {
1684 // Treat an empty command as a successful no-op.
1685 // From 'man sh' POSIX (man sh):
1686 // "If the command_string operand is an empty string,
1687 // sh shall exit with a zero exit status."
1688 return 0;
1689 }
1690
1691 // TBD: vfork is deprecated as of macOS 12.0
1692 const pid_t child_pid = ::vfork(); // NB: vfork, not fork!
1693
1694 if (child_pid == -1)
1695 {
1697 << "vfork() failed for system command " << command
1698 << exit(FatalError);
1699
1700 return -1; // fallback error value
1701 }
1702 else if (child_pid == 0)
1703 {
1704 // In child
1705
1706 // Close or redirect file descriptors
1707 redirects(bg);
1708
1709 // execl uses the current environ
1710 (void) ::execl
1711 (
1712 "/bin/sh", // Path of the shell
1713 "sh", // Command-name (name for the shell)
1714 "-c", // Read commands from command_string operand
1715 command.c_str(), // Command string
1716 reinterpret_cast<char*>(0)
1717 );
1718
1719 // Obviously failed, since exec should not return
1721 << "exec failed: " << command
1722 << exit(FatalError);
1723
1724 return -1; // fallback error value
1725 }
1726
1727
1728 // In parent
1729 // - started as background process, or blocking wait for the child
1730
1731 return (bg ? 0 : waitpid(child_pid));
1732}
1733
1734
1735int Foam::system(const CStringList& command, const bool bg)
1736{
1737 if (command.empty())
1738 {
1739 // Treat an empty command as a successful no-op.
1740 // For consistency with POSIX (man sh) behaviour for (sh -c command),
1741 // which is what is mostly being replicated here.
1742 return 0;
1743 }
1744
1745 // NB: use vfork, not fork!
1746 // vfork behaves more like a thread and avoids copy-on-write problems
1747 // triggered by fork.
1748 // The normal system() command has a fork buried in it that causes
1749 // issues with infiniband and openmpi etc.
1750
1751 // TBD: vfork is deprecated as of macOS 12.0
1752 const pid_t child_pid = ::vfork();
1753
1754 if (child_pid == -1)
1755 {
1757 << "vfork() failed for system command " << command[0]
1758 << exit(FatalError);
1760 return -1; // fallback error value
1761 }
1762 else if (child_pid == 0)
1763 {
1764 // In child
1765
1766 // Close or redirect file descriptors
1767 redirects(bg);
1768
1769 // execvp searches the path, uses the current environ
1770 (void) ::execvp(command[0], command.strings());
1771
1772 // Obviously failed, since exec should not return
1774 << "exec(" << command[0] << ", ...) failed"
1775 << exit(FatalError);
1776
1777 return -1; // fallback error value
1778 }
1779
1780
1781 // In parent
1782 // - started as background process, or blocking wait for the child
1783
1784 return (bg ? 0 : waitpid(child_pid));
1785}
1786
1787
1788int Foam::system(const Foam::UList<Foam::string>& command, const bool bg)
1789{
1790 if (command.empty())
1791 {
1792 // Treat an empty command as a successful no-op.
1793 return 0;
1794 }
1795
1796 // Make a deep copy as C-strings
1797 const CStringList cmd(command);
1798 return Foam::system(cmd, bg);
1799}
1800
1801
1802void* Foam::dlOpen(const fileName& libName, const bool check)
1803{
1804 if (POSIX::debug)
1805 {
1806 std::cout
1807 << "dlopen() of " << libName << std::endl;
1808 }
1809
1810 void* handle = loadLibrary(libName);
1811
1812 if (!handle)
1813 {
1814 fileName libso;
1815
1816 if (!libName.has_path() && !libName.starts_with("lib"))
1817 {
1818 // Try with 'lib' prefix
1819 libso = "lib" + libName;
1820 handle = loadLibrary(libso);
1821
1822 if (POSIX::debug)
1823 {
1824 std::cout
1825 << " dlopen() as " << libso << std::endl;
1827 }
1828 else
1829 {
1830 libso = libName;
1831 }
1832
1833 // With canonical library extension ("so" or "dylib"), which remaps
1834 // "libXX" to "libXX.so" as well as "libXX.so" -> "libXX.dylib"
1835 if (!handle && !libso.has_ext(EXT_SO))
1836 {
1837 libso.replace_ext(EXT_SO);
1838 handle = loadLibrary(libso);
1839
1840 if (POSIX::debug)
1841 {
1842 std::cout
1843 << " dlopen() as " << libso << std::endl;
1844 }
1845 }
1846 }
1847
1848 if (!handle && check)
1849 {
1851 << "dlopen error : " << ::dlerror() << endl;
1852 }
1853
1854 if (POSIX::debug)
1855 {
1856 std::cout
1857 << "dlopen() of " << libName
1858 << " handle " << handle << std::endl;
1859 }
1860
1861 return handle;
1862}
1863
1864
1865void* Foam::dlOpen(const fileName& libName, std::string& errorMsg)
1866{
1867 // Call without emitting error message - we capture that ourselves
1868 void* handle = Foam::dlOpen(libName, false);
1869
1870 if (!handle)
1871 {
1872 // Capture error message
1873 errorMsg = ::dlerror();
1874 }
1875 else
1876 {
1877 // No errors
1878 errorMsg.clear();
1879 }
1880
1881 return handle;
1882}
1883
1884
1885Foam::label Foam::dlOpen
1886(
1887 std::initializer_list<fileName> libNames,
1888 const bool check
1890{
1891 label nLoaded = 0;
1892
1893 for (const fileName& libName : libNames)
1894 {
1895 if (Foam::dlOpen(libName, check))
1896 {
1897 ++nLoaded;
1898 }
1899 }
1900
1901 return nLoaded;
1902}
1903
1904
1905bool Foam::dlClose(void* handle)
1906{
1907 if (POSIX::debug)
1908 {
1909 std::cout
1910 << "dlClose(void*)"
1911 << " : dlclose of handle " << handle << std::endl;
1912 }
1913 return ::dlclose(handle) == 0;
1914}
1915
1916
1917void* Foam::dlSymFind(void* handle, const std::string& symbol, bool required)
1918{
1919 if (!required && (!handle || symbol.empty()))
1920 {
1921 return nullptr;
1922 }
1923
1924 if (POSIX::debug)
1925 {
1926 std::cout
1927 << "dlSymFind(void*, const std::string&, bool)"
1928 << " : dlsym of " << symbol << std::endl;
1930
1931 // Clear any old errors - see manpage dlopen
1932 (void) ::dlerror();
1933
1934 // Get address of symbol
1935 void* fun = ::dlsym(handle, symbol.c_str());
1936
1937 // Any error?
1938 char *err = ::dlerror();
1939
1940 if (err)
1942 if (!required)
1943 {
1944 return nullptr;
1945 }
1946
1948 << "Cannot lookup symbol " << symbol << " : " << err
1949 << endl;
1950 }
1951
1952 return fun;
1953}
1954
1955
1956#ifndef __APPLE__
1957static int collectLibsCallback
1958(
1959 struct dl_phdr_info *info,
1960 size_t size,
1961 void *data
1962)
1963{
1965 reinterpret_cast<Foam::DynamicList<Foam::fileName>*>(data);
1966 ptr->append(info->dlpi_name);
1967 return 0;
1968}
1969#endif
1970
1971
1973{
1975 #ifdef __APPLE__
1976 for (uint32_t i=0; i < _dyld_image_count(); ++i)
1977 {
1978 libs.append(_dyld_get_image_name(i));
1979 }
1980 #else
1981 dl_iterate_phdr(collectLibsCallback, &libs);
1982 #endif
1983
1984 if (POSIX::debug)
1985 {
1986 std::cout
1987 << "dlLoaded()"
1988 << " : determined loaded libraries :" << libs.size() << std::endl;
1989 }
1990 return libs;
1991}
1992
1993
1994// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
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)
Definition POSIX.C:89
static void * loadLibrary(const Foam::fileName &libName)
Definition POSIX.C:111
static int collectLibsCallback(struct dl_phdr_info *info, size_t size, void *data)
Definition POSIX.C:1982
label n
An adapter for copying a list of C++ strings into a list of C-style strings for passing to C code tha...
Definition CStringList.H:68
bool empty() const noexcept
True if the size (ie, argc) is zero.
char ** strings() const noexcept
Return the list of C-strings (ie, argv).
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
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...
Definition List.H:72
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
A simple directory contents iterator.
Definition POSIX.C:165
~directoryIterator()
Destructor.
Definition POSIX.C:213
bool exists() const noexcept
Directory open succeeded.
Definition POSIX.C:224
bool good() const noexcept
Directory pointer is valid.
Definition POSIX.C:232
void close()
Close directory.
Definition POSIX.C:240
directoryIterator(const std::string &dirName, bool allowHidden=false)
Construct for dirName, optionally allowing hidden files/dirs.
Definition POSIX.C:194
const std::string & val() const noexcept
The current item.
Definition POSIX.C:252
bool next()
Read next item, always ignoring "." and ".." entries.
Definition POSIX.C:263
directoryIterator & operator++()
Same as next().
Definition POSIX.C:303
const std::string & operator*() const noexcept
Same as val().
Definition POSIX.C:295
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static void printStack(Ostream &os, int size=-1)
Helper function to print a stack, with optional upper limit.
A class for handling file names.
Definition fileName.H:75
static fileName validate(const std::string &, const bool doClean=true)
Construct fileName without invalid characters, possibly applying other transformations such as changi...
Definition fileName.C:199
fileName & replace_ext(const word &ending)
Remove extension (if any) and append a new one.
Definition fileNameI.H:230
Type
Enumerations to handle directory entry types.
Definition fileName.H:82
@ SYMLINK
A symbolic link.
Definition fileName.H:86
@ UNDEFINED
Undefined type.
Definition fileName.H:83
@ FILE
A regular file.
Definition fileName.H:84
@ DIRECTORY
A directory.
Definition fileName.H:85
Type type(bool followLink=true, bool checkGzip=false) const
Return the directory entry type: UNDEFINED, FILE, DIRECTORY (or SYMLINK).
Definition fileName.C:353
bool has_path() const
True if it contains a '/' character.
Definition fileNameI.H:163
static fileName concat(const std::string &s1, const std::string &s2, const char delim='/')
Join two strings with a path separator ('/' by default).
Definition fileName.C:211
static bool isBackup(const std::string &str)
Return true if string ends with "~", ".bak", ".old", ".save".
Definition fileName.C:279
bool has_ext() const
Various checks for extensions.
Definition stringI.H:43
static std::string path(const std::string &str)
Return directory path name (part before last /).
Definition fileNameI.H:169
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition fileNameI.H:192
static bool isAbsolute(const std::string &str)
Return true if filename starts with a '/' or '\' or (windows-only) with a filesystem-root.
Definition fileNameI.H:129
Wrapper for stat() and lstat() system calls.
Definition fileStat.H:64
const struct stat & status() const noexcept
The raw status.
Definition fileStat.H:146
time_t modTime() const
The modification time in seconds, 0 for an invalid file-stat.
Definition fileStat.C:100
bool good() const noexcept
True if file-stat was successful.
Definition fileStat.H:130
double dmodTime() const
The modification time in seconds (nanosecond resolution), 0 for an invalid file-stat.
Definition fileStat.C:106
A class for handling character strings derived from std::string.
Definition string.H:76
bool starts_with(char c) const
True if string starts with given character (cf. C++20).
Definition string.H:436
Implements a timeout mechanism via sigalarm.
Definition timer.H:83
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
volScalarField & p
#define EXT_SO
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
#define WarningInFunction
Report a warning using Foam::Warning.
#define FUNCTION_NAME
#define InfoInFunction
Report an information message using Foam::Info.
OS-specific functions implemented in POSIX.
Definition POSIX.C:159
constexpr label pathLengthChunk
Definition POSIX.H:52
constexpr label pathLengthMax
Definition POSIX.H:53
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition debug.C:234
Foam::SubStrings split(const std::string &str, const char delim, std::string::size_type pos=0, const bool keepEmpty=false)
Split string into sub-strings at the delimiter character.
Namespace for OpenFOAM.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition POSIX.C:1406
static Foam::fileName cwd_P()
The physical current working directory path name (pwd -P).
Definition POSIX.C:484
fileName readLink(const fileName &link)
Return the contents (target) of a symlink.
Definition POSIX.C:1292
fileName cwd()
The physical or logical current working directory path name.
Definition POSIX.C:592
dimensionedScalar pos(const dimensionedScalar &ds)
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition POSIX.C:341
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable, return true on success.
Definition POSIX.C:358
time_t lastModified(const fileName &name, const bool followLink=true)
Return time of last file modification (normally follows symbolic links).
Definition POSIX.C:932
void fdClose(const int fd)
Close file descriptor.
Definition POSIX.C:1555
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?
Definition POSIX.C:837
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition POSIX.C:1704
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition POSIX.C:616
bool isAdministrator()
Is the current user the administrator (root).
Definition POSIX.C:436
bool dlClose(void *handle)
Close a dlopened library using handle. Return true if successful.
Definition POSIX.C:1929
bool env(const std::string &envName)
Deprecated(2020-05) check for existence of environment variable.
Definition OSspecific.H:96
List< fileName > fileNameList
List of fileName.
messageStream Info
Information stream (stdout output on master, null elsewhere).
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Definition POSIX.C:775
static void check(const int retVal, const char *what)
unsigned int sleep(const unsigned int sec)
Sleep for the specified number of seconds.
Definition POSIX.C:1549
bool chMod(const fileName &name, const mode_t mode)
Set the file/directory mode, return true on success.
Definition POSIX.C:759
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
string userName()
Return the user's login name.
Definition POSIX.C:424
pid_t pgid()
Return the group PID of this process.
Definition POSIX.C:328
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
string hostName()
Return the system's host name, as per hostname(1).
Definition POSIX.C:373
void * dlSymFind(void *handle, const std::string &symbol, bool required=false)
Look for symbol in a dlopened library.
Definition POSIX.C:1941
bool ping(const std::string &destName, const label port, const label timeOut)
Check if machine is up by pinging given port.
Definition POSIX.C:1567
pid_t ppid()
Return the parent PID of this process.
Definition POSIX.C:322
errorManip< error > abort(error &err)
Definition errorManip.H:139
off_t fileSize(const fileName &name, const bool followLink=true)
Return size of file or -1 on failure (normally follows symbolic links).
Definition POSIX.C:907
bool rmDir(const fileName &directory, const bool silent=false, const bool emptyOnly=false)
Remove a directory and its contents recursively,.
Definition POSIX.C:1435
double highResLastModified(const fileName &, const bool followLink=true)
Return time of last file modification.
Definition POSIX.C:948
void * dlOpen(const fileName &libName, const bool check=true)
Open a shared library and return handle to library.
Definition POSIX.C:1826
pid_t pid()
Return the PID of this process.
Definition POSIX.C:316
int infoDetailLevel
Global for selective suppression of Info output.
const direction noexcept
Definition scalarImpl.H:265
bool mvBak(const fileName &src, const std::string &ext="bak")
Rename to a corresponding backup file.
Definition POSIX.C:1359
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition POSIX.C:879
bool cp(const fileName &src, const fileName &dst, const bool followLink=true)
Copy the source to the destination (recursively if necessary).
Definition POSIX.C:1065
fileNameList dlLoaded()
Return all loaded libraries.
Definition POSIX.C:1996
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
static Foam::fileName cwd_L()
The logical current working directory path name.
Definition POSIX.C:532
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
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.
Definition POSIX.C:1326
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
fileName home()
Return home directory path name for the current user.
Definition POSIX.C:442
string domainName()
Deprecated(2022-01) domain name resolution may be unreliable.
Definition POSIX.C:403
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition POSIX.C:1239
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition POSIX.C:862
bool hasEnv(const std::string &envName)
True if environment variable of given name is defined.
Definition POSIX.C:334
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::Type::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
Definition POSIX.C:965
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
bool chDir(const fileName &dir)
Change current directory to the one specified and return true on success.
Definition POSIX.C:609
#define timedOut(x)
Check if timeout has occurred.
Definition timer.H:72
mkDir(pdfPath)