All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-2021 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 {
67  defineTypeNameAndDebug(POSIX, 0);
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 
114 bool Foam::setEnv
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  {
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  {
454  }
455  }
456  return ::chmod(name.c_str(), m) == 0;
457 }
458 
459 
460 mode_t Foam::mode
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  {
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 
519 bool Foam::exists
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  {
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  {
548  }
549  }
550  return S_ISDIR(mode(name, false, followLink));
551 }
552 
553 
554 bool Foam::isFile
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  {
568  }
569  }
570 
571  return S_ISREG(mode(name, checkVariants, followLink));
572 }
573 
574 
575 off_t Foam::fileSize
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  {
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 
603 time_t Foam::lastModified
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  {
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  {
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  {
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  {
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 (!srcStream.eof() || !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,
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  {
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  {
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  {
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  {
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  {
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 
1147 bool Foam::ping
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 
1332 static int collectLibsCallback
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 move(libs);
1358 }
1359 
1360 
1361 // ************************************************************************* //
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
static void printStack(Ostream &)
Helper function to print a stack.
A HashTable with keys but without contents.
Definition: HashSet.H:59
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
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
mode_t mode(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file mode.
Definition: POSIX.C:461
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 mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition: POSIX.C:948
A class for handling file names.
Definition: fileName.H:79
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const label nVariants_
Number of file variants.
Definition: fileStat.H:79
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:323
const label pathLengthMax
Definition: POSIX.H:53
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
pid_t ppid()
Return the parent PID of this process.
Definition: POSIX.C:79
Implements a timeout mechanism via sigalarm.
Definition: timer.H:81
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
static const fileName null
An empty fileName.
Definition: fileName.H:97
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
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
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
bool chDir(const fileName &dir)
Change the current directory to the one given and return true,.
Definition: POSIX.C:284
bool ping(const string &, const label port, const label timeOut)
Check if machine is up by pinging given port.
Definition: POSIX.C:1148
fileNameList dlLoaded()
Return all loaded libraries.
Definition: POSIX.C:1346
const label pathLengthChunk
Definition: POSIX.H:52
fileName home()
Return home directory path name for the current user.
Definition: POSIX.C:186
static int collectLibsCallback(struct dl_phdr_info *info, size_t size, void *data)
Definition: POSIX.C:1333
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:111
bool mvBak(const fileName &, const std::string &ext="bak")
Rename to a corresponding backup file.
Definition: POSIX.C:976
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:299
dlLibraryTable libs
Table of loaded dynamic libraries.
wordList components(const char delimiter='/') const
Return path components as wordList.
Definition: fileName.C:314
const struct stat & status() const
Raw status.
Definition: fileStat.H:110
fileType type(const bool checkVariants=true, const bool followLink=true) const
Return the file type: file, directory, undefined or.
Definition: fileName.C:52
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:66
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
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.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
string hostName(const bool full=false)
Return the system&#39;s host name, as per hostname(1)
Definition: POSIX.C:125
bool dlClose(void *)
Close a dlopened library using handle. Return true if successful.
Definition: POSIX.C:1264
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:73
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a directory in the file system?
Definition: POSIX.C:539
A class for handling words, derived from string.
Definition: word.H:59
string domainName()
Return the system&#39;s domain name, as per hostname(1) with the &#39;-d&#39; option.
Definition: POSIX.C:144
word name() const
Return file name (part beyond last /)
Definition: fileName.C:195
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
string userName()
Return the user&#39;s login name.
Definition: POSIX.C:165
fileType
Enumeration of file types.
Definition: fileName.H:66
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
errorManip< error > abort(error &err)
Definition: errorManip.H:131
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition: POSIX.C:908
word component(const size_type, const char delimiter='/') const
Return a single component of the path.
Definition: fileName.C:342
static const string null
An empty string.
Definition: string.H:88
bool rmDir(const fileName &)
Remove a directory and its contents.
Definition: POSIX.C:1047
pid_t pid()
Return the PID of this process.
Definition: POSIX.C:73
static const char nl
Definition: Ostream.H:260
#define FUNCTION_NAME
defineTypeNameAndDebug(combustionModel, 0)
Wrapper for stat() system call.
Definition: fileStat.H:65
#define timedOut(x)
Check it a timeout has occurred.
Definition: timer.H:71
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
pid_t pgid()
Return the group PID of this process.
Definition: POSIX.C:85
bool isAdministrator()
Is user administrator.
Definition: POSIX.C:180
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
double highResLastModified(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return time of last file modification.
Definition: POSIX.C:632
fvModels source(alpha1, mixture.thermo1().rho())
#define WarningInFunction
Report a warning using Foam::Warning.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
bool chMod(const fileName &, const mode_t)
Set the file mode.
Definition: POSIX.C:446
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:284
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:241
void fdClose(const int)
Close file descriptor.
Definition: POSIX.C:1136
static const char * variantExts_[]
Extensions of the file variants.
Definition: fileStat.H:82
label n
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:265
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:105
off_t fileSize(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return size of file.
Definition: POSIX.C:576
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:202
bool env(const word &)
Return true if environment variable of given name is defined.
Definition: POSIX.C:91
volScalarField & p
bool rm(const fileName &)
Remove a file, returning true if successful otherwise false.
Definition: POSIX.C:1017
A class for handling character strings derived from std::string.
Definition: string.H:76
unsigned int sleep(const unsigned int)
Sleep for the specified number of seconds.
Definition: POSIX.C:1130
void * dlOpen(const fileName &lib, const bool check=true)
Open a shared library. Return handle to library. Print error message.
Definition: POSIX.C:1236
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
void * dlSym(void *handle, const std::string &symbol)
Lookup a symbol in a dlopened library using handle to library.
Definition: POSIX.C:1276
bool dlSymFound(void *handle, const std::string &symbol)
Report if symbol in a dlopened library could be found.
Definition: POSIX.C:1305
bool isValid() const
Did constructor fail.
Definition: fileStat.H:116
Namespace for OpenFOAM.
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1230
fileName path(UMean.rootPath()/UMean.caseName()/functionObjects::writeFile::outputPrefix/"graphs"/UMean.instance())
#define InfoInFunction
Report an information message using Foam::Info.