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