POSIX.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2017 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 "IOstreams.H"
42 #include "Pstream.H"
43 
44 #include <fstream>
45 #include <cstdlib>
46 #include <cctype>
47 
48 #include <stdio.h>
49 #include <unistd.h>
50 #include <dirent.h>
51 #include <pwd.h>
52 #include <errno.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <sys/socket.h>
56 #include <netdb.h>
57 #include <dlfcn.h>
58 #include <link.h>
59 
60 #include <netinet/in.h>
61 
62 #ifdef USE_RANDOM
63  #include <climits>
64  #if INT_MAX != 2147483647
65  #error "INT_MAX != 2147483647"
66  #error "The random number generator may not work!"
67  #endif
68 #endif
69 
70 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
71 
72 namespace Foam
73 {
74  defineTypeNameAndDebug(POSIX, 0);
75 }
76 
77 
78 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
79 
80 pid_t Foam::pid()
81 {
82  return ::getpid();
83 }
84 
85 
86 pid_t Foam::ppid()
87 {
88  return ::getppid();
89 }
90 
91 
92 pid_t Foam::pgid()
93 {
94  return ::getpgrp();
95 }
96 
97 
98 bool Foam::env(const word& envName)
99 {
100  return ::getenv(envName.c_str()) != nullptr;
101 }
102 
103 
105 {
106  char* env = ::getenv(envName.c_str());
107 
108  if (env)
109  {
110  return string(env);
111  }
112  else
113  {
114  // Return null-constructed string rather than string::null
115  // to avoid cyclic dependencies in the construction of globals
116  return string();
117  }
118 }
119 
120 
121 bool Foam::setEnv
122 (
123  const word& envName,
124  const std::string& value,
125  const bool overwrite
126 )
127 {
128  return setenv(envName.c_str(), value.c_str(), overwrite) == 0;
129 }
130 
131 
133 {
134  char buf[128];
135  ::gethostname(buf, sizeof(buf));
136 
137  // implementation as per hostname from net-tools
138  if (full)
139  {
140  struct hostent *hp = ::gethostbyname(buf);
141  if (hp)
142  {
143  return hp->h_name;
144  }
145  }
146 
147  return buf;
148 }
149 
150 
152 {
153  char buf[128];
154  ::gethostname(buf, sizeof(buf));
155 
156  // implementation as per hostname from net-tools
157  struct hostent *hp = ::gethostbyname(buf);
158  if (hp)
159  {
160  char *p = ::strchr(hp->h_name, '.');
161  if (p)
162  {
163  ++p;
164  return p;
165  }
166  }
167 
168  return string::null;
169 }
170 
171 
173 {
174  struct passwd* pw = ::getpwuid(::getuid());
175 
176  if (pw != nullptr)
177  {
178  return pw->pw_name;
179  }
180  else
181  {
182  return string::null;
183  }
184 }
185 
186 
188 {
189  return (::geteuid() == 0);
190 }
191 
192 
194 {
195  char* env = ::getenv("HOME");
196 
197  if (env != nullptr)
198  {
199  return fileName(env);
200  }
201  else
202  {
203  struct passwd* pw = ::getpwuid(getuid());
204 
205  if (pw != nullptr)
206  {
207  return pw->pw_dir;
208  }
209  else
210  {
211  return fileName::null;
212  }
213  }
214 }
215 
216 
218 {
219  struct passwd* pw;
220 
221  if (userName.size())
222  {
223  pw = ::getpwnam(userName.c_str());
224  }
225  else
226  {
227  char* env = ::getenv("HOME");
228 
229  if (env != nullptr)
230  {
231  return fileName(env);
232  }
233 
234  pw = ::getpwuid(::getuid());
235  }
236 
237  if (pw != nullptr)
238  {
239  return pw->pw_dir;
240  }
241  else
242  {
243  return fileName::null;
244  }
245 }
246 
247 
249 {
250  label pathLengthLimit = POSIX::pathLengthChunk;
251  List<char> path(pathLengthLimit);
252 
253  // Resize path if getcwd fails with an ERANGE error
254  while(pathLengthLimit == path.size())
255  {
256  if (::getcwd(path.data(), path.size()))
257  {
258  return path.data();
259  }
260  else if(errno == ERANGE)
261  {
262  // Increment path length upto the pathLengthMax limit
263  if
264  (
265  (pathLengthLimit += POSIX::pathLengthChunk)
267  )
268  {
270  << "Attempt to increase path length beyond limit of "
272  << exit(FatalError);
273  }
274 
275  path.setSize(pathLengthLimit);
276  }
277  else
278  {
279  break;
280  }
281  }
282 
284  << "Couldn't get the current working directory"
285  << exit(FatalError);
286 
287  return fileName::null;
288 }
289 
290 
291 bool Foam::chDir(const fileName& dir)
292 {
293  return ::chdir(dir.c_str()) == 0;
294 }
295 
296 
297 bool Foam::mkDir(const fileName& pathName, mode_t mode)
298 {
299  if (POSIX::debug)
300  {
301  Pout<< FUNCTION_NAME << " : pathName:" << pathName << " mode:" << mode
302  << endl;
303  if ((POSIX::debug & 2) && !Pstream::master())
304  {
306  }
307  }
308 
309  // empty names are meaningless
310  if (pathName.empty())
311  {
312  return false;
313  }
314 
315  // Construct instance path directory if does not exist
316  if (::mkdir(pathName.c_str(), mode) == 0)
317  {
318  // Directory made OK so return true
319  return true;
320  }
321  else
322  {
323  switch (errno)
324  {
325  case EPERM:
326  {
328  << "The filesystem containing " << pathName
329  << " does not support the creation of directories."
330  << exit(FatalError);
331 
332  return false;
333  }
334 
335  case EEXIST:
336  {
337  // Directory already exists so simply return true
338  return true;
339  }
340 
341  case EFAULT:
342  {
344  << "" << pathName
345  << " points outside your accessible address space."
346  << exit(FatalError);
347 
348  return false;
349  }
350 
351  case EACCES:
352  {
354  << "The parent directory does not allow write "
355  "permission to the process,"<< nl
356  << "or one of the directories in " << pathName
357  << " did not allow search (execute) permission."
358  << exit(FatalError);
359 
360  return false;
361  }
362 
363  case ENAMETOOLONG:
364  {
366  << "" << pathName << " is too long."
367  << exit(FatalError);
368 
369  return false;
370  }
371 
372  case ENOENT:
373  {
374  // Part of the path does not exist so try to create it
375  if (pathName.path().size() && mkDir(pathName.path(), mode))
376  {
377  return mkDir(pathName, mode);
378  }
379  else
380  {
382  << "Couldn't create directory " << pathName
383  << exit(FatalError);
384 
385  return false;
386  }
387  }
388 
389  case ENOTDIR:
390  {
392  << "A component used as a directory in " << pathName
393  << " is not, in fact, a directory."
394  << exit(FatalError);
395 
396  return false;
397  }
398 
399  case ENOMEM:
400  {
402  << "Insufficient kernel memory was available to make "
403  "directory " << pathName << '.'
404  << exit(FatalError);
405 
406  return false;
407  }
408 
409  case EROFS:
410  {
412  << "" << pathName
413  << " refers to a file on a read-only filesystem."
414  << exit(FatalError);
415 
416  return false;
417  }
418 
419  case ELOOP:
420  {
422  << "Too many symbolic links were encountered in resolving "
423  << pathName << '.'
424  << exit(FatalError);
425 
426  return false;
427  }
428 
429  case ENOSPC:
430  {
432  << "The device containing " << pathName
433  << " has no room for the new directory or "
434  << "the user's disk quota is exhausted."
435  << exit(FatalError);
436 
437  return false;
438  }
439 
440  default:
441  {
443  << "Couldn't create directory " << pathName
444  << exit(FatalError);
445 
446  return false;
447  }
448  }
449  }
450 }
451 
452 
453 bool Foam::chMod(const fileName& name, const mode_t m)
454 {
455  if (POSIX::debug)
456  {
457  Pout<< FUNCTION_NAME << " : name:" << name << endl;
458  if ((POSIX::debug & 2) && !Pstream::master())
459  {
461  }
462  }
463  return ::chmod(name.c_str(), m) == 0;
464 }
465 
466 
467 mode_t Foam::mode(const fileName& name, const bool followLink)
468 {
469  if (POSIX::debug)
470  {
471  Pout<< FUNCTION_NAME << " : name:" << name << endl;
472  }
473  fileStat fileStatus(name, followLink);
474  if (fileStatus.isValid())
475  {
476  return fileStatus.status().st_mode;
477  }
478  else
479  {
480  return 0;
481  }
482 }
483 
484 
485 Foam::fileName::Type Foam::type(const fileName& name, const bool followLink)
486 {
487  if (POSIX::debug)
488  {
489  Pout<< FUNCTION_NAME << " : name:" << name << endl;
490  if ((POSIX::debug & 2) && !Pstream::master())
491  {
493  }
494  }
495  mode_t m = mode(name, followLink);
496 
497  if (S_ISREG(m))
498  {
499  return fileName::FILE;
500  }
501  else if (S_ISLNK(m))
502  {
503  return fileName::LINK;
504  }
505  else if (S_ISDIR(m))
506  {
507  return fileName::DIRECTORY;
508  }
509  else
510  {
511  return fileName::UNDEFINED;
512  }
513 }
514 
515 
516 bool Foam::exists
517 (
518  const fileName& name,
519  const bool checkGzip,
520  const bool followLink
521 )
522 {
523  if (POSIX::debug)
524  {
525  Pout<< FUNCTION_NAME << " : name:" << name << " checkGzip:" << checkGzip
526  << endl;
527  if ((POSIX::debug & 2) && !Pstream::master())
528  {
530  }
531  }
532  return mode(name, followLink) || isFile(name, checkGzip, followLink);
533 }
534 
535 
536 bool Foam::isDir(const fileName& name, const bool followLink)
537 {
538  if (POSIX::debug)
539  {
540  Pout<< FUNCTION_NAME << " : name:" << name << endl;
541  if ((POSIX::debug & 2) && !Pstream::master())
542  {
544  }
545  }
546  return S_ISDIR(mode(name, followLink));
547 }
548 
549 
550 bool Foam::isFile
551 (
552  const fileName& name,
553  const bool checkGzip,
554  const bool followLink
555 )
556 {
557  if (POSIX::debug)
558  {
559  Pout<< FUNCTION_NAME << " : name:" << name << " checkGzip:" << checkGzip
560  << endl;
561  if ((POSIX::debug & 2) && !Pstream::master())
562  {
564  }
565  }
566  return
567  S_ISREG(mode(name, followLink))
568  || (checkGzip && S_ISREG(mode(name + ".gz", followLink)));
569 }
570 
571 
572 off_t Foam::fileSize(const fileName& name, const bool followLink)
573 {
574  if (POSIX::debug)
575  {
576  Pout<< FUNCTION_NAME << " : name:" << name << endl;
577  if ((POSIX::debug & 2) && !Pstream::master())
578  {
580  }
581  }
582  fileStat fileStatus(name, followLink);
583  if (fileStatus.isValid())
584  {
585  return fileStatus.status().st_size;
586  }
587  else
588  {
589  return -1;
590  }
591 }
592 
593 
594 time_t Foam::lastModified(const fileName& name, const bool followLink)
595 {
596  if (POSIX::debug)
597  {
598  Pout<< FUNCTION_NAME << " : name:" << name << endl;
599  if ((POSIX::debug & 2) && !Pstream::master())
600  {
602  }
603  }
604  fileStat fileStatus(name, followLink);
605  if (fileStatus.isValid())
606  {
607  return fileStatus.status().st_mtime;
608  }
609  else
610  {
611  return 0;
612  }
613 }
614 
615 
616 double Foam::highResLastModified(const fileName& name, const bool followLink)
617 {
618  if (POSIX::debug)
619  {
620  Pout<< FUNCTION_NAME << " : name:" << name << endl;
621  if ((POSIX::debug & 2) && !Pstream::master())
622  {
624  }
625  }
626  fileStat fileStatus(name, followLink);
627  if (fileStatus.isValid())
628  {
629  return
630  fileStatus.status().st_mtime
631  + 1e-9*fileStatus.status().st_atim.tv_nsec;
632  }
633  else
634  {
635  return 0;
636  }
637 }
638 
639 
641 (
642  const fileName& directory,
643  const fileName::Type type,
644  const bool filtergz,
645  const bool followLink
646 )
647 {
648  // Initial filename list size
649  // also used as increment if initial size found to be insufficient
650  static const int maxNnames = 100;
651 
652  if (POSIX::debug)
653  {
654  //InfoInFunction
655  Pout<< FUNCTION_NAME << " : reading directory " << directory << endl;
656  if ((POSIX::debug & 2) && !Pstream::master())
657  {
659  }
660  }
661 
662  // Setup empty string list MAXTVALUES long
663  fileNameList dirEntries(maxNnames);
664 
665  // Pointers to the directory entries
666  DIR *source;
667  struct dirent *list;
668 
669  // Temporary variables and counters
670  label nEntries = 0;
671 
672  // Attempt to open directory and set the structure pointer
673  if ((source = ::opendir(directory.c_str())) == nullptr)
674  {
675  dirEntries.setSize(0);
676 
677  if (POSIX::debug)
678  {
680  << "cannot open directory " << directory << endl;
681  }
682  }
683  else
684  {
685  // Read and parse all the entries in the directory
686  while ((list = ::readdir(source)) != nullptr)
687  {
688  fileName fName(list->d_name);
689 
690  // ignore files begining with ., i.e. '.', '..' and '.*'
691  if (fName.size() && fName[0] != '.')
692  {
693  word fExt = fName.ext();
694 
695  if
696  (
697  (type == fileName::DIRECTORY)
698  ||
699  (
700  type == fileName::FILE
701  && fName[fName.size()-1] != '~'
702  && fExt != "bak"
703  && fExt != "BAK"
704  && fExt != "old"
705  && fExt != "save"
706  )
707  )
708  {
709  if ((directory/fName).type(followLink) == type)
710  {
711  if (nEntries >= dirEntries.size())
712  {
713  dirEntries.setSize(dirEntries.size() + maxNnames);
714  }
715 
716  if (filtergz && fExt == "gz")
717  {
718  dirEntries[nEntries++] = fName.lessExt();
719  }
720  else
721  {
722  dirEntries[nEntries++] = fName;
723  }
724  }
725  }
726  }
727  }
728 
729  // Reset the length of the entries list
730  dirEntries.setSize(nEntries);
731 
732  ::closedir(source);
733  }
734 
735  return dirEntries;
736 }
737 
738 
739 bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
740 {
741  if (POSIX::debug)
742  {
743  Pout<< FUNCTION_NAME << " : src:" << src << " dest:" << dest << endl;
744  if ((POSIX::debug & 2) && !Pstream::master())
745  {
747  }
748  }
749  // Make sure source exists.
750  if (!exists(src))
751  {
752  return false;
753  }
754 
755  const fileName::Type srcType = src.type(followLink);
756 
757  fileName destFile(dest);
758 
759  // Check type of source file.
760  if (srcType == fileName::FILE)
761  {
762  // If dest is a directory, create the destination file name.
763  if (destFile.type() == fileName::DIRECTORY)
764  {
765  destFile = destFile/src.name();
766  }
767 
768  // Make sure the destination directory exists.
769  if (!isDir(destFile.path()) && !mkDir(destFile.path()))
770  {
771  return false;
772  }
773 
774  // Open and check streams.
775  std::ifstream srcStream(src.c_str());
776  if (!srcStream)
777  {
778  return false;
779  }
780 
781  std::ofstream destStream(destFile.c_str());
782  if (!destStream)
783  {
784  return false;
785  }
786 
787  // Copy character data.
788  char ch;
789  while (srcStream.get(ch))
790  {
791  destStream.put(ch);
792  }
793 
794  // Final check.
795  if (!srcStream.eof() || !destStream)
796  {
797  return false;
798  }
799  }
800  else if (srcType == fileName::LINK)
801  {
802  // If dest is a directory, create the destination file name.
803  if (destFile.type() == fileName::DIRECTORY)
804  {
805  destFile = destFile/src.name();
806  }
807 
808  // Make sure the destination directory exists.
809  if (!isDir(destFile.path()) && !mkDir(destFile.path()))
810  {
811  return false;
812  }
813 
814  ln(src, destFile);
815  }
816  else if (srcType == fileName::DIRECTORY)
817  {
818  // If dest is a directory, create the destination file name.
819  if (destFile.type() == fileName::DIRECTORY)
820  {
821  destFile = destFile/src.component(src.components().size() -1);
822  }
823 
824  // Make sure the destination directory exists.
825  if (!isDir(destFile) && !mkDir(destFile))
826  {
827  return false;
828  }
829 
830  // Copy files
831  fileNameList contents = readDir(src, fileName::FILE, false, followLink);
832  forAll(contents, i)
833  {
834  if (POSIX::debug)
835  {
837  << "Copying : " << src/contents[i]
838  << " to " << destFile/contents[i] << endl;
839  }
840 
841  // File to file.
842  cp(src/contents[i], destFile/contents[i], followLink);
843  }
844 
845  // Copy sub directories.
846  fileNameList subdirs = readDir
847  (
848  src,
850  false,
851  followLink
852  );
853 
854  forAll(subdirs, i)
855  {
856  if (POSIX::debug)
857  {
859  << "Copying : " << src/subdirs[i]
860  << " to " << destFile << endl;
861  }
862 
863  // Dir to Dir.
864  cp(src/subdirs[i], destFile, followLink);
865  }
866  }
867 
868  return true;
869 }
870 
871 
872 bool Foam::ln(const fileName& src, const fileName& dst)
873 {
874  if (POSIX::debug)
875  {
876  //InfoInFunction
878  << " : Create softlink from : " << src << " to " << dst << endl;
879  if ((POSIX::debug & 2) && !Pstream::master())
880  {
882  }
883  }
884 
885  if (exists(dst))
886  {
888  << "destination " << dst << " already exists. Not linking."
889  << endl;
890  return false;
891  }
892 
893  if (src.isAbsolute() && !exists(src))
894  {
896  << "source " << src << " does not exist." << endl;
897  return false;
898  }
899 
900  if (::symlink(src.c_str(), dst.c_str()) == 0)
901  {
902  return true;
903  }
904  else
905  {
907  << "symlink from " << src << " to " << dst << " failed." << endl;
908  return false;
909  }
910 }
911 
912 
913 bool Foam::mv(const fileName& src, const fileName& dst, const bool followLink)
914 {
915  if (POSIX::debug)
916  {
917  //InfoInFunction
918  Pout<< FUNCTION_NAME << " : Move : " << src << " to " << dst << endl;
919  if ((POSIX::debug & 2) && !Pstream::master())
920  {
922  }
923  }
924 
925  if
926  (
927  dst.type() == fileName::DIRECTORY
928  && src.type(followLink) != fileName::DIRECTORY
929  )
930  {
931  const fileName dstName(dst/src.name());
932 
933  return ::rename(src.c_str(), dstName.c_str()) == 0;
934  }
935  else
936  {
937  return ::rename(src.c_str(), dst.c_str()) == 0;
938  }
939 }
940 
941 
942 bool Foam::mvBak(const fileName& src, const std::string& ext)
943 {
944  if (POSIX::debug)
945  {
946  //InfoInFunction
948  << " : moving : " << src << " to extension " << ext << endl;
949  if ((POSIX::debug & 2) && !Pstream::master())
950  {
952  }
953  }
954 
955  if (exists(src, false))
956  {
957  const int maxIndex = 99;
958  char index[3];
959 
960  for (int n = 0; n <= maxIndex; n++)
961  {
962  fileName dstName(src + "." + ext);
963  if (n)
964  {
965  sprintf(index, "%02d", n);
966  dstName += index;
967  }
968 
969  // avoid overwriting existing files, except for the last
970  // possible index where we have no choice
971  if (!exists(dstName, false) || n == maxIndex)
972  {
973  return ::rename(src.c_str(), dstName.c_str()) == 0;
974  }
975 
976  }
977  }
978 
979  // fall-through: nothing to do
980  return false;
981 }
982 
983 
984 bool Foam::rm(const fileName& file)
985 {
986  if (POSIX::debug)
987  {
988  //InfoInFunction
989  Pout<< FUNCTION_NAME << " : Removing : " << file << endl;
990  if ((POSIX::debug & 2) && !Pstream::master())
991  {
993  }
994  }
995 
996  // Try returning plain file name; if not there, try with .gz
997  if (remove(file.c_str()) == 0)
998  {
999  return true;
1000  }
1001  else
1002  {
1003  return ::remove(string(file + ".gz").c_str()) == 0;
1004  }
1005 }
1006 
1007 
1008 bool Foam::rmDir(const fileName& directory)
1009 {
1010  if (POSIX::debug)
1011  {
1012  //InfoInFunction
1013  Pout<< FUNCTION_NAME << " : removing directory " << directory << endl;
1014  if ((POSIX::debug & 2) && !Pstream::master())
1015  {
1017  }
1018  }
1019 
1020  // Pointers to the directory entries
1021  DIR *source;
1022  struct dirent *list;
1023 
1024  // Attempt to open directory and set the structure pointer
1025  if ((source = ::opendir(directory.c_str())) == nullptr)
1026  {
1028  << "cannot open directory " << directory << endl;
1029 
1030  return false;
1031  }
1032  else
1033  {
1034  // Read and parse all the entries in the directory
1035  while ((list = ::readdir(source)) != nullptr)
1036  {
1037  fileName fName(list->d_name);
1038 
1039  if (fName != "." && fName != "..")
1040  {
1041  fileName path = directory/fName;
1042 
1043  if (path.type(false) == fileName::DIRECTORY)
1044  {
1045  if (!rmDir(path))
1046  {
1048  << "failed to remove directory " << fName
1049  << " while removing directory " << directory
1050  << endl;
1051 
1052  ::closedir(source);
1053 
1054  return false;
1055  }
1056  }
1057  else
1058  {
1059  if (!rm(path))
1060  {
1062  << "failed to remove file " << fName
1063  << " while removing directory " << directory
1064  << endl;
1065 
1066  ::closedir(source);
1067 
1068  return false;
1069  }
1070  }
1071  }
1072 
1073  }
1074 
1075  if (!rm(directory))
1076  {
1078  << "failed to remove directory " << directory << endl;
1079 
1080  ::closedir(source);
1081 
1082  return false;
1083  }
1084 
1085  ::closedir(source);
1086 
1087  return true;
1088  }
1089 }
1090 
1091 
1092 unsigned int Foam::sleep(const unsigned int s)
1093 {
1094  return ::sleep(s);
1095 }
1096 
1097 
1098 void Foam::fdClose(const int fd)
1099 {
1100  if (close(fd) != 0)
1101  {
1103  << "close error on " << fd << endl
1104  << abort(FatalError);
1105  }
1106 }
1107 
1108 
1109 bool Foam::ping
1111  const string& destName,
1112  const label destPort,
1113  const label timeOut
1114 )
1115 {
1116  struct hostent *hostPtr;
1117  volatile int sockfd;
1118  struct sockaddr_in destAddr; // will hold the destination addr
1119  u_int addr;
1120 
1121  if ((hostPtr = ::gethostbyname(destName.c_str())) == nullptr)
1122  {
1124  << "gethostbyname error " << h_errno << " for host " << destName
1125  << abort(FatalError);
1126  }
1127 
1128  // Get first of the SLL of addresses
1129  addr = (reinterpret_cast<struct in_addr*>(*(hostPtr->h_addr_list)))->s_addr;
1130 
1131  // Allocate socket
1132  sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1133  if (sockfd < 0)
1134  {
1136  << "socket error"
1137  << abort(FatalError);
1138  }
1139 
1140  // Fill sockaddr_in structure with dest address and port
1141  memset(reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
1142  destAddr.sin_family = AF_INET;
1143  destAddr.sin_port = htons(ushort(destPort));
1144  destAddr.sin_addr.s_addr = addr;
1145 
1146 
1147  timer myTimer(timeOut);
1148 
1149  if (timedOut(myTimer))
1150  {
1151  // Setjmp from timer jumps back to here
1152  fdClose(sockfd);
1153  return false;
1154  }
1155 
1156  if
1157  (
1158  ::connect
1159  (
1160  sockfd,
1161  reinterpret_cast<struct sockaddr*>(&destAddr),
1162  sizeof(struct sockaddr)
1163  ) != 0
1164  )
1165  {
1166  // Connection refused. Check if network was actually used or not.
1167 
1168  int connectErr = errno;
1169 
1170  fdClose(sockfd);
1171 
1172  if (connectErr == ECONNREFUSED)
1173  {
1174  return true;
1175  }
1176  //perror("connect");
1177 
1178  return false;
1179  }
1180 
1181  fdClose(sockfd);
1182 
1183  return true;
1184 }
1185 
1186 
1187 bool Foam::ping(const string& hostname, const label timeOut)
1188 {
1189  return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
1190 }
1191 
1192 
1193 int Foam::system(const std::string& command)
1194 {
1195  return ::system(command.c_str());
1196 }
1197 
1198 
1199 void* Foam::dlOpen(const fileName& lib, const bool check)
1200 {
1201  if (POSIX::debug)
1202  {
1203  std::cout<< "dlOpen(const fileName&)"
1204  << " : dlopen of " << lib << std::endl;
1205  }
1206  void* handle = ::dlopen(lib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
1207 
1208  if (!handle && check)
1209  {
1211  << "dlopen error : " << ::dlerror()
1212  << endl;
1213  }
1214 
1215  if (POSIX::debug)
1216  {
1217  std::cout
1218  << "dlOpen(const fileName&)"
1219  << " : dlopen of " << lib
1220  << " handle " << handle << std::endl;
1221  }
1222 
1223  return handle;
1224 }
1225 
1226 
1227 bool Foam::dlClose(void* handle)
1228 {
1229  if (POSIX::debug)
1230  {
1231  std::cout
1232  << "dlClose(void*)"
1233  << " : dlclose of handle " << handle << std::endl;
1234  }
1235  return ::dlclose(handle) == 0;
1236 }
1237 
1238 
1239 void* Foam::dlSym(void* handle, const std::string& symbol)
1240 {
1241  if (POSIX::debug)
1242  {
1243  std::cout
1244  << "dlSym(void*, const std::string&)"
1245  << " : dlsym of " << symbol << std::endl;
1246  }
1247  // clear any old errors - see manpage dlopen
1248  (void) ::dlerror();
1249 
1250  // get address of symbol
1251  void* fun = ::dlsym(handle, symbol.c_str());
1252 
1253  // find error (if any)
1254  char *error = ::dlerror();
1255 
1256  if (error)
1257  {
1259  << "Cannot lookup symbol " << symbol << " : " << error
1260  << endl;
1261  }
1262 
1263  return fun;
1264 }
1265 
1266 
1267 bool Foam::dlSymFound(void* handle, const std::string& symbol)
1268 {
1269  if (handle && !symbol.empty())
1270  {
1271  if (POSIX::debug)
1272  {
1273  std::cout
1274  << "dlSymFound(void*, const std::string&)"
1275  << " : dlsym of " << symbol << std::endl;
1276  }
1277 
1278  // clear any old errors - see manpage dlopen
1279  (void) ::dlerror();
1280 
1281  // get address of symbol
1282  (void) ::dlsym(handle, symbol.c_str());
1283 
1284  // symbol can be found if there was no error
1285  return !::dlerror();
1286  }
1287  else
1288  {
1289  return false;
1290  }
1291 }
1292 
1293 
1294 static int collectLibsCallback
1296  struct dl_phdr_info *info,
1297  size_t size,
1298  void *data
1299 )
1300 {
1302  reinterpret_cast<Foam::DynamicList<Foam::fileName>*>(data);
1303  ptr->append(info->dlpi_name);
1304  return 0;
1305 }
1306 
1307 
1309 {
1310  DynamicList<fileName> libs;
1311  dl_iterate_phdr(collectLibsCallback, &libs);
1312  if (POSIX::debug)
1313  {
1314  std::cout
1315  << "dlLoaded()"
1316  << " : determined loaded libraries :" << libs.size() << std::endl;
1317  }
1318  return libs;
1319 }
1320 
1321 
1322 void Foam::osRandomSeed(const label seed)
1323 {
1324  #ifdef USE_RANDOM
1325  srandom((unsigned int)seed);
1326  #else
1327  srand48(seed);
1328  #endif
1329 }
1330 
1331 
1333 {
1334  #ifdef USE_RANDOM
1335  return random();
1336  #else
1337  return lrand48();
1338  #endif
1339 }
1340 
1341 
1342 Foam::scalar Foam::osRandomDouble()
1343 {
1344  #ifdef USE_RANDOM
1345  return (scalar)random()/INT_MAX;
1346  #else
1347  return drand48();
1348  #endif
1349 }
1350 
1351 
1354 
1355 
1357 {
1358  forAll(threads_, i)
1359  {
1360  if (!threads_[i].valid())
1361  {
1362  if (POSIX::debug)
1363  {
1364  Pout<< "allocateThread : reusing index:" << i << endl;
1365  }
1366  // Reuse entry
1367  threads_[i].reset(new pthread_t());
1368  return i;
1369  }
1370  }
1371 
1372  label index = threads_.size();
1373  if (POSIX::debug)
1374  {
1375  Pout<< "allocateThread : new index:" << index << endl;
1376  }
1377  threads_.append(autoPtr<pthread_t>(new pthread_t()));
1378 
1379  return index;
1380 }
1381 
1382 
1383 void Foam::createThread
1385  const label index,
1386  void *(*start_routine) (void *),
1387  void *arg
1388 )
1389 {
1390  if (POSIX::debug)
1391  {
1392  Pout<< "createThread : index:" << index << endl;
1393  }
1394  if (pthread_create(&threads_[index](), nullptr, start_routine, arg))
1395  {
1397  << "Failed starting thread " << index << exit(FatalError);
1398  }
1399 }
1400 
1401 
1402 void Foam::joinThread(const label index)
1403 {
1404  if (POSIX::debug)
1405  {
1406  Pout<< "freeThread : join:" << index << endl;
1407  }
1408  if (pthread_join(threads_[index](), nullptr))
1409  {
1410  FatalErrorInFunction << "Failed freeing thread " << index
1411  << exit(FatalError);
1412  }
1413 }
1414 
1415 
1416 void Foam::freeThread(const label index)
1417 {
1418  if (POSIX::debug)
1419  {
1420  Pout<< "freeThread : index:" << index << endl;
1421  }
1422  threads_[index].clear();
1423 }
1424 
1425 
1427 {
1428  forAll(mutexes_, i)
1429  {
1430  if (!mutexes_[i].valid())
1431  {
1432  if (POSIX::debug)
1433  {
1434  Pout<< "allocateMutex : reusing index:" << i << endl;
1435  }
1436  // Reuse entry
1437  mutexes_[i].reset(new pthread_mutex_t());
1438  return i;
1439  }
1440  }
1441 
1442  label index = mutexes_.size();
1443 
1444  if (POSIX::debug)
1445  {
1446  Pout<< "allocateMutex : new index:" << index << endl;
1447  }
1448  mutexes_.append(autoPtr<pthread_mutex_t>(new pthread_mutex_t()));
1449  return index;
1450 }
1451 
1452 
1453 void Foam::lockMutex(const label index)
1454 {
1455  if (POSIX::debug)
1456  {
1457  Pout<< "lockMutex : index:" << index << endl;
1458  }
1459  if (pthread_mutex_lock(&mutexes_[index]()))
1460  {
1461  FatalErrorInFunction << "Failed locking mutex " << index
1462  << exit(FatalError);
1463  }
1464 }
1465 
1466 
1467 void Foam::unlockMutex(const label index)
1468 {
1469  if (POSIX::debug)
1470  {
1471  Pout<< "unlockMutex : index:" << index << endl;
1472  }
1473  if (pthread_mutex_unlock(&mutexes_[index]()))
1474  {
1475  FatalErrorInFunction << "Failed unlocking mutex " << index
1476  << exit(FatalError);
1477  }
1478 }
1479 
1480 
1481 void Foam::freeMutex(const label index)
1482 {
1483  if (POSIX::debug)
1484  {
1485  Pout<< "freeMutex : index:" << index << endl;
1486  }
1487  mutexes_[index].clear();
1488 }
1489 
1490 
1491 // ************************************************************************* //
void freeMutex(const label)
Free a mutex variable.
Definition: POSIX.C:1481
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:104
time_t lastModified(const fileName &, const bool followLink=true)
Return time of last file modification.
Definition: POSIX.C:594
static void printStack(Ostream &)
Helper function to print a stack.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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:913
scalar random
A class for handling file names.
Definition: fileName.H:69
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const double e
Elementary charge.
Definition: doubleFloat.H:78
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
const label pathLengthMax
Definition: POSIX.H:53
off_t fileSize(const fileName &, const bool followLink=true)
Return size of file.
Definition: POSIX.C:572
pid_t ppid()
Return the parent PID of this process.
Definition: POSIX.C:86
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
scalar osRandomDouble()
Return random double precision (uniform distribution between 0 and 1)
Definition: POSIX.C:1342
static const fileName null
An empty fileName.
Definition: fileName.H:97
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
bool cp(const fileName &src, const fileName &dst, const bool followLink=true)
Copy, recursively if necessary, the source to the destination.
Definition: POSIX.C:739
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:412
bool chDir(const fileName &dir)
Change the current directory to the one given and return true,.
Definition: POSIX.C:291
bool ping(const string &, const label port, const label timeOut)
Check if machine is up by pinging given port.
Definition: POSIX.C:1110
fileNameList dlLoaded()
Return all loaded libraries.
Definition: POSIX.C:1308
void unlockMutex(const label)
Unlock a mutex variable.
Definition: POSIX.C:1467
const label pathLengthChunk
Definition: POSIX.H:52
fileName home()
Return home directory path name for the current user.
Definition: POSIX.C:193
static int collectLibsCallback(struct dl_phdr_info *info, size_t size, void *data)
Definition: POSIX.C:1295
bool mvBak(const fileName &, const std::string &ext="bak")
Rename to a corresponding backup file.
Definition: POSIX.C:942
void freeThread(const label)
Delete a thread.
Definition: POSIX.C:1416
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:284
Type type(const bool followLink=true) const
Return the file type: FILE, DIRECTORY, UNDEFINED or.
Definition: fileName.C:52
wordList components(const char delimiter='/') const
Return path components as wordList.
Definition: fileName.C:299
const struct stat & status() const
Raw status.
Definition: fileStat.H:100
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:132
bool dlClose(void *)
Close a dlopened library using handle. Return true if successful.
Definition: POSIX.C:1227
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:58
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:536
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:151
label osRandomInteger()
Return random integer (uniform distribution between 0 and 2^31)
Definition: POSIX.C:1332
mode_t mode(const fileName &, const bool followLink=true)
Return the file mode.
Definition: POSIX.C:467
word name() const
Return file name (part beyond last /)
Definition: fileName.C:180
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:292
string userName()
Return the user&#39;s login name.
Definition: POSIX.C:172
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:872
void joinThread(const label)
Wait for thread.
Definition: POSIX.C:1402
void createThread(const label, void *(*start_routine)(void *), void *arg)
Start a thread.
Definition: POSIX.C:1384
word component(const size_type, const char delimiter='/') const
Return a single component of the path.
Definition: fileName.C:327
static const string null
An empty string.
Definition: string.H:86
bool rmDir(const fileName &)
Remove a dirctory and its contents.
Definition: POSIX.C:1008
pid_t pid()
Return the PID of this process.
Definition: POSIX.C:80
bool isFile(const fileName &, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: POSIX.C:551
static const char nl
Definition: Ostream.H:262
#define FUNCTION_NAME
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
Wrapper for stat() system call.
Definition: fileStat.H:65
void lockMutex(const label)
Lock a mutex variable.
Definition: POSIX.C:1453
#define timedOut(x)
Check it a timeout has occured.
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:297
pid_t pgid()
Return the group PID of this process.
Definition: POSIX.C:92
fileName::Type type(const fileName &, const bool followLink=true)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:485
bool isAdministrator()
Is user administrator.
Definition: POSIX.C:187
label allocateThread()
Allocate a thread.
Definition: POSIX.C:1356
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
static Foam::DynamicList< Foam::autoPtr< pthread_mutex_t > > mutexes_
Definition: POSIX.C:1353
#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:453
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:269
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:248
fileNameList readDir(const fileName &, const fileName::Type=fileName::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a string list.
Definition: POSIX.C:641
void fdClose(const int)
Close file descriptor.
Definition: POSIX.C:1098
label n
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:250
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
bool env(const word &)
Return true if environment variable of given name is defined.
Definition: POSIX.C:98
volScalarField & p
bool rm(const fileName &)
Remove a file, returning true if successful otherwise false.
Definition: POSIX.C:984
label allocateMutex()
Allocate a mutex variable.
Definition: POSIX.C:1426
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:224
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:1092
void * dlOpen(const fileName &lib, const bool check=true)
Open a shared library. Return handle to library. Print error message.
Definition: POSIX.C:1199
void osRandomSeed(const label seed)
Seed random number generator.
Definition: POSIX.C:1322
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:122
void * dlSym(void *handle, const std::string &symbol)
Lookup a symbol in a dlopened library using handle to library.
Definition: POSIX.C:1239
bool dlSymFound(void *handle, const std::string &symbol)
Report if symbol in a dlopened library could be found.
Definition: POSIX.C:1267
static Foam::DynamicList< Foam::autoPtr< pthread_t > > threads_
Definition: POSIX.C:1352
bool exists(const fileName &, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:517
Type
Enumerations to handle file types and modes.
Definition: fileName.H:82
bool isValid() const
Did constructor fail.
Definition: fileStat.H:106
Namespace for OpenFOAM.
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1193
double highResLastModified(const fileName &, const bool followLink=true)
Return time of last file modification.
Definition: POSIX.C:616
#define InfoInFunction
Report an information message using Foam::Info.