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