BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OSspecific / POSIX / POSIX.C
blob7595c5a695809105109c6d1a3eba46de5e23c397
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 Description
25     POSIX versions of the functions declared in OSspecific.H
27 \*---------------------------------------------------------------------------*/
29 #ifdef solarisGcc
30 # define _SYS_VNODE_H
31 #endif
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"
42 #include <fstream>
43 #include <cstdlib>
44 #include <cctype>
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>
58 #include <netinet/in.h>
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
68 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
70 defineTypeNameAndDebug(Foam::POSIX, 0);
72 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
74 pid_t Foam::pid()
76     return ::getpid();
80 pid_t Foam::ppid()
82     return ::getppid();
86 pid_t Foam::pgid()
88     return ::getpgrp();
92 bool Foam::env(const word& envName)
94     return ::getenv(envName.c_str()) != NULL;
98 Foam::string Foam::getEnv(const word& envName)
100     char* env = ::getenv(envName.c_str());
102     if (env)
103     {
104         return string(env);
105     }
106     else
107     {
108         // Return null-constructed string rather than string::null
109         // to avoid cyclic dependencies in the construction of globals
110         return string();
111     }
115 bool Foam::setEnv
117     const word& envName,
118     const std::string& value,
119     const bool overwrite
122     return setenv(envName.c_str(), value.c_str(), overwrite) == 0;
126 Foam::word Foam::hostName(bool full)
128     char buf[128];
129     ::gethostname(buf, sizeof(buf));
131     // implementation as per hostname from net-tools
132     if (full)
133     {
134         struct hostent *hp = ::gethostbyname(buf);
135         if (hp)
136         {
137             return hp->h_name;
138         }
139     }
141     return buf;
145 Foam::word Foam::domainName()
147     char buf[128];
148     ::gethostname(buf, sizeof(buf));
150     // implementation as per hostname from net-tools
151     struct hostent *hp = ::gethostbyname(buf);
152     if (hp)
153     {
154         char *p = ::strchr(hp->h_name, '.');
155         if (p)
156         {
157             ++p;
158             return p;
159         }
160     }
162     return word::null;
166 Foam::word Foam::userName()
168     struct passwd* pw = ::getpwuid(::getuid());
170     if (pw != NULL)
171     {
172         return pw->pw_name;
173     }
174     else
175     {
176         return word::null;
177     }
181 bool Foam::isAdministrator()
183     return (::geteuid() == 0);
187 // use $HOME environment variable or passwd info
188 Foam::fileName Foam::home()
190     char* env = ::getenv("HOME");
192     if (env != NULL)
193     {
194         return fileName(env);
195     }
196     else
197     {
198         struct passwd* pw = ::getpwuid(getuid());
200         if (pw != NULL)
201         {
202             return pw->pw_dir;
203         }
204         else
205         {
206             return fileName::null;
207         }
208     }
212 Foam::fileName Foam::home(const word& userName)
214     struct passwd* pw;
216     if (userName.size())
217     {
218         pw = ::getpwnam(userName.c_str());
219     }
220     else
221     {
222         char* env = ::getenv("HOME");
224         if (env != NULL)
225         {
226             return fileName(env);
227         }
229         pw = ::getpwuid(::getuid());
230     }
232     if (pw != NULL)
233     {
234         return pw->pw_dir;
235     }
236     else
237     {
238         return fileName::null;
239     }
243 Foam::fileName Foam::cwd()
245     char buf[256];
246     if (::getcwd(buf, sizeof(buf)))
247     {
248         return buf;
249     }
250     else
251     {
252         FatalErrorIn("Foam::cwd()")
253             << "Couldn't get the current working directory"
254             << exit(FatalError);
256         return fileName::null;
257     }
261 bool Foam::chDir(const fileName& dir)
263     return ::chdir(dir.c_str()) == 0;
267 Foam::fileNameList Foam::findEtcFiles(const fileName& name, bool mandatory)
269     fileNameList results;
271     // Search for user files in
272     // * ~/.OpenFOAM/VERSION
273     // * ~/.OpenFOAM
274     //
275     fileName searchDir = home()/".OpenFOAM";
276     if (isDir(searchDir))
277     {
278         fileName fullName = searchDir/FOAMversion/name;
279         if (isFile(fullName))
280         {
281             results.append(fullName);
282         }
284         fullName = searchDir/name;
285         if (isFile(fullName))
286         {
287             results.append(fullName);
288         }
289     }
291     // Search for group (site) files in
292     // * $WM_PROJECT_SITE/VERSION
293     // * $WM_PROJECT_SITE
294     //
295     searchDir = getEnv("WM_PROJECT_SITE");
296     if (searchDir.size())
297     {
298         if (isDir(searchDir))
299         {
300             fileName fullName = searchDir/FOAMversion/name;
301             if (isFile(fullName))
302             {
303                 results.append(fullName);
304             }
306             fullName = searchDir/name;
307             if (isFile(fullName))
308             {
309                 results.append(fullName);
310             }
311         }
312     }
313     else
314     {
315         // OR search for group (site) files in
316         // * $WM_PROJECT_INST_DIR/site/VERSION
317         // * $WM_PROJECT_INST_DIR/site
318         //
319         searchDir = getEnv("WM_PROJECT_INST_DIR");
320         if (isDir(searchDir))
321         {
322             fileName fullName = searchDir/"site"/FOAMversion/name;
323             if (isFile(fullName))
324             {
325                 results.append(fullName);
326             }
328             fullName = searchDir/"site"/name;
329             if (isFile(fullName))
330             {
331                 results.append(fullName);
332             }
333         }
334     }
336     // Search for other (shipped) files in
337     // * $WM_PROJECT_DIR/etc
338     //
339     searchDir = getEnv("WM_PROJECT_DIR");
340     if (isDir(searchDir))
341     {
342         fileName fullName = searchDir/"etc"/name;
343         if (isFile(fullName))
344         {
345             results.append(fullName);
346         }
347     }
349     // Not found
350     if (results.empty())
351     {
352         // Abort if the file is mandatory, otherwise return null
353         if (mandatory)
354         {
355             std::cerr
356                 << "--> FOAM FATAL ERROR in Foam::findEtcFiles() :"
357                    " could not find mandatory file\n    '"
358                 << name.c_str() << "'\n\n" << std::endl;
359             ::exit(1);
360         }
361     }
363     // Return list of matching paths or empty list if none found
364     return results;
368 Foam::fileName Foam::findEtcFile(const fileName& name, bool mandatory)
370     fileNameList results(findEtcFiles(name, mandatory));
372     if (results.size())
373     {
374         return results[0];
375     }
376     else
377     {
378         return fileName();
379     }
383 bool Foam::mkDir(const fileName& pathName, mode_t mode)
385     // empty names are meaningless
386     if (pathName.empty())
387     {
388         return false;
389     }
391     // Construct instance path directory if does not exist
392     if (::mkdir(pathName.c_str(), mode) == 0)
393     {
394         // Directory made OK so return true
395         return true;
396     }
397     else
398     {
399         switch (errno)
400         {
401             case EPERM:
402             {
403                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
404                     << "The filesystem containing " << pathName
405                     << " does not support the creation of directories."
406                     << exit(FatalError);
408                 return false;
409             }
411             case EEXIST:
412             {
413                 // Directory already exists so simply return true
414                 return true;
415             }
417             case EFAULT:
418             {
419                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
420                     << "" << pathName
421                     << " points outside your accessible address space."
422                     << exit(FatalError);
424                 return false;
425             }
427             case EACCES:
428             {
429                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
430                     << "The parent directory does not allow write "
431                        "permission to the process,"<< nl
432                     << "or one of the directories in " << pathName
433                     << " did not allow search (execute) permission."
434                     << exit(FatalError);
436                 return false;
437             }
439             case ENAMETOOLONG:
440             {
441                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
442                     << "" << pathName << " is too long."
443                     << exit(FatalError);
445                 return false;
446             }
448             case ENOENT:
449             {
450                 // Part of the path does not exist so try to create it
451                 if (pathName.path().size() && mkDir(pathName.path(), mode))
452                 {
453                     return mkDir(pathName, mode);
454                 }
455                 else
456                 {
457                     FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
458                         << "Couldn't create directory " << pathName
459                         << exit(FatalError);
461                     return false;
462                 }
463             }
465             case ENOTDIR:
466             {
467                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
468                     << "A component used as a directory in " << pathName
469                     << " is not, in fact, a directory."
470                     << exit(FatalError);
472                 return false;
473             }
475             case ENOMEM:
476             {
477                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
478                     << "Insufficient kernel memory was available to make "
479                        "directory " << pathName << '.'
480                     << exit(FatalError);
482                 return false;
483             }
485             case EROFS:
486             {
487                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
488                     << "" << pathName
489                     << " refers to a file on a read-only filesystem."
490                     << exit(FatalError);
492                 return false;
493             }
495             case ELOOP:
496             {
497                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
498                     << "Too many symbolic links were encountered in resolving "
499                     << pathName << '.'
500                     << exit(FatalError);
502                 return false;
503             }
505             case ENOSPC:
506             {
507                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
508                     << "The device containing " << pathName
509                     << " has no room for the new directory or "
510                     << "the user's disk quota is exhausted."
511                     << exit(FatalError);
513                 return false;
514             }
516             default:
517             {
518                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
519                     << "Couldn't create directory " << pathName
520                     << exit(FatalError);
522                 return false;
523             }
524         }
525     }
529 // Set the file mode
530 bool Foam::chMod(const fileName& name, const mode_t m)
532     return ::chmod(name.c_str(), m) == 0;
536 // Return the file mode
537 mode_t Foam::mode(const fileName& name)
539     fileStat fileStatus(name);
540     if (fileStatus.isValid())
541     {
542         return fileStatus.status().st_mode;
543     }
544     else
545     {
546         return 0;
547     }
551 // Return the file type: FILE or DIRECTORY
552 Foam::fileName::Type Foam::type(const fileName& name)
554     mode_t m = mode(name);
556     if (S_ISREG(m))
557     {
558         return fileName::FILE;
559     }
560     else if (S_ISDIR(m))
561     {
562         return fileName::DIRECTORY;
563     }
564     else
565     {
566         return fileName::UNDEFINED;
567     }
571 // Does the name exist in the filing system?
572 bool Foam::exists(const fileName& name, const bool checkGzip)
574     return mode(name) || isFile(name, checkGzip);
578 // Does the directory exist?
579 bool Foam::isDir(const fileName& name)
581     return S_ISDIR(mode(name));
585 // Does the file exist?
586 bool Foam::isFile(const fileName& name, const bool checkGzip)
588     return S_ISREG(mode(name)) || (checkGzip && S_ISREG(mode(name + ".gz")));
592 // Return size of file
593 off_t Foam::fileSize(const fileName& name)
595     fileStat fileStatus(name);
596     if (fileStatus.isValid())
597     {
598         return fileStatus.status().st_size;
599     }
600     else
601     {
602         return -1;
603     }
607 // Return time of last file modification
608 time_t Foam::lastModified(const fileName& name)
610     fileStat fileStatus(name);
611     if (fileStatus.isValid())
612     {
613         return fileStatus.status().st_mtime;
614     }
615     else
616     {
617         return 0;
618     }
622 // Read a directory and return the entries as a string list
623 Foam::fileNameList Foam::readDir
625     const fileName& directory,
626     const fileName::Type type,
627     const bool filtergz
630     // Initial filename list size
631     // also used as increment if initial size found to be insufficient
632     static const int maxNnames = 100;
634     if (POSIX::debug)
635     {
636         Info<< "readDir(const fileName&, const fileType, const bool filtergz)"
637             << " : reading directory " << directory << endl;
638     }
640     // Setup empty string list MAXTVALUES long
641     fileNameList dirEntries(maxNnames);
643     // Pointers to the directory entries
644     DIR *source;
645     struct dirent *list;
647     // Temporary variables and counters
648     label nEntries = 0;
650     // Attempt to open directory and set the structure pointer
651     if ((source = ::opendir(directory.c_str())) == NULL)
652     {
653         dirEntries.setSize(0);
655         if (POSIX::debug)
656         {
657             Info<< "readDir(const fileName&, const fileType, "
658                    "const bool filtergz) : cannot open directory "
659                 << directory << endl;
660         }
661     }
662     else
663     {
664         // Read and parse all the entries in the directory
665         while ((list = ::readdir(source)) != NULL)
666         {
667             fileName fName(list->d_name);
669             // ignore files begining with ., i.e. '.', '..' and '.*'
670             if (fName.size() && fName[0] != '.')
671             {
672                 word fExt = fName.ext();
674                 if
675                 (
676                     (type == fileName::DIRECTORY)
677                  ||
678                     (
679                         type == fileName::FILE
680                      && fName[fName.size()-1] != '~'
681                      && fExt != "bak"
682                      && fExt != "BAK"
683                      && fExt != "old"
684                      && fExt != "save"
685                     )
686                 )
687                 {
688                     if ((directory/fName).type() == type)
689                     {
690                         if (nEntries >= dirEntries.size())
691                         {
692                             dirEntries.setSize(dirEntries.size() + maxNnames);
693                         }
695                         if (filtergz && fExt == "gz")
696                         {
697                             dirEntries[nEntries++] = fName.lessExt();
698                         }
699                         else
700                         {
701                             dirEntries[nEntries++] = fName;
702                         }
703                     }
704                 }
705             }
706         }
708         // Reset the length of the entries list
709         dirEntries.setSize(nEntries);
711         ::closedir(source);
712     }
714     return dirEntries;
718 // Copy, recursively if necessary, the source to the destination
719 bool Foam::cp(const fileName& src, const fileName& dest)
721     // Make sure source exists.
722     if (!exists(src))
723     {
724         return false;
725     }
727     fileName destFile(dest);
729     // Check type of source file.
730     if (src.type() == fileName::FILE)
731     {
732         // If dest is a directory, create the destination file name.
733         if (destFile.type() == fileName::DIRECTORY)
734         {
735             destFile = destFile/src.name();
736         }
738         // Make sure the destination directory exists.
739         if (!isDir(destFile.path()) && !mkDir(destFile.path()))
740         {
741             return false;
742         }
744         // Open and check streams.
745         std::ifstream srcStream(src.c_str());
746         if (!srcStream)
747         {
748             return false;
749         }
751         std::ofstream destStream(destFile.c_str());
752         if (!destStream)
753         {
754             return false;
755         }
757         // Copy character data.
758         char ch;
759         while (srcStream.get(ch))
760         {
761             destStream.put(ch);
762         }
764         // Final check.
765         if (!srcStream.eof() || !destStream)
766         {
767             return false;
768         }
769     }
770     else if (src.type() == fileName::DIRECTORY)
771     {
772         // If dest is a directory, create the destination file name.
773         if (destFile.type() == fileName::DIRECTORY)
774         {
775             destFile = destFile/src.component(src.components().size() -1);
776         }
778         // Make sure the destination directory exists.
779         if (!isDir(destFile) && !mkDir(destFile))
780         {
781             return false;
782         }
784         // Copy files
785         fileNameList contents = readDir(src, fileName::FILE, false);
786         forAll(contents, i)
787         {
788             if (POSIX::debug)
789             {
790                 Info<< "Copying : " << src/contents[i]
791                     << " to " << destFile/contents[i] << endl;
792             }
794             // File to file.
795             cp(src/contents[i], destFile/contents[i]);
796         }
798         // Copy sub directories.
799         fileNameList subdirs = readDir(src, fileName::DIRECTORY);
800         forAll(subdirs, i)
801         {
802             if (POSIX::debug)
803             {
804                 Info<< "Copying : " << src/subdirs[i]
805                     << " to " << destFile << endl;
806             }
808             // Dir to Dir.
809             cp(src/subdirs[i], destFile);
810         }
811     }
813     return true;
817 // Create a softlink. dst should not exist. Returns true if successful.
818 bool Foam::ln(const fileName& src, const fileName& dst)
820     if (POSIX::debug)
821     {
822         Info<< "Create softlink from : " << src << " to " << dst
823             << endl;
824     }
826     if (exists(dst))
827     {
828         WarningIn("ln(const fileName&, const fileName&)")
829             << "destination " << dst << " already exists. Not linking."
830             << endl;
831         return false;
832     }
834     if (!exists(src))
835     {
836         WarningIn("ln(const fileName&, const fileName&)")
837             << "source " << src << " does not exist." << endl;
838         return false;
839     }
841     if (::symlink(src.c_str(), dst.c_str()) == 0)
842     {
843         return true;
844     }
845     else
846     {
847         WarningIn("ln(const fileName&, const fileName&)")
848             << "symlink from " << src << " to " << dst << " failed." << endl;
849         return false;
850     }
854 // Rename srcFile dstFile
855 bool Foam::mv(const fileName& src, const fileName& dst)
857     if (POSIX::debug)
858     {
859         Info<< "Move : " << src << " to " << dst << endl;
860     }
862     if
863     (
864         dst.type() == fileName::DIRECTORY
865      && src.type() != fileName::DIRECTORY
866     )
867     {
868         const fileName dstName(dst/src.name());
870         return ::rename(src.c_str(), dstName.c_str()) == 0;
871     }
872     else
873     {
874         return ::rename(src.c_str(), dst.c_str()) == 0;
875     }
879 //- Rename to a corresponding backup file
880 //  If the backup file already exists, attempt with "01" .. "99" index
881 bool Foam::mvBak(const fileName& src, const std::string& ext)
883     if (POSIX::debug)
884     {
885         Info<< "mvBak : " << src << " to extension " << ext << endl;
886     }
888     if (exists(src, false))
889     {
890         const int maxIndex = 99;
891         char index[3];
893         for (int n = 0; n <= maxIndex; n++)
894         {
895             fileName dstName(src + "." + ext);
896             if (n)
897             {
898                 sprintf(index, "%02d", n);
899                 dstName += index;
900             }
902             // avoid overwriting existing files, except for the last
903             // possible index where we have no choice
904             if (!exists(dstName, false) || n == maxIndex)
905             {
906                 return ::rename(src.c_str(), dstName.c_str()) == 0;
907             }
909         }
910     }
912     // fall-through: nothing to do
913     return false;
917 // Remove a file, returning true if successful otherwise false
918 bool Foam::rm(const fileName& file)
920     if (POSIX::debug)
921     {
922         Info<< "Removing : " << file << endl;
923     }
925     // Try returning plain file name; if not there, try with .gz
926     if (remove(file.c_str()) == 0)
927     {
928         return true;
929     }
930     else
931     {
932         return ::remove(string(file + ".gz").c_str()) == 0;
933     }
937 // Remove a dirctory and its contents
938 bool Foam::rmDir(const fileName& directory)
940     if (POSIX::debug)
941     {
942         Info<< "rmDir(const fileName&) : "
943             << "removing directory " << directory << endl;
944     }
946     // Pointers to the directory entries
947     DIR *source;
948     struct dirent *list;
950     // Attempt to open directory and set the structure pointer
951     if ((source = ::opendir(directory.c_str())) == NULL)
952     {
953         WarningIn("rmDir(const fileName&)")
954             << "cannot open directory " << directory << endl;
956         return false;
957     }
958     else
959     {
960         // Read and parse all the entries in the directory
961         while ((list = ::readdir(source)) != NULL)
962         {
963             fileName fName(list->d_name);
965             if (fName != "." && fName != "..")
966             {
967                 fileName path = directory/fName;
969                 if (path.type() == fileName::DIRECTORY)
970                 {
971                     if (!rmDir(path))
972                     {
973                         WarningIn("rmDir(const fileName&)")
974                             << "failed to remove directory " << fName
975                             << " while removing directory " << directory
976                             << endl;
978                         ::closedir(source);
980                         return false;
981                     }
982                 }
983                 else
984                 {
985                     if (!rm(path))
986                     {
987                         WarningIn("rmDir(const fileName&)")
988                             << "failed to remove file " << fName
989                             << " while removing directory " << directory
990                             << endl;
992                         ::closedir(source);
994                         return false;
995                     }
996                 }
997             }
999         }
1001         if (!rm(directory))
1002         {
1003             WarningIn("rmDir(const fileName&)")
1004                 << "failed to remove directory " << directory << endl;
1006             ::closedir(source);
1008             return false;
1009         }
1011         ::closedir(source);
1013         return true;
1014     }
1018 unsigned int Foam::sleep(const unsigned int s)
1020     return ::sleep(s);
1024 void Foam::fdClose(const int fd)
1026     if (close(fd) != 0)
1027     {
1028         FatalErrorIn
1029         (
1030             "fdClose(const int fd)"
1031         )   << "close error on " << fd << endl
1032             << abort(FatalError);
1033     }
1037 bool Foam::ping
1039     const word& destName,
1040     const label destPort,
1041     const label timeOut
1044     struct hostent *hostPtr;
1045     volatile int sockfd;
1046     struct sockaddr_in destAddr;      // will hold the destination addr
1047     u_int addr;
1049     if ((hostPtr = ::gethostbyname(destName.c_str())) == NULL)
1050     {
1051         FatalErrorIn
1052         (
1053             "Foam::ping(const word&, ...)"
1054         )   << "gethostbyname error " << h_errno << " for host " << destName
1055             << abort(FatalError);
1056     }
1058     // Get first of the SLL of addresses
1059     addr = (reinterpret_cast<struct in_addr*>(*(hostPtr->h_addr_list)))->s_addr;
1061     // Allocate socket
1062     sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1063     if (sockfd < 0)
1064     {
1065         FatalErrorIn
1066         (
1067             "Foam::ping(const word&, const label)"
1068         )   << "socket error"
1069             << abort(FatalError);
1070     }
1072     // Fill sockaddr_in structure with dest address and port
1073     memset(reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
1074     destAddr.sin_family = AF_INET;
1075     destAddr.sin_port = htons(ushort(destPort));
1076     destAddr.sin_addr.s_addr = addr;
1079     timer myTimer(timeOut);
1081     if (timedOut(myTimer))
1082     {
1083         // Setjmp from timer jumps back to here
1084         fdClose(sockfd);
1085         return false;
1086     }
1088     if
1089     (
1090         ::connect
1091         (
1092             sockfd,
1093             reinterpret_cast<struct sockaddr*>(&destAddr),
1094             sizeof(struct sockaddr)
1095         ) != 0
1096     )
1097     {
1098         // Connection refused. Check if network was actually used or not.
1100         int connectErr = errno;
1102         fdClose(sockfd);
1104         if (connectErr == ECONNREFUSED)
1105         {
1106             return true;
1107         }
1108         //perror("connect");
1110         return false;
1111     }
1113     fdClose(sockfd);
1115     return true;
1119 bool Foam::ping(const word& hostname, const label timeOut)
1121     return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
1125 int Foam::system(const std::string& command)
1127     return ::system(command.c_str());
1131 void* Foam::dlOpen(const fileName& lib, const bool check)
1133     if (POSIX::debug)
1134     {
1135         std::cout<< "dlOpen(const fileName&)"
1136             << " : dlopen of " << lib << std::endl;
1137     }
1138     void* handle = ::dlopen(lib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
1140     if (!handle && check)
1141     {
1142         WarningIn("dlOpen(const fileName&, const bool)")
1143             << "dlopen error : " << ::dlerror()
1144             << endl;
1145     }
1147     if (POSIX::debug)
1148     {
1149         std::cout
1150             << "dlOpen(const fileName&)"
1151             << " : dlopen of " << lib
1152             << " handle " << handle << std::endl;
1153     }
1155     return handle;
1159 bool Foam::dlClose(void* handle)
1161     if (POSIX::debug)
1162     {
1163         std::cout
1164             << "dlClose(void*)"
1165             << " : dlclose of handle " << handle << std::endl;
1166     }
1167     return ::dlclose(handle) == 0;
1171 void* Foam::dlSym(void* handle, const std::string& symbol)
1173     if (POSIX::debug)
1174     {
1175         std::cout
1176             << "dlSym(void*, const std::string&)"
1177             << " : dlsym of " << symbol << std::endl;
1178     }
1179     // clear any old errors - see manpage dlopen
1180     (void) ::dlerror();
1182     // get address of symbol
1183     void* fun = ::dlsym(handle, symbol.c_str());
1185     // find error (if any)
1186     char *error = ::dlerror();
1188     if (error)
1189     {
1190         WarningIn("dlSym(void*, const std::string&)")
1191             << "Cannot lookup symbol " << symbol << " : " << error
1192             << endl;
1193     }
1195     return fun;
1199 bool Foam::dlSymFound(void* handle, const std::string& symbol)
1201     if (handle && !symbol.empty())
1202     {
1203         if (POSIX::debug)
1204         {
1205             std::cout
1206                 << "dlSymFound(void*, const std::string&)"
1207                 << " : dlsym of " << symbol << std::endl;
1208         }
1210         // clear any old errors - see manpage dlopen
1211         (void) ::dlerror();
1213         // get address of symbol
1214         (void) ::dlsym(handle, symbol.c_str());
1216         // symbol can be found if there was no error
1217         return !::dlerror();
1218     }
1219     else
1220     {
1221         return false;
1222     }
1226 static int collectLibsCallback
1228     struct dl_phdr_info *info,
1229     size_t size,
1230     void *data
1233     Foam::DynamicList<Foam::fileName>* ptr =
1234         reinterpret_cast<Foam::DynamicList<Foam::fileName>*>(data);
1235     ptr->append(info->dlpi_name);
1236     return 0;
1240 Foam::fileNameList Foam::dlLoaded()
1242     DynamicList<fileName> libs;
1243     dl_iterate_phdr(collectLibsCallback, &libs);
1244     if (POSIX::debug)
1245     {
1246         std::cout
1247             << "dlLoaded()"
1248             << " : determined loaded libraries :" << libs.size() << std::endl;
1249     }
1250     return libs;
1254 void Foam::osRandomSeed(const label seed)
1256 #ifdef USE_RANDOM
1257     srandom((unsigned int)seed);
1258 #else
1259     srand48(seed);
1260 #endif
1264 Foam::label Foam::osRandomInteger()
1266 #ifdef USE_RANDOM
1267     return random();
1268 #else
1269     return lrand48();
1270 #endif
1274 Foam::scalar Foam::osRandomDouble()
1276 #ifdef USE_RANDOM
1277     return (scalar)random()/INT_MAX;
1278 #else
1279     return drand48();
1280 #endif
1284 // ************************************************************************* //