POSIX.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  POSIX versions of the functions declared in OSspecific.H
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #ifdef solarisGcc
30  #define _SYS_VNODE_H
31 #endif
32 
33 #include "OSspecific.H"
34 #include "POSIX.H"
35 #include "foamVersion.H"
36 #include "fileName.H"
37 #include "fileStat.H"
38 #include "timer.H"
39 #include "IFstream.H"
40 #include "DynamicList.H"
41 #include "HashSet.H"
42 #include "IOstreams.H"
43 #include "Pstream.H"
44 
45 #include <fstream>
46 #include <cstdlib>
47 #include <cctype>
48 
49 #include <stdio.h>
50 #include <unistd.h>
51 #include <dirent.h>
52 #include <pwd.h>
53 #include <errno.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <sys/socket.h>
57 #include <netdb.h>
58 #include <dlfcn.h>
59 #include <link.h>
60 
61 #include <netinet/in.h>
62 
63 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
64 
65 namespace Foam
66 {
68 }
69 
70 
71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
72 
73 pid_t Foam::pid()
74 {
75  return ::getpid();
76 }
77 
78 
79 pid_t Foam::ppid()
80 {
81  return ::getppid();
82 }
83 
84 
85 pid_t Foam::pgid()
86 {
87  return ::getpgrp();
88 }
89 
90 
91 bool Foam::env(const word& envName)
92 {
93  return ::getenv(envName.c_str()) != nullptr;
94 }
95 
96 
98 {
99  char* env = ::getenv(envName.c_str());
100 
101  if (env)
102  {
103  return string(env);
104  }
105  else
106  {
107  // Return null-constructed string rather than string::null
108  // to avoid cyclic dependencies in the construction of globals
109  return string();
110  }
111 }
112 
113 
115 (
116  const word& envName,
117  const std::string& value,
118  const bool overwrite
119 )
120 {
121  return setenv(envName.c_str(), value.c_str(), overwrite) == 0;
122 }
123 
124 
126 {
127  char buf[128];
128  ::gethostname(buf, sizeof(buf));
129 
130  // Implementation as per hostname from net-tools
131  if (full)
132  {
133  struct hostent *hp = ::gethostbyname(buf);
134  if (hp)
135  {
136  return hp->h_name;
137  }
138  }
139 
140  return buf;
141 }
142 
143 
145 {
146  char buf[128];
147  ::gethostname(buf, sizeof(buf));
148 
149  // Implementation as per hostname from net-tools
150  struct hostent *hp = ::gethostbyname(buf);
151  if (hp)
152  {
153  char *p = ::strchr(hp->h_name, '.');
154  if (p)
155  {
156  ++p;
157  return p;
158  }
159  }
160 
161  return string::null;
162 }
163 
164 
166 {
167  struct passwd* pw = ::getpwuid(::getuid());
168 
169  if (pw != nullptr)
170  {
171  return pw->pw_name;
172  }
173  else
174  {
175  return string::null;
176  }
177 }
178 
179 
181 {
182  return (::geteuid() == 0);
183 }
184 
185 
187 {
188  char* env = ::getenv("HOME");
189 
190  if (env != nullptr)
191  {
192  return fileName(env);
193  }
194  else
195  {
196  struct passwd* pw = ::getpwuid(getuid());
197 
198  if (pw != nullptr)
199  {
200  return pw->pw_dir;
201  }
202  else
203  {
204  return fileName::null;
205  }
206  }
207 }
208 
209 
211 {
212  struct passwd* pw;
213 
214  if (userName.size())
215  {
216  pw = ::getpwnam(userName.c_str());
217  }
218  else
219  {
220  char* env = ::getenv("HOME");
221 
222  if (env != nullptr)
223  {
224  return fileName(env);
225  }
226 
227  pw = ::getpwuid(::getuid());
228  }
229 
230  if (pw != nullptr)
231  {
232  return pw->pw_dir;
233  }
234  else
235  {
236  return fileName::null;
237  }
238 }
239 
240 
242 {
243  label pathLengthLimit = POSIX::pathLengthChunk;
244  List<char> path(pathLengthLimit);
245 
246  // Resize path if getcwd fails with an ERANGE error
247  while(pathLengthLimit == path.size())
248  {
249  if (::getcwd(path.data(), path.size()))
250  {
251  return path.data();
252  }
253  else if(errno == ERANGE)
254  {
255  // Increment path length up to the pathLengthMax limit
256  if
257  (
258  (pathLengthLimit += POSIX::pathLengthChunk)
260  )
261  {
263  << "Attempt to increase path length beyond limit of "
265  << exit(FatalError);
266  }
267 
268  path.setSize(pathLengthLimit);
269  }
270  else
271  {
272  break;
273  }
274  }
275 
277  << "Couldn't get the current working directory"
278  << exit(FatalError);
279 
280  return fileName::null;
281 }
282 
283 
284 bool Foam::chDir(const fileName& dir)
285 {
286  return ::chdir(dir.c_str()) == 0;
287 }
288 
289 
290 bool Foam::mkDir(const fileName& filePath, mode_t mode)
291 {
292  if (POSIX::debug)
293  {
294  Pout<< FUNCTION_NAME << " : filePath:" << filePath << " mode:" << mode
295  << endl;
296  if ((POSIX::debug & 2) && !Pstream::master())
297  {
298  error::printStack(Pout);
299  }
300  }
301 
302  // Empty names are meaningless
303  if (filePath.empty())
304  {
305  return false;
306  }
307 
308  // Construct instance path directory if does not exist
309  if (::mkdir(filePath.c_str(), mode) == 0)
310  {
311  // Directory made OK so return true
312  return true;
313  }
314  else
315  {
316  switch (errno)
317  {
318  case EPERM:
319  {
321  << "The filesystem containing " << filePath
322  << " does not support the creation of directories."
323  << exit(FatalError);
324 
325  return false;
326  }
327 
328  case EEXIST:
329  {
330  // Directory already exists so simply return true
331  return true;
332  }
333 
334  case EFAULT:
335  {
337  << "" << filePath
338  << " points outside your accessible address space."
339  << exit(FatalError);
340 
341  return false;
342  }
343 
344  case EACCES:
345  {
347  << "The parent directory does not allow write "
348  "permission to the process,"<< nl
349  << "or one of the directories in " << filePath
350  << " did not allow search (execute) permission."
351  << exit(FatalError);
352 
353  return false;
354  }
355 
356  case ENAMETOOLONG:
357  {
359  << "" << filePath << " is too long."
360  << exit(FatalError);
361 
362  return false;
363  }
364 
365  case ENOENT:
366  {
367  // Part of the path does not exist so try to create it
368  if (filePath.path().size() && mkDir(filePath.path(), mode))
369  {
370  return mkDir(filePath, mode);
371  }
372  else
373  {
375  << "Couldn't create directory " << filePath
376  << exit(FatalError);
377 
378  return false;
379  }
380  }
381 
382  case ENOTDIR:
383  {
385  << "A component used as a directory in " << filePath
386  << " is not, in fact, a directory."
387  << exit(FatalError);
388 
389  return false;
390  }
391 
392  case ENOMEM:
393  {
395  << "Insufficient kernel memory was available to make "
396  "directory " << filePath << '.'
397  << exit(FatalError);
398 
399  return false;
400  }
401 
402  case EROFS:
403  {
405  << "" << filePath
406  << " refers to a file on a read-only filesystem."
407  << exit(FatalError);
408 
409  return false;
410  }
411 
412  case ELOOP:
413  {
415  << "Too many symbolic links were encountered in resolving "
416  << filePath << '.'
417  << exit(FatalError);
418 
419  return false;
420  }
421 
422  case ENOSPC:
423  {
425  << "The device containing " << filePath
426  << " has no room for the new directory or "
427  << "the user's disk quota is exhausted."
428  << exit(FatalError);
429 
430  return false;
431  }
432 
433  default:
434  {
436  << "Couldn't create directory " << filePath
437  << exit(FatalError);
438 
439  return false;
440  }
441  }
442  }
443 }
444 
445 
446 bool Foam::chMod(const fileName& name, const mode_t m)
447 {
448  if (POSIX::debug)
449  {
450  Pout<< FUNCTION_NAME << " : name:" << name << endl;
451  if ((POSIX::debug & 2) && !Pstream::master())
452  {
453  error::printStack(Pout);
454  }
455  }
456  return ::chmod(name.c_str(), m) == 0;
457 }
458 
459 
461 (
462  const fileName& name,
463  const bool checkVariants,
464  const bool followLink
465 )
466 {
467  if (POSIX::debug)
468  {
469  Pout<< FUNCTION_NAME << " : name:" << name << endl;
470  if ((POSIX::debug & 2) && !Pstream::master())
471  {
472  error::printStack(Pout);
473  }
474  }
475  fileStat fileStatus(name, checkVariants, followLink);
476  if (fileStatus.isValid())
477  {
478  return fileStatus.status().st_mode;
479  }
480  else
481  {
482  return 0;
483  }
484 }
485 
486 
488 (
489  const fileName& name,
490  const bool checkVariants,
491  const bool followLink
492 )
493 {
494  if (POSIX::debug)
495  {
496  Pout<< FUNCTION_NAME << " : name:" << name << endl;
497  }
498  mode_t m = mode(name, checkVariants, followLink);
499 
500  if (S_ISREG(m))
501  {
502  return fileType::file;
503  }
504  else if (S_ISLNK(m))
505  {
506  return fileType::link;
507  }
508  else if (S_ISDIR(m))
509  {
510  return fileType::directory;
511  }
512  else
513  {
514  return fileType::undefined;
515  }
516 }
517 
518 
520 (
521  const fileName& name,
522  const bool checkVariants,
523  const bool followLink
524 )
525 {
526  if (POSIX::debug)
527  {
528  Pout<< FUNCTION_NAME << " : name:" << name << " checkVariants:"
529  << bool(checkVariants) << " followLink:" << followLink << endl;
530  if ((POSIX::debug & 2) && !Pstream::master())
531  {
532  error::printStack(Pout);
533  }
534  }
535  return mode(name, checkVariants, followLink);
536 }
537 
538 
539 bool Foam::isDir(const fileName& name, const bool followLink)
540 {
541  if (POSIX::debug)
542  {
543  Pout<< FUNCTION_NAME << " : name:" << name << " followLink:"
544  << followLink << endl;
545  if ((POSIX::debug & 2) && !Pstream::master())
546  {
547  error::printStack(Pout);
548  }
549  }
550  return S_ISDIR(mode(name, false, followLink));
551 }
552 
553 
555 (
556  const fileName& name,
557  const bool checkVariants,
558  const bool followLink
559 )
560 {
561  if (POSIX::debug)
562  {
563  Pout<< FUNCTION_NAME << " : name:" << name << " checkVariants:"
564  << bool(checkVariants) << " followLink:" << followLink << endl;
565  if ((POSIX::debug & 2) && !Pstream::master())
566  {
567  error::printStack(Pout);
568  }
569  }
570 
571  return S_ISREG(mode(name, checkVariants, followLink));
572 }
573 
574 
576 (
577  const fileName& name,
578  const bool checkVariants,
579  const bool followLink
580 )
581 {
582  if (POSIX::debug)
583  {
584  Pout<< FUNCTION_NAME << " : name:" << name << " checkVariants:"
585  << bool(checkVariants) << " followLink:" << followLink << endl;
586  if ((POSIX::debug & 2) && !Pstream::master())
587  {
588  error::printStack(Pout);
589  }
590  }
591  fileStat fileStatus(name, checkVariants, followLink);
592  if (fileStatus.isValid())
593  {
594  return fileStatus.status().st_size;
595  }
596  else
597  {
598  return -1;
599  }
600 }
601 
602 
604 (
605  const fileName& name,
606  const bool checkVariants,
607  const bool followLink
608 )
609 {
610  if (POSIX::debug)
611  {
612  Pout<< FUNCTION_NAME << " : name:" << name << " checkVariants:"
613  << bool(checkVariants) << " followLink:" << followLink << endl;
614  if ((POSIX::debug & 2) && !Pstream::master())
615  {
616  error::printStack(Pout);
617  }
618  }
619  fileStat fileStatus(name, checkVariants, followLink);
620  if (fileStatus.isValid())
621  {
622  return fileStatus.status().st_mtime;
623  }
624  else
625  {
626  return 0;
627  }
628 }
629 
630 
632 (
633  const fileName& name,
634  const bool checkVariants,
635  const bool followLink
636 )
637 {
638  if (POSIX::debug)
639  {
640  Pout<< FUNCTION_NAME << " : name:" << name << " checkVariants:"
641  << bool(checkVariants) << " followLink:" << followLink << endl;
642  if ((POSIX::debug & 2) && !Pstream::master())
643  {
644  error::printStack(Pout);
645  }
646  }
647  fileStat fileStatus(name, checkVariants, followLink);
648  if (fileStatus.isValid())
649  {
650  return
651  fileStatus.status().st_mtime
652  + 1e-9*fileStatus.status().st_atim.tv_nsec;
653  }
654  else
655  {
656  return 0;
657  }
658 }
659 
660 
662 (
663  const fileName& directory,
664  const fileType type,
665  const bool filterVariants,
666  const bool followLink
667 )
668 {
669  if (POSIX::debug)
670  {
671  Pout<< FUNCTION_NAME << " : reading directory " << directory << endl;
672  if ((POSIX::debug & 2) && !Pstream::master())
673  {
674  error::printStack(Pout);
675  }
676  }
677 
678  // Create empty set of file names
679  HashSet<fileName> dirEntries;
680 
681  // Pointers to the directory entries
682  DIR *source;
683  struct dirent *list;
684 
685  // Attempt to open directory and set the structure pointer
686  if ((source = ::opendir(directory.c_str())) == nullptr)
687  {
688  if (POSIX::debug)
689  {
691  << "cannot open directory " << directory << endl;
692  }
693  }
694  else
695  {
696  // Read and parse all the entries in the directory
697  while ((list = ::readdir(source)) != nullptr)
698  {
699  fileName fName(list->d_name);
700 
701  // Ignore files beginning with ., i.e. '.', '..' and '.*'
702  if (fName.size() && fName[0] != '.')
703  {
704  word fExt = fName.ext();
705 
706  if
707  (
708  (type == fileType::directory)
709  ||
710  (
711  type == fileType::file
712  && fName[fName.size()-1] != '~'
713  && fExt != "bak"
714  && fExt != "BAK"
715  && fExt != "old"
716  && fExt != "save"
717  )
718  )
719  {
720  if ((directory/fName).type(false, followLink) == type)
721  {
722  bool filtered = false;
723 
724  if (filterVariants)
725  {
726  for (label i = 0; i < fileStat::nVariants_; ++ i)
727  {
728  if (fExt == fileStat::variantExts_[i])
729  {
730  dirEntries.insert(fName.lessExt());
731  filtered = true;
732  break;
733  }
734  }
735  }
736 
737  if (!filtered)
738  {
739  dirEntries.insert(fName);
740  }
741  }
742  }
743  }
744  }
745 
746  ::closedir(source);
747  }
748 
749  return dirEntries.toc();
750 }
751 
752 
753 bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
754 {
755  if (POSIX::debug)
756  {
757  Pout<< FUNCTION_NAME << " : src:" << src << " dest:" << dest << endl;
758  if ((POSIX::debug & 2) && !Pstream::master())
759  {
760  error::printStack(Pout);
761  }
762  }
763  // Make sure source exists.
764  if (!exists(src))
765  {
766  return false;
767  }
768 
769  const fileType srcType = src.type(false, followLink);
770 
771  fileName destFile(dest);
772 
773  // Check type of source file.
774  if (srcType == fileType::file)
775  {
776  // If dest is a directory, create the destination file name.
777  if (destFile.type() == fileType::directory)
778  {
779  destFile = destFile/src.name();
780  }
781 
782  // Make sure the destination directory exists.
783  if (!isDir(destFile.path()) && !mkDir(destFile.path()))
784  {
785  return false;
786  }
787 
788  // Open and check streams.
789  std::ifstream srcStream(src.c_str());
790  if (!srcStream)
791  {
792  return false;
793  }
794 
795  std::ofstream destStream(destFile.c_str());
796  if (!destStream)
797  {
798  return false;
799  }
800 
801  // Copy character data.
802  destStream << srcStream.rdbuf();
803 
804  // Final check.
805  if (!destStream)
806  {
807  return false;
808  }
809  }
810  else if (srcType == fileType::link)
811  {
812  // If dest is a directory, create the destination file name.
813  if (destFile.type() == fileType::directory)
814  {
815  destFile = destFile/src.name();
816  }
817 
818  // Make sure the destination directory exists.
819  if (!isDir(destFile.path()) && !mkDir(destFile.path()))
820  {
821  return false;
822  }
823 
824  ln(src, destFile);
825  }
826  else if (srcType == fileType::directory)
827  {
828  // If dest is a directory, create the destination file name.
829  if (destFile.type() == fileType::directory)
830  {
831  destFile = destFile/src.component(src.components().size() -1);
832  }
833 
834  // Make sure the destination directory exists.
835  if (!isDir(destFile) && !mkDir(destFile))
836  {
837  return false;
838  }
839 
840  char* realSrcPath = realpath(src.c_str(), nullptr);
841  char* realDestPath = realpath(destFile.c_str(), nullptr);
842  const bool samePath = strcmp(realSrcPath, realDestPath) == 0;
843 
844  if (POSIX::debug && samePath)
845  {
847  << "Attempt to copy " << realSrcPath << " to itself" << endl;
848  }
849 
850  if (realSrcPath)
851  {
852  free(realSrcPath);
853  }
854 
855  if (realDestPath)
856  {
857  free(realDestPath);
858  }
859 
860  // Do not copy over self when src is actually a link to dest
861  if (samePath)
862  {
863  return false;
864  }
865 
866  // Copy files
867  fileNameList contents = readDir(src, fileType::file, false, followLink);
868  forAll(contents, i)
869  {
870  if (POSIX::debug)
871  {
873  << "Copying : " << src/contents[i]
874  << " to " << destFile/contents[i] << endl;
875  }
876 
877  // File to file.
878  cp(src/contents[i], destFile/contents[i], followLink);
879  }
880 
881  // Copy sub directories.
882  fileNameList subdirs = readDir
883  (
884  src,
885  fileType::directory,
886  false,
887  followLink
888  );
889 
890  forAll(subdirs, i)
891  {
892  if (POSIX::debug)
893  {
895  << "Copying : " << src/subdirs[i]
896  << " to " << destFile << endl;
897  }
898 
899  // Dir to Dir.
900  cp(src/subdirs[i], destFile, followLink);
901  }
902  }
903 
904  return true;
905 }
906 
907 
908 bool Foam::ln(const fileName& src, const fileName& dst)
909 {
910  if (POSIX::debug)
911  {
913  << " : Create softlink from : " << src << " to " << dst << endl;
914  if ((POSIX::debug & 2) && !Pstream::master())
915  {
916  error::printStack(Pout);
917  }
918  }
919 
920  if (exists(dst))
921  {
923  << "destination " << dst << " already exists. Not linking."
924  << endl;
925  return false;
926  }
927 
928  if (src.isAbsolute() && !exists(src))
929  {
931  << "source " << src << " does not exist." << endl;
932  return false;
933  }
934 
935  if (::symlink(src.c_str(), dst.c_str()) == 0)
936  {
937  return true;
938  }
939  else
940  {
942  << "symlink from " << src << " to " << dst << " failed." << endl;
943  return false;
944  }
945 }
946 
947 
948 bool Foam::mv(const fileName& src, const fileName& dst, const bool followLink)
949 {
950  if (POSIX::debug)
951  {
952  Pout<< FUNCTION_NAME << " : Move : " << src << " to " << dst << endl;
953  if ((POSIX::debug & 2) && !Pstream::master())
954  {
955  error::printStack(Pout);
956  }
957  }
958 
959  if
960  (
961  dst.type() == fileType::directory
962  && src.type(false, followLink) != fileType::directory
963  )
964  {
965  const fileName dstName(dst/src.name());
966 
967  return ::rename(src.c_str(), dstName.c_str()) == 0;
968  }
969  else
970  {
971  return ::rename(src.c_str(), dst.c_str()) == 0;
972  }
973 }
974 
975 
976 bool Foam::mvBak(const fileName& src, const std::string& ext)
977 {
978  if (POSIX::debug)
979  {
981  << " : moving : " << src << " to extension " << ext << endl;
982  if ((POSIX::debug & 2) && !Pstream::master())
983  {
984  error::printStack(Pout);
985  }
986  }
987 
988  if (exists(src, false, false))
989  {
990  const int maxIndex = 99;
991  char index[3];
992 
993  for (int n = 0; n <= maxIndex; n++)
994  {
995  fileName dstName(src + "." + ext);
996  if (n)
997  {
998  sprintf(index, "%02d", n);
999  dstName += index;
1000  }
1001 
1002  // Avoid overwriting existing files, except for the last
1003  // possible index where we have no choice
1004  if (!exists(dstName, false, false) || n == maxIndex)
1005  {
1006  return ::rename(src.c_str(), dstName.c_str()) == 0;
1007  }
1008 
1009  }
1010  }
1011 
1012  // Fall-through: nothing to do
1013  return false;
1014 }
1015 
1016 
1017 bool Foam::rm(const fileName& file)
1018 {
1019  if (POSIX::debug)
1020  {
1021  Pout<< FUNCTION_NAME << " : Removing : " << file << endl;
1022  if ((POSIX::debug & 2) && !Pstream::master())
1023  {
1024  error::printStack(Pout);
1025  }
1026  }
1027 
1028  // Try returning plain file name; if not there, try variants
1029  if (remove(file.c_str()) == 0)
1030  {
1031  return true;
1032  }
1033 
1034  for (label i = 0; i < fileStat::nVariants_; ++ i)
1035  {
1036  const fileName fileVar = file + "." + fileStat::variantExts_[i];
1037  if (::remove(string(fileVar).c_str()) == 0)
1038  {
1039  return true;
1040  }
1041  }
1042 
1043  return false;
1044 }
1045 
1046 
1047 bool Foam::rmDir(const fileName& directory)
1048 {
1049  if (POSIX::debug)
1050  {
1051  Pout<< FUNCTION_NAME << " : removing directory " << directory << endl;
1052  if ((POSIX::debug & 2) && !Pstream::master())
1053  {
1054  error::printStack(Pout);
1055  }
1056  }
1057 
1058  // Pointers to the directory entries
1059  DIR *source;
1060  struct dirent *list;
1061 
1062  // Attempt to open directory and set the structure pointer
1063  if ((source = ::opendir(directory.c_str())) == nullptr)
1064  {
1066  << "cannot open directory " << directory << endl;
1067 
1068  return false;
1069  }
1070  else
1071  {
1072  // Read and parse all the entries in the directory
1073  while ((list = ::readdir(source)) != nullptr)
1074  {
1075  fileName fName(list->d_name);
1076 
1077  if (fName != "." && fName != "..")
1078  {
1079  fileName path = directory/fName;
1080 
1081  if (path.type(false, false) == fileType::directory)
1082  {
1083  if (!rmDir(path))
1084  {
1086  << "failed to remove directory " << fName
1087  << " while removing directory " << directory
1088  << endl;
1089 
1090  ::closedir(source);
1091 
1092  return false;
1093  }
1094  }
1095  else
1096  {
1097  if (!rm(path))
1098  {
1100  << "failed to remove file " << fName
1101  << " while removing directory " << directory
1102  << endl;
1103 
1104  ::closedir(source);
1105 
1106  return false;
1107  }
1108  }
1109  }
1110 
1111  }
1112 
1113  if (!rm(directory))
1114  {
1116  << "failed to remove directory " << directory << endl;
1117 
1118  ::closedir(source);
1119 
1120  return false;
1121  }
1122 
1123  ::closedir(source);
1124 
1125  return true;
1126  }
1127 }
1128 
1129 
1130 unsigned int Foam::sleep(const unsigned int s)
1131 {
1132  return ::sleep(s);
1133 }
1134 
1135 
1136 void Foam::fdClose(const int fd)
1137 {
1138  if (close(fd) != 0)
1139  {
1141  << "close error on " << fd << endl
1142  << abort(FatalError);
1143  }
1144 }
1145 
1146 
1148 (
1149  const string& destName,
1150  const label destPort,
1151  const label timeOut
1152 )
1153 {
1154  struct hostent *hostPtr;
1155  volatile int sockfd;
1156  struct sockaddr_in destAddr; // Will hold the destination addr
1157  u_int addr;
1158 
1159  if ((hostPtr = ::gethostbyname(destName.c_str())) == nullptr)
1160  {
1162  << "gethostbyname error " << h_errno << " for host " << destName
1163  << abort(FatalError);
1164  }
1165 
1166  // Get first of the SLL of addresses
1167  addr = (reinterpret_cast<struct in_addr*>(*(hostPtr->h_addr_list)))->s_addr;
1168 
1169  // Allocate socket
1170  sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1171  if (sockfd < 0)
1172  {
1174  << "socket error"
1175  << abort(FatalError);
1176  }
1177 
1178  // Fill sockaddr_in structure with dest address and port
1179  memset(reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
1180  destAddr.sin_family = AF_INET;
1181  destAddr.sin_port = htons(ushort(destPort));
1182  destAddr.sin_addr.s_addr = addr;
1183 
1184 
1185  timer myTimer(timeOut);
1186 
1187  if (timedOut(myTimer))
1188  {
1189  // Setjmp from timer jumps back to here
1190  fdClose(sockfd);
1191  return false;
1192  }
1193 
1194  if
1195  (
1196  ::connect
1197  (
1198  sockfd,
1199  reinterpret_cast<struct sockaddr*>(&destAddr),
1200  sizeof(struct sockaddr)
1201  ) != 0
1202  )
1203  {
1204  // Connection refused. Check if network was actually used or not.
1205 
1206  int connectErr = errno;
1207 
1208  fdClose(sockfd);
1209 
1210  if (connectErr == ECONNREFUSED)
1211  {
1212  return true;
1213  }
1214 
1215  return false;
1216  }
1217 
1218  fdClose(sockfd);
1219 
1220  return true;
1221 }
1222 
1223 
1224 bool Foam::ping(const string& hostname, const label timeOut)
1225 {
1226  return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
1227 }
1228 
1229 
1230 int Foam::system(const std::string& command)
1231 {
1232  return ::system(command.c_str());
1233 }
1234 
1235 
1236 void* Foam::dlOpen(const fileName& lib, const bool check)
1237 {
1238  if (POSIX::debug)
1239  {
1240  std::cout<< "dlOpen(const fileName&)"
1241  << " : dlopen of " << lib << std::endl;
1242  }
1243  void* handle = ::dlopen(lib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
1244 
1245  if (!handle && check)
1246  {
1248  << "dlopen error : " << ::dlerror()
1249  << endl;
1250  }
1251 
1252  if (POSIX::debug)
1253  {
1254  std::cout
1255  << "dlOpen(const fileName&)"
1256  << " : dlopen of " << lib
1257  << " handle " << handle << std::endl;
1258  }
1259 
1260  return handle;
1261 }
1262 
1263 
1264 bool Foam::dlClose(void* handle)
1265 {
1266  if (POSIX::debug)
1267  {
1268  std::cout
1269  << "dlClose(void*)"
1270  << " : dlclose of handle " << handle << std::endl;
1271  }
1272  return ::dlclose(handle) == 0;
1273 }
1274 
1275 
1276 void* Foam::dlSym(void* handle, const std::string& symbol)
1277 {
1278  if (POSIX::debug)
1279  {
1280  std::cout
1281  << "dlSym(void*, const std::string&)"
1282  << " : dlsym of " << symbol << std::endl;
1283  }
1284 
1285  // Clear any old errors - see manpage dlopen
1286  (void) ::dlerror();
1287 
1288  // Get address of symbol
1289  void* fun = ::dlsym(handle, symbol.c_str());
1290 
1291  // Find error (if any)
1292  char *error = ::dlerror();
1293 
1294  if (error)
1295  {
1297  << "Cannot lookup symbol " << symbol << " : " << error
1298  << endl;
1299  }
1300 
1301  return fun;
1302 }
1303 
1304 
1305 bool Foam::dlSymFound(void* handle, const std::string& symbol)
1306 {
1307  if (handle && !symbol.empty())
1308  {
1309  if (POSIX::debug)
1310  {
1311  std::cout
1312  << "dlSymFound(void*, const std::string&)"
1313  << " : dlsym of " << symbol << std::endl;
1314  }
1315 
1316  // Clear any old errors - see manpage dlopen
1317  (void) ::dlerror();
1318 
1319  // Get address of symbol
1320  (void) ::dlsym(handle, symbol.c_str());
1321 
1322  // Symbol can be found if there was no error
1323  return !::dlerror();
1324  }
1325  else
1326  {
1327  return false;
1328  }
1329 }
1330 
1331 
1333 (
1334  struct dl_phdr_info *info,
1335  size_t size,
1336  void *data
1337 )
1338 {
1340  reinterpret_cast<Foam::DynamicList<Foam::fileName>*>(data);
1341  ptr->append(info->dlpi_name);
1342  return 0;
1343 }
1344 
1345 
1347 {
1349  dl_iterate_phdr(collectLibsCallback, &libs);
1350  if (POSIX::debug)
1351  {
1352  std::cout
1353  << "dlLoaded()"
1354  << " : determined loaded libraries :" << libs.size() << std::endl;
1355  }
1356 
1357  return libs;
1358 }
1359 
1360 
1361 // ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
static int collectLibsCallback(struct dl_phdr_info *info, size_t size, void *data)
Definition: POSIX.C:1333
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
A HashTable with keys but without contents.
Definition: HashSet.H:62
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:227
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
T * data()
Return a pointer to the first data element,.
Definition: UListI.H:149
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:71
A class for handling file names.
Definition: fileName.H:82
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:73
wordList components(const char delimiter='/') const
Return path components as wordList.
Definition: fileName.C:314
word name() const
Return file name (part beyond last /)
Definition: fileName.C:195
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:284
fileType type(const bool checkVariants=true, const bool followLink=true) const
Return the file type: file, directory, undefined or.
Definition: fileName.C:52
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:299
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:265
word component(const size_type, const char delimiter='/') const
Return a single component of the path.
Definition: fileName.C:342
Wrapper for stat() system call.
Definition: fileStat.H:66
const struct stat & status() const
Raw status.
Definition: fileStat.H:110
bool isValid() const
Did constructor fail.
Definition: fileStat.H:116
A class for handling character strings derived from std::string.
Definition: string.H:79
Implements a timeout mechanism via sigalarm.
Definition: timer.H:82
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define WarningInFunction
Report a warning using Foam::Warning.
#define FUNCTION_NAME
#define InfoInFunction
Report an information message using Foam::Info.
const label pathLengthMax
Definition: POSIX.H:53
const label pathLengthChunk
Definition: POSIX.H:52
const dimensionedScalar e
Elementary charge.
Namespace for OpenFOAM.
bool isFile(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist as a file in the file system?
Definition: POSIX.C:555
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dlLibraryTable libs
Table of loaded dynamic libraries.
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:241
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1230
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
off_t fileSize(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return size of file.
Definition: POSIX.C:576
bool mvBak(const fileName &, const std::string &ext="bak")
Rename to a corresponding backup file.
Definition: POSIX.C:976
mode_t mode(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file mode.
Definition: POSIX.C:461
bool env(const word &)
Return true if environment variable of given name is defined.
Definition: POSIX.C:91
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
bool rm(const fileName &)
Remove a file, returning true if successful otherwise false.
Definition: POSIX.C:1017
bool dlSymFound(void *handle, const std::string &symbol)
Report if symbol in a dlopened library could be found.
Definition: POSIX.C:1305
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
bool isAdministrator()
Is user administrator.
Definition: POSIX.C:180
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
void * dlOpen(const fileName &lib, const bool check=true)
Open a shared library. Return handle to library. Print error message.
Definition: POSIX.C:1236
double highResLastModified(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return time of last file modification.
Definition: POSIX.C:632
bool dlClose(void *)
Close a dlopened library using handle. Return true if successful.
Definition: POSIX.C:1264
errorManip< error > abort(error &err)
Definition: errorManip.H:131
bool exists(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist (as directory or file) in the file system?
Definition: POSIX.C:520
void fdClose(const int)
Close file descriptor.
Definition: POSIX.C:1136
string userName()
Return the user's login name.
Definition: POSIX.C:165
pid_t pgid()
Return the group PID of this process.
Definition: POSIX.C:85
string hostName(const bool full=false)
Return the system's host name, as per hostname(1)
Definition: POSIX.C:125
bool chMod(const fileName &, const mode_t)
Set the file mode.
Definition: POSIX.C:446
bool rmDir(const fileName &)
Remove a directory and its contents.
Definition: POSIX.C:1047
defineTypeNameAndDebug(combustionModel, 0)
pid_t ppid()
Return the parent PID of this process.
Definition: POSIX.C:79
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a directory in the file system?
Definition: POSIX.C:539
bool ping(const string &, const label port, const label timeOut)
Check if machine is up by pinging given port.
Definition: POSIX.C:1148
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
time_t lastModified(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return time of last file modification.
Definition: POSIX.C:604
pid_t pid()
Return the PID of this process.
Definition: POSIX.C:73
fileType
Enumeration of file types.
Definition: fileName.H:67
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
void * dlSym(void *handle, const std::string &symbol)
Lookup a symbol in a dlopened library using handle to library.
Definition: POSIX.C:1276
bool cp(const fileName &src, const fileName &dst, const bool followLink=true)
Copy, recursively if necessary, the source to the destination.
Definition: POSIX.C:753
fileNameList dlLoaded()
Return all loaded libraries.
Definition: POSIX.C:1346
error FatalError
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition: POSIX.C:948
fileName home()
Return home directory path name for the current user.
Definition: POSIX.C:186
unsigned int sleep(const unsigned int)
Sleep for the specified number of seconds.
Definition: POSIX.C:1130
static const char nl
Definition: Ostream.H:266
fileNameList readDir(const fileName &, const fileType=fileType::file, const bool filterVariants=true, const bool followLink=true)
Read a directory and return the entries as a string list.
Definition: POSIX.C:662
string domainName()
Return the system's domain name, as per hostname(1) with the '-d' option.
Definition: POSIX.C:144
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition: POSIX.C:908
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
bool chDir(const fileName &dir)
Change the current directory to the one given and return true,.
Definition: POSIX.C:284
volScalarField & p
#define timedOut(x)
Check it a timeout has occurred.
Definition: timer.H:71
mkDir(pdfPath)