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-2019 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& pathName, mode_t mode)
291 {
292  if (POSIX::debug)
293  {
294  Pout<< FUNCTION_NAME << " : pathName:" << pathName << " mode:" << mode
295  << endl;
296  if ((POSIX::debug & 2) && !Pstream::master())
297  {
299  }
300  }
301 
302  // Empty names are meaningless
303  if (pathName.empty())
304  {
305  return false;
306  }
307 
308  // Construct instance path directory if does not exist
309  if (::mkdir(pathName.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 " << pathName
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  << "" << pathName
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 " << pathName
350  << " did not allow search (execute) permission."
351  << exit(FatalError);
352 
353  return false;
354  }
355 
356  case ENAMETOOLONG:
357  {
359  << "" << pathName << " 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 (pathName.path().size() && mkDir(pathName.path(), mode))
369  {
370  return mkDir(pathName, mode);
371  }
372  else
373  {
375  << "Couldn't create directory " << pathName
376  << exit(FatalError);
377 
378  return false;
379  }
380  }
381 
382  case ENOTDIR:
383  {
385  << "A component used as a directory in " << pathName
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 " << pathName << '.'
397  << exit(FatalError);
398 
399  return false;
400  }
401 
402  case EROFS:
403  {
405  << "" << pathName
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  << pathName << '.'
417  << exit(FatalError);
418 
419  return false;
420  }
421 
422  case ENOSPC:
423  {
425  << "The device containing " << pathName
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 " << pathName
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  char ch;
803  while (srcStream.get(ch))
804  {
805  destStream.put(ch);
806  }
807 
808  // Final check.
809  if (!srcStream.eof() || !destStream)
810  {
811  return false;
812  }
813  }
814  else if (srcType == fileType::link)
815  {
816  // If dest is a directory, create the destination file name.
817  if (destFile.type() == fileType::directory)
818  {
819  destFile = destFile/src.name();
820  }
821 
822  // Make sure the destination directory exists.
823  if (!isDir(destFile.path()) && !mkDir(destFile.path()))
824  {
825  return false;
826  }
827 
828  ln(src, destFile);
829  }
830  else if (srcType == fileType::directory)
831  {
832  // If dest is a directory, create the destination file name.
833  if (destFile.type() == fileType::directory)
834  {
835  destFile = destFile/src.component(src.components().size() -1);
836  }
837 
838  // Make sure the destination directory exists.
839  if (!isDir(destFile) && !mkDir(destFile))
840  {
841  return false;
842  }
843 
844  char* realSrcPath = realpath(src.c_str(), nullptr);
845  char* realDestPath = realpath(destFile.c_str(), nullptr);
846  const bool samePath = strcmp(realSrcPath, realDestPath) == 0;
847 
848  if (POSIX::debug && samePath)
849  {
851  << "Attempt to copy " << realSrcPath << " to itself" << endl;
852  }
853 
854  if (realSrcPath)
855  {
856  free(realSrcPath);
857  }
858 
859  if (realDestPath)
860  {
861  free(realDestPath);
862  }
863 
864  // Do not copy over self when src is actually a link to dest
865  if (samePath)
866  {
867  return false;
868  }
869 
870  // Copy files
871  fileNameList contents = readDir(src, fileType::file, false, followLink);
872  forAll(contents, i)
873  {
874  if (POSIX::debug)
875  {
877  << "Copying : " << src/contents[i]
878  << " to " << destFile/contents[i] << endl;
879  }
880 
881  // File to file.
882  cp(src/contents[i], destFile/contents[i], followLink);
883  }
884 
885  // Copy sub directories.
886  fileNameList subdirs = readDir
887  (
888  src,
890  false,
891  followLink
892  );
893 
894  forAll(subdirs, i)
895  {
896  if (POSIX::debug)
897  {
899  << "Copying : " << src/subdirs[i]
900  << " to " << destFile << endl;
901  }
902 
903  // Dir to Dir.
904  cp(src/subdirs[i], destFile, followLink);
905  }
906  }
907 
908  return true;
909 }
910 
911 
912 bool Foam::ln(const fileName& src, const fileName& dst)
913 {
914  if (POSIX::debug)
915  {
917  << " : Create softlink from : " << src << " to " << dst << endl;
918  if ((POSIX::debug & 2) && !Pstream::master())
919  {
921  }
922  }
923 
924  if (exists(dst))
925  {
927  << "destination " << dst << " already exists. Not linking."
928  << endl;
929  return false;
930  }
931 
932  if (src.isAbsolute() && !exists(src))
933  {
935  << "source " << src << " does not exist." << endl;
936  return false;
937  }
938 
939  if (::symlink(src.c_str(), dst.c_str()) == 0)
940  {
941  return true;
942  }
943  else
944  {
946  << "symlink from " << src << " to " << dst << " failed." << endl;
947  return false;
948  }
949 }
950 
951 
952 bool Foam::mv(const fileName& src, const fileName& dst, const bool followLink)
953 {
954  if (POSIX::debug)
955  {
956  Pout<< FUNCTION_NAME << " : Move : " << src << " to " << dst << endl;
957  if ((POSIX::debug & 2) && !Pstream::master())
958  {
960  }
961  }
962 
963  if
964  (
965  dst.type() == fileType::directory
966  && src.type(false, followLink) != fileType::directory
967  )
968  {
969  const fileName dstName(dst/src.name());
970 
971  return ::rename(src.c_str(), dstName.c_str()) == 0;
972  }
973  else
974  {
975  return ::rename(src.c_str(), dst.c_str()) == 0;
976  }
977 }
978 
979 
980 bool Foam::mvBak(const fileName& src, const std::string& ext)
981 {
982  if (POSIX::debug)
983  {
985  << " : moving : " << src << " to extension " << ext << endl;
986  if ((POSIX::debug & 2) && !Pstream::master())
987  {
989  }
990  }
991 
992  if (exists(src, false, false))
993  {
994  const int maxIndex = 99;
995  char index[3];
996 
997  for (int n = 0; n <= maxIndex; n++)
998  {
999  fileName dstName(src + "." + ext);
1000  if (n)
1001  {
1002  sprintf(index, "%02d", n);
1003  dstName += index;
1004  }
1005 
1006  // Avoid overwriting existing files, except for the last
1007  // possible index where we have no choice
1008  if (!exists(dstName, false, false) || n == maxIndex)
1009  {
1010  return ::rename(src.c_str(), dstName.c_str()) == 0;
1011  }
1012 
1013  }
1014  }
1015 
1016  // Fall-through: nothing to do
1017  return false;
1018 }
1019 
1020 
1021 bool Foam::rm(const fileName& file)
1022 {
1023  if (POSIX::debug)
1024  {
1025  Pout<< FUNCTION_NAME << " : Removing : " << file << endl;
1026  if ((POSIX::debug & 2) && !Pstream::master())
1027  {
1029  }
1030  }
1031 
1032  // Try returning plain file name; if not there, try variants
1033  if (remove(file.c_str()) == 0)
1034  {
1035  return true;
1036  }
1037 
1038  for (label i = 0; i < fileStat::nVariants_; ++ i)
1039  {
1040  const fileName fileVar = file + "." + fileStat::variantExts_[i];
1041  if (::remove(string(fileVar).c_str()) == 0)
1042  {
1043  return true;
1044  }
1045  }
1046 
1047  return false;
1048 }
1049 
1050 
1051 bool Foam::rmDir(const fileName& directory)
1052 {
1053  if (POSIX::debug)
1054  {
1055  Pout<< FUNCTION_NAME << " : removing directory " << directory << endl;
1056  if ((POSIX::debug & 2) && !Pstream::master())
1057  {
1059  }
1060  }
1061 
1062  // Pointers to the directory entries
1063  DIR *source;
1064  struct dirent *list;
1065 
1066  // Attempt to open directory and set the structure pointer
1067  if ((source = ::opendir(directory.c_str())) == nullptr)
1068  {
1070  << "cannot open directory " << directory << endl;
1071 
1072  return false;
1073  }
1074  else
1075  {
1076  // Read and parse all the entries in the directory
1077  while ((list = ::readdir(source)) != nullptr)
1078  {
1079  fileName fName(list->d_name);
1080 
1081  if (fName != "." && fName != "..")
1082  {
1083  fileName path = directory/fName;
1084 
1085  if (path.type(false, false) == fileType::directory)
1086  {
1087  if (!rmDir(path))
1088  {
1090  << "failed to remove directory " << fName
1091  << " while removing directory " << directory
1092  << endl;
1093 
1094  ::closedir(source);
1095 
1096  return false;
1097  }
1098  }
1099  else
1100  {
1101  if (!rm(path))
1102  {
1104  << "failed to remove file " << fName
1105  << " while removing directory " << directory
1106  << endl;
1107 
1108  ::closedir(source);
1109 
1110  return false;
1111  }
1112  }
1113  }
1114 
1115  }
1116 
1117  if (!rm(directory))
1118  {
1120  << "failed to remove directory " << directory << endl;
1121 
1122  ::closedir(source);
1123 
1124  return false;
1125  }
1126 
1127  ::closedir(source);
1128 
1129  return true;
1130  }
1131 }
1132 
1133 
1134 unsigned int Foam::sleep(const unsigned int s)
1135 {
1136  return ::sleep(s);
1137 }
1138 
1139 
1140 void Foam::fdClose(const int fd)
1141 {
1142  if (close(fd) != 0)
1143  {
1145  << "close error on " << fd << endl
1146  << abort(FatalError);
1147  }
1148 }
1149 
1150 
1151 bool Foam::ping
1153  const string& destName,
1154  const label destPort,
1155  const label timeOut
1156 )
1157 {
1158  struct hostent *hostPtr;
1159  volatile int sockfd;
1160  struct sockaddr_in destAddr; // Will hold the destination addr
1161  u_int addr;
1162 
1163  if ((hostPtr = ::gethostbyname(destName.c_str())) == nullptr)
1164  {
1166  << "gethostbyname error " << h_errno << " for host " << destName
1167  << abort(FatalError);
1168  }
1169 
1170  // Get first of the SLL of addresses
1171  addr = (reinterpret_cast<struct in_addr*>(*(hostPtr->h_addr_list)))->s_addr;
1172 
1173  // Allocate socket
1174  sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1175  if (sockfd < 0)
1176  {
1178  << "socket error"
1179  << abort(FatalError);
1180  }
1181 
1182  // Fill sockaddr_in structure with dest address and port
1183  memset(reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
1184  destAddr.sin_family = AF_INET;
1185  destAddr.sin_port = htons(ushort(destPort));
1186  destAddr.sin_addr.s_addr = addr;
1187 
1188 
1189  timer myTimer(timeOut);
1190 
1191  if (timedOut(myTimer))
1192  {
1193  // Setjmp from timer jumps back to here
1194  fdClose(sockfd);
1195  return false;
1196  }
1197 
1198  if
1199  (
1200  ::connect
1201  (
1202  sockfd,
1203  reinterpret_cast<struct sockaddr*>(&destAddr),
1204  sizeof(struct sockaddr)
1205  ) != 0
1206  )
1207  {
1208  // Connection refused. Check if network was actually used or not.
1209 
1210  int connectErr = errno;
1211 
1212  fdClose(sockfd);
1213 
1214  if (connectErr == ECONNREFUSED)
1215  {
1216  return true;
1217  }
1218 
1219  return false;
1220  }
1221 
1222  fdClose(sockfd);
1223 
1224  return true;
1225 }
1226 
1227 
1228 bool Foam::ping(const string& hostname, const label timeOut)
1229 {
1230  return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
1231 }
1232 
1233 
1234 int Foam::system(const std::string& command)
1235 {
1236  return ::system(command.c_str());
1237 }
1238 
1239 
1240 void* Foam::dlOpen(const fileName& lib, const bool check)
1241 {
1242  if (POSIX::debug)
1243  {
1244  std::cout<< "dlOpen(const fileName&)"
1245  << " : dlopen of " << lib << std::endl;
1246  }
1247  void* handle = ::dlopen(lib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
1248 
1249  if (!handle && check)
1250  {
1252  << "dlopen error : " << ::dlerror()
1253  << endl;
1254  }
1255 
1256  if (POSIX::debug)
1257  {
1258  std::cout
1259  << "dlOpen(const fileName&)"
1260  << " : dlopen of " << lib
1261  << " handle " << handle << std::endl;
1262  }
1263 
1264  return handle;
1265 }
1266 
1267 
1268 bool Foam::dlClose(void* handle)
1269 {
1270  if (POSIX::debug)
1271  {
1272  std::cout
1273  << "dlClose(void*)"
1274  << " : dlclose of handle " << handle << std::endl;
1275  }
1276  return ::dlclose(handle) == 0;
1277 }
1278 
1279 
1280 void* Foam::dlSym(void* handle, const std::string& symbol)
1281 {
1282  if (POSIX::debug)
1283  {
1284  std::cout
1285  << "dlSym(void*, const std::string&)"
1286  << " : dlsym of " << symbol << std::endl;
1287  }
1288 
1289  // Clear any old errors - see manpage dlopen
1290  (void) ::dlerror();
1291 
1292  // Get address of symbol
1293  void* fun = ::dlsym(handle, symbol.c_str());
1294 
1295  // Find error (if any)
1296  char *error = ::dlerror();
1297 
1298  if (error)
1299  {
1301  << "Cannot lookup symbol " << symbol << " : " << error
1302  << endl;
1303  }
1304 
1305  return fun;
1306 }
1307 
1308 
1309 bool Foam::dlSymFound(void* handle, const std::string& symbol)
1310 {
1311  if (handle && !symbol.empty())
1312  {
1313  if (POSIX::debug)
1314  {
1315  std::cout
1316  << "dlSymFound(void*, const std::string&)"
1317  << " : dlsym of " << symbol << std::endl;
1318  }
1319 
1320  // Clear any old errors - see manpage dlopen
1321  (void) ::dlerror();
1322 
1323  // Get address of symbol
1324  (void) ::dlsym(handle, symbol.c_str());
1325 
1326  // Symbol can be found if there was no error
1327  return !::dlerror();
1328  }
1329  else
1330  {
1331  return false;
1332  }
1333 }
1334 
1335 
1336 static int collectLibsCallback
1338  struct dl_phdr_info *info,
1339  size_t size,
1340  void *data
1341 )
1342 {
1344  reinterpret_cast<Foam::DynamicList<Foam::fileName>*>(data);
1345  ptr->append(info->dlpi_name);
1346  return 0;
1347 }
1348 
1349 
1351 {
1352  DynamicList<fileName> libs;
1353  dl_iterate_phdr(collectLibsCallback, &libs);
1354  if (POSIX::debug)
1355  {
1356  std::cout
1357  << "dlLoaded()"
1358  << " : determined loaded libraries :" << libs.size() << std::endl;
1359  }
1360 
1361  return move(libs);
1362 }
1363 
1364 
1365 // ************************************************************************* //
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:952
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:319
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:163
static const fileName null
An empty fileName.
Definition: fileName.H:97
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
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:1152
fileNameList dlLoaded()
Return all loaded libraries.
Definition: POSIX.C:1350
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:1337
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:108
bool mvBak(const fileName &, const std::string &ext="bak")
Rename to a corresponding backup file.
Definition: POSIX.C:980
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:287
wordList components(const char delimiter='/') const
Return path components as wordList.
Definition: fileName.C:302
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:1268
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:61
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:183
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:912
word component(const size_type, const char delimiter='/') const
Return a single component of the path.
Definition: fileName.C:330
static const string null
An empty string.
Definition: string.H:86
bool rmDir(const fileName &)
Remove a directory and its contents.
Definition: POSIX.C:1051
pid_t pid()
Return the PID of this process.
Definition: POSIX.C:73
static const char nl
Definition: Ostream.H:265
#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
#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:272
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:241
void fdClose(const int)
Close file descriptor.
Definition: POSIX.C:1140
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:253
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:98
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:1021
A class for handling character strings derived from std::string.
Definition: string.H:74
unsigned int sleep(const unsigned int)
Sleep for the specified number of seconds.
Definition: POSIX.C:1134
void * dlOpen(const fileName &lib, const bool check=true)
Open a shared library. Return handle to library. Print error message.
Definition: POSIX.C:1240
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:1280
bool dlSymFound(void *handle, const std::string &symbol)
Report if symbol in a dlopened library could be found.
Definition: POSIX.C:1309
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:1234
fileName path(UMean.rootPath()/UMean.caseName()/functionObjects::writeFile::outputPrefix/"graphs"/UMean.instance())
#define InfoInFunction
Report an information message using Foam::Info.