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