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