Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OSspecific / POSIX / POSIX.C
blob48e4b3a4dfe05fb0dca7ddc19053b3aaff0e075e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2011 OpenCFD Ltd.
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 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
62 defineTypeNameAndDebug(Foam::POSIX, 0);
64 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66 pid_t Foam::pid()
68     return ::getpid();
71 pid_t Foam::ppid()
73     return ::getppid();
76 pid_t Foam::pgid()
78     return ::getpgrp();
81 bool Foam::env(const word& envName)
83     return ::getenv(envName.c_str()) != NULL;
87 Foam::string Foam::getEnv(const word& envName)
89     char* env = ::getenv(envName.c_str());
91     if (env)
92     {
93         return string(env);
94     }
95     else
96     {
97         // Return null-constructed string rather than string::null
98         // to avoid cyclic dependencies in the construction of globals
99         return string();
100     }
104 bool Foam::setEnv
106     const word& envName,
107     const std::string& value,
108     const bool overwrite
111     return setenv(envName.c_str(), value.c_str(), overwrite) == 0;
115 Foam::word Foam::hostName(bool full)
117     char buf[128];
118     ::gethostname(buf, sizeof(buf));
120     // implementation as per hostname from net-tools
121     if (full)
122     {
123         struct hostent *hp = ::gethostbyname(buf);
124         if (hp)
125         {
126             return hp->h_name;
127         }
128     }
130     return buf;
134 Foam::word Foam::domainName()
136     char buf[128];
137     ::gethostname(buf, sizeof(buf));
139     // implementation as per hostname from net-tools
140     struct hostent *hp = ::gethostbyname(buf);
141     if (hp)
142     {
143         char *p = ::strchr(hp->h_name, '.');
144         if (p)
145         {
146             ++p;
147             return p;
148         }
149     }
151     return word::null;
155 Foam::word Foam::userName()
157     struct passwd* pw = ::getpwuid(::getuid());
159     if (pw != NULL)
160     {
161         return pw->pw_name;
162     }
163     else
164     {
165         return word::null;
166     }
170 bool Foam::isAdministrator()
172     return (::geteuid() == 0);
176 // use $HOME environment variable or passwd info
177 Foam::fileName Foam::home()
179     char* env = ::getenv("HOME");
181     if (env != NULL)
182     {
183         return fileName(env);
184     }
185     else
186     {
187         struct passwd* pw = ::getpwuid(getuid());
189         if (pw != NULL)
190         {
191             return pw->pw_dir;
192         }
193         else
194         {
195             return fileName::null;
196         }
197     }
201 Foam::fileName Foam::home(const word& userName)
203     struct passwd* pw;
205     if (userName.size())
206     {
207         pw = ::getpwnam(userName.c_str());
208     }
209     else
210     {
211         char* env = ::getenv("HOME");
213         if (env != NULL)
214         {
215             return fileName(env);
216         }
218         pw = ::getpwuid(::getuid());
219     }
221     if (pw != NULL)
222     {
223         return pw->pw_dir;
224     }
225     else
226     {
227         return fileName::null;
228     }
232 Foam::fileName Foam::cwd()
234     char buf[256];
235     if (::getcwd(buf, sizeof(buf)))
236     {
237         return buf;
238     }
239     else
240     {
241         FatalErrorIn("Foam::cwd()")
242             << "Couldn't get the current working directory"
243             << exit(FatalError);
245         return fileName::null;
246     }
250 bool Foam::chDir(const fileName& dir)
252     return ::chdir(dir.c_str()) == 0;
256 Foam::fileName Foam::findEtcFile(const fileName& name, bool mandatory)
258     //
259     // search for user files in
260     // * ~/.OpenFOAM/VERSION
261     // * ~/.OpenFOAM
262     //
263     fileName searchDir = home()/".OpenFOAM";
264     if (isDir(searchDir))
265     {
266         fileName fullName = searchDir/FOAMversion/name;
267         if (isFile(fullName))
268         {
269             return fullName;
270         }
272         fullName = searchDir/name;
273         if (isFile(fullName))
274         {
275             return fullName;
276         }
277     }
280     //
281     // search for group (site) files in
282     // * $WM_PROJECT_SITE/VERSION
283     // * $WM_PROJECT_SITE
284     //
285     searchDir = getEnv("WM_PROJECT_SITE");
286     if (searchDir.size())
287     {
288         if (isDir(searchDir))
289         {
290             fileName fullName = searchDir/FOAMversion/name;
291             if (isFile(fullName))
292             {
293                 return fullName;
294             }
296             fullName = searchDir/name;
297             if (isFile(fullName))
298             {
299                 return fullName;
300             }
301         }
302     }
303     else
304     {
305         //
306         // OR search for group (site) files in
307         // * $WM_PROJECT_INST_DIR/site/VERSION
308         // * $WM_PROJECT_INST_DIR/site
309         //
310         searchDir = getEnv("WM_PROJECT_INST_DIR");
311         if (isDir(searchDir))
312         {
313             fileName fullName = searchDir/"site"/FOAMversion/name;
314             if (isFile(fullName))
315             {
316                 return fullName;
317             }
319             fullName = searchDir/"site"/name;
320             if (isFile(fullName))
321             {
322                 return fullName;
323             }
324         }
325     }
328     //
329     // search for other (shipped) files in
330     // * $WM_PROJECT_DIR/etc
331     //
332     searchDir = getEnv("WM_PROJECT_DIR");
333     if (isDir(searchDir))
334     {
335         fileName fullName = searchDir/"etc"/name;
336         if (isFile(fullName))
337         {
338             return fullName;
339         }
340     }
342     // Not found
343     // abort if the file is mandatory, otherwise return null
344     if (mandatory)
345     {
346         std::cerr
347             << "--> FOAM FATAL ERROR in Foam::findEtcFile() :"
348                " could not find mandatory file\n    '"
349             << name.c_str() << "'\n\n" << std::endl;
350         ::exit(1);
351     }
353     // Return null-constructed fileName rather than fileName::null
354     // to avoid cyclic dependencies in the construction of globals
355     return fileName();
359 bool Foam::mkDir(const fileName& pathName, mode_t mode)
361     // empty names are meaningless
362     if (pathName.empty())
363     {
364         return false;
365     }
367     // Construct instance path directory if does not exist
368     if (::mkdir(pathName.c_str(), mode) == 0)
369     {
370         // Directory made OK so return true
371         return true;
372     }
373     else
374     {
375         switch (errno)
376         {
377             case EPERM:
378             {
379                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
380                     << "The filesystem containing " << pathName
381                     << " does not support the creation of directories."
382                     << exit(FatalError);
384                 return false;
385             }
387             case EEXIST:
388             {
389                 // Directory already exists so simply return true
390                 return true;
391             }
393             case EFAULT:
394             {
395                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
396                     << "" << pathName
397                     << " points outside your accessible address space."
398                     << exit(FatalError);
400                 return false;
401             }
403             case EACCES:
404             {
405                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
406                     << "The parent directory does not allow write "
407                        "permission to the process,"<< nl
408                     << "or one of the directories in " << pathName
409                     << " did not allow search (execute) permission."
410                     << exit(FatalError);
412                 return false;
413             }
415             case ENAMETOOLONG:
416             {
417                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
418                     << "" << pathName << " is too long."
419                     << exit(FatalError);
421                 return false;
422             }
424             case ENOENT:
425             {
426                 // Part of the path does not exist so try to create it
427                 if (pathName.path().size() && mkDir(pathName.path(), mode))
428                 {
429                     return mkDir(pathName, mode);
430                 }
431                 else
432                 {
433                     FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
434                         << "Couldn't create directory " << pathName
435                         << exit(FatalError);
437                     return false;
438                 }
439             }
441             case ENOTDIR:
442             {
443                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
444                     << "A component used as a directory in " << pathName
445                     << " is not, in fact, a directory."
446                     << exit(FatalError);
448                 return false;
449             }
451             case ENOMEM:
452             {
453                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
454                     << "Insufficient kernel memory was available to make "
455                        "directory " << pathName << '.'
456                     << exit(FatalError);
458                 return false;
459             }
461             case EROFS:
462             {
463                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
464                     << "" << pathName
465                     << " refers to a file on a read-only filesystem."
466                     << exit(FatalError);
468                 return false;
469             }
471             case ELOOP:
472             {
473                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
474                     << "Too many symbolic links were encountered in resolving "
475                     << pathName << '.'
476                     << exit(FatalError);
478                 return false;
479             }
481             case ENOSPC:
482             {
483                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
484                     << "The device containing " << pathName
485                     << " has no room for the new directory or "
486                     << "the user's disk quota is exhausted."
487                     << exit(FatalError);
489                 return false;
490             }
492             default:
493             {
494                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
495                     << "Couldn't create directory " << pathName
496                     << exit(FatalError);
498                 return false;
499             }
500         }
501     }
505 // Set the file mode
506 bool Foam::chMod(const fileName& name, const mode_t m)
508     return ::chmod(name.c_str(), m) == 0;
512 // Return the file mode
513 mode_t Foam::mode(const fileName& name)
515     fileStat fileStatus(name);
516     if (fileStatus.isValid())
517     {
518         return fileStatus.status().st_mode;
519     }
520     else
521     {
522         return 0;
523     }
527 // Return the file type: FILE or DIRECTORY
528 Foam::fileName::Type Foam::type(const fileName& name)
530     mode_t m = mode(name);
532     if (S_ISREG(m))
533     {
534         return fileName::FILE;
535     }
536     else if (S_ISDIR(m))
537     {
538         return fileName::DIRECTORY;
539     }
540     else
541     {
542         return fileName::UNDEFINED;
543     }
547 // Does the name exist in the filing system?
548 bool Foam::exists(const fileName& name, const bool checkGzip)
550     return mode(name) || isFile(name, checkGzip);
554 // Does the directory exist?
555 bool Foam::isDir(const fileName& name)
557     return S_ISDIR(mode(name));
561 // Does the file exist?
562 bool Foam::isFile(const fileName& name, const bool checkGzip)
564     return S_ISREG(mode(name)) || (checkGzip && S_ISREG(mode(name + ".gz")));
568 // Return size of file
569 off_t Foam::fileSize(const fileName& name)
571     fileStat fileStatus(name);
572     if (fileStatus.isValid())
573     {
574         return fileStatus.status().st_size;
575     }
576     else
577     {
578         return -1;
579     }
583 // Return time of last file modification
584 time_t Foam::lastModified(const fileName& name)
586     fileStat fileStatus(name);
587     if (fileStatus.isValid())
588     {
589         return fileStatus.status().st_mtime;
590     }
591     else
592     {
593         return 0;
594     }
598 // Read a directory and return the entries as a string list
599 Foam::fileNameList Foam::readDir
601     const fileName& directory,
602     const fileName::Type type,
603     const bool filtergz
606     // Initial filename list size
607     // also used as increment if initial size found to be insufficient
608     static const int maxNnames = 100;
610     if (POSIX::debug)
611     {
612         Info<< "readDir(const fileName&, const fileType, const bool filtergz)"
613             << " : reading directory " << directory << endl;
614     }
616     // Setup empty string list MAXTVALUES long
617     fileNameList dirEntries(maxNnames);
619     // Pointers to the directory entries
620     DIR *source;
621     struct dirent *list;
623     // Temporary variables and counters
624     label nEntries = 0;
626     // Attempt to open directory and set the structure pointer
627     if ((source = ::opendir(directory.c_str())) == NULL)
628     {
629         dirEntries.setSize(0);
631         if (POSIX::debug)
632         {
633             Info<< "readDir(const fileName&, const fileType, "
634                    "const bool filtergz) : cannot open directory "
635                 << directory << endl;
636         }
637     }
638     else
639     {
640         // Read and parse all the entries in the directory
641         while ((list = ::readdir(source)) != NULL)
642         {
643             fileName fName(list->d_name);
645             // ignore files begining with ., i.e. '.', '..' and '.*'
646             if (fName.size() && fName[0] != '.')
647             {
648                 word fExt = fName.ext();
650                 if
651                 (
652                     (type == fileName::DIRECTORY)
653                  ||
654                     (
655                         type == fileName::FILE
656                      && fName[fName.size()-1] != '~'
657                      && fExt != "bak"
658                      && fExt != "BAK"
659                      && fExt != "old"
660                      && fExt != "save"
661                     )
662                 )
663                 {
664                     if ((directory/fName).type() == type)
665                     {
666                         if (nEntries >= dirEntries.size())
667                         {
668                             dirEntries.setSize(dirEntries.size() + maxNnames);
669                         }
671                         if (filtergz && fExt == "gz")
672                         {
673                             dirEntries[nEntries++] = fName.lessExt();
674                         }
675                         else
676                         {
677                             dirEntries[nEntries++] = fName;
678                         }
679                     }
680                 }
681             }
682         }
684         // Reset the length of the entries list
685         dirEntries.setSize(nEntries);
687         ::closedir(source);
688     }
690     return dirEntries;
694 // Copy, recursively if necessary, the source to the destination
695 bool Foam::cp(const fileName& src, const fileName& dest)
697     // Make sure source exists.
698     if (!exists(src))
699     {
700         return false;
701     }
703     fileName destFile(dest);
705     // Check type of source file.
706     if (src.type() == fileName::FILE)
707     {
708         // If dest is a directory, create the destination file name.
709         if (destFile.type() == fileName::DIRECTORY)
710         {
711             destFile = destFile/src.name();
712         }
714         // Make sure the destination directory exists.
715         if (!isDir(destFile.path()) && !mkDir(destFile.path()))
716         {
717             return false;
718         }
720         // Open and check streams.
721         std::ifstream srcStream(src.c_str());
722         if (!srcStream)
723         {
724             return false;
725         }
727         std::ofstream destStream(destFile.c_str());
728         if (!destStream)
729         {
730             return false;
731         }
733         // Copy character data.
734         char ch;
735         while (srcStream.get(ch))
736         {
737             destStream.put(ch);
738         }
740         // Final check.
741         if (!srcStream.eof() || !destStream)
742         {
743             return false;
744         }
745     }
746     else if (src.type() == fileName::DIRECTORY)
747     {
748         // If dest is a directory, create the destination file name.
749         if (destFile.type() == fileName::DIRECTORY)
750         {
751             destFile = destFile/src.component(src.components().size() -1);
752         }
754         // Make sure the destination directory exists.
755         if (!isDir(destFile) && !mkDir(destFile))
756         {
757             return false;
758         }
760         // Copy files
761         fileNameList contents = readDir(src, fileName::FILE, false);
762         forAll(contents, i)
763         {
764             if (POSIX::debug)
765             {
766                 Info<< "Copying : " << src/contents[i]
767                     << " to " << destFile/contents[i] << endl;
768             }
770             // File to file.
771             cp(src/contents[i], destFile/contents[i]);
772         }
774         // Copy sub directories.
775         fileNameList subdirs = readDir(src, fileName::DIRECTORY);
776         forAll(subdirs, i)
777         {
778             if (POSIX::debug)
779             {
780                 Info<< "Copying : " << src/subdirs[i]
781                     << " to " << destFile << endl;
782             }
784             // Dir to Dir.
785             cp(src/subdirs[i], destFile);
786         }
787     }
789     return true;
793 // Create a softlink. dst should not exist. Returns true if successful.
794 bool Foam::ln(const fileName& src, const fileName& dst)
796     if (POSIX::debug)
797     {
798         Info<< "Create softlink from : " << src << " to " << dst
799             << endl;
800     }
802     if (exists(dst))
803     {
804         WarningIn("ln(const fileName&, const fileName&)")
805             << "destination " << dst << " already exists. Not linking."
806             << endl;
807         return false;
808     }
810     if (!exists(src))
811     {
812         WarningIn("ln(const fileName&, const fileName&)")
813             << "source " << src << " does not exist." << endl;
814         return false;
815     }
817     if (::symlink(src.c_str(), dst.c_str()) == 0)
818     {
819         return true;
820     }
821     else
822     {
823         WarningIn("ln(const fileName&, const fileName&)")
824             << "symlink from " << src << " to " << dst << " failed." << endl;
825         return false;
826     }
830 // Rename srcFile dstFile
831 bool Foam::mv(const fileName& src, const fileName& dst)
833     if (POSIX::debug)
834     {
835         Info<< "Move : " << src << " to " << dst << endl;
836     }
838     if
839     (
840         dst.type() == fileName::DIRECTORY
841      && src.type() != fileName::DIRECTORY
842     )
843     {
844         const fileName dstName(dst/src.name());
846         return ::rename(src.c_str(), dstName.c_str()) == 0;
847     }
848     else
849     {
850         return ::rename(src.c_str(), dst.c_str()) == 0;
851     }
855 //- Rename to a corresponding backup file
856 //  If the backup file already exists, attempt with "01" .. "99" index
857 bool Foam::mvBak(const fileName& src, const std::string& ext)
859     if (POSIX::debug)
860     {
861         Info<< "mvBak : " << src << " to extension " << ext << endl;
862     }
864     if (exists(src, false))
865     {
866         const int maxIndex = 99;
867         char index[3];
869         for (int n = 0; n <= maxIndex; n++)
870         {
871             fileName dstName(src + "." + ext);
872             if (n)
873             {
874                 sprintf(index, "%02d", n);
875                 dstName += index;
876             }
878             // avoid overwriting existing files, except for the last
879             // possible index where we have no choice
880             if (!exists(dstName, false) || n == maxIndex)
881             {
882                 return ::rename(src.c_str(), dstName.c_str()) == 0;
883             }
885         }
886     }
888     // fall-through: nothing to do
889     return false;
894 // Remove a file, returning true if successful otherwise false
895 bool Foam::rm(const fileName& file)
897     if (POSIX::debug)
898     {
899         Info<< "Removing : " << file << endl;
900     }
902     // Try returning plain file name; if not there, try with .gz
903     if (remove(file.c_str()) == 0)
904     {
905         return true;
906     }
907     else
908     {
909         return ::remove(string(file + ".gz").c_str()) == 0;
910     }
914 // Remove a dirctory and its contents
915 bool Foam::rmDir(const fileName& directory)
917     if (POSIX::debug)
918     {
919         Info<< "rmDir(const fileName&) : "
920             << "removing directory " << directory << endl;
921     }
923     // Pointers to the directory entries
924     DIR *source;
925     struct dirent *list;
927     // Attempt to open directory and set the structure pointer
928     if ((source = ::opendir(directory.c_str())) == NULL)
929     {
930         WarningIn("rmDir(const fileName&)")
931             << "cannot open directory " << directory << endl;
933         return false;
934     }
935     else
936     {
937         // Read and parse all the entries in the directory
938         while ((list = ::readdir(source)) != NULL)
939         {
940             fileName fName(list->d_name);
942             if (fName != "." && fName != "..")
943             {
944                 fileName path = directory/fName;
946                 if (path.type() == fileName::DIRECTORY)
947                 {
948                     if (!rmDir(path))
949                     {
950                         WarningIn("rmDir(const fileName&)")
951                             << "failed to remove directory " << fName
952                             << " while removing directory " << directory
953                             << endl;
955                         ::closedir(source);
957                         return false;
958                     }
959                 }
960                 else
961                 {
962                     if (!rm(path))
963                     {
964                         WarningIn("rmDir(const fileName&)")
965                             << "failed to remove file " << fName
966                             << " while removing directory " << directory
967                             << endl;
969                         ::closedir(source);
971                         return false;
972                     }
973                 }
974             }
976         }
978         if (!rm(directory))
979         {
980             WarningIn("rmDir(const fileName&)")
981                 << "failed to remove directory " << directory << endl;
983             ::closedir(source);
985             return false;
986         }
988         ::closedir(source);
990         return true;
991     }
995 unsigned int Foam::sleep(const unsigned int s)
997     return ::sleep(s);
1001 void Foam::fdClose(const int fd)
1003     if (close(fd) != 0)
1004     {
1005         FatalErrorIn
1006         (
1007             "fdClose(const int fd)"
1008         )   << "close error on " << fd << endl
1009             << abort(FatalError);
1010     }
1014 bool Foam::ping
1016     const word& destName,
1017     const label destPort,
1018     const label timeOut
1021     struct hostent *hostPtr;
1022     volatile int sockfd;
1023     struct sockaddr_in destAddr;      // will hold the destination addr
1024     u_int addr;
1026     if ((hostPtr = ::gethostbyname(destName.c_str())) == NULL)
1027     {
1028         FatalErrorIn
1029         (
1030             "Foam::ping(const word&, ...)"
1031         )   << "gethostbyname error " << h_errno << " for host " << destName
1032             << abort(FatalError);
1033     }
1035     // Get first of the SLL of addresses
1036     addr = (reinterpret_cast<struct in_addr*>(*(hostPtr->h_addr_list)))->s_addr;
1038     // Allocate socket
1039     sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
1040     if (sockfd < 0)
1041     {
1042         FatalErrorIn
1043         (
1044             "Foam::ping(const word&, const label)"
1045         )   << "socket error"
1046             << abort(FatalError);
1047     }
1049     // Fill sockaddr_in structure with dest address and port
1050     memset(reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
1051     destAddr.sin_family = AF_INET;
1052     destAddr.sin_port = htons(ushort(destPort));
1053     destAddr.sin_addr.s_addr = addr;
1056     timer myTimer(timeOut);
1058     if (timedOut(myTimer))
1059     {
1060         // Setjmp from timer jumps back to here
1061         fdClose(sockfd);
1062         return false;
1063     }
1065     if
1066     (
1067         ::connect
1068         (
1069             sockfd,
1070             reinterpret_cast<struct sockaddr*>(&destAddr),
1071             sizeof(struct sockaddr)
1072         ) != 0
1073     )
1074     {
1075         // Connection refused. Check if network was actually used or not.
1077         int connectErr = errno;
1079         fdClose(sockfd);
1081         if (connectErr == ECONNREFUSED)
1082         {
1083             return true;
1084         }
1085         //perror("connect");
1087         return false;
1088     }
1090     fdClose(sockfd);
1092     return true;
1096 bool Foam::ping(const word& hostname, const label timeOut)
1098     return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
1102 int Foam::system(const std::string& command)
1104     return ::system(command.c_str());
1108 void* Foam::dlOpen(const fileName& lib)
1110     if (POSIX::debug)
1111     {
1112         std::cout<< "dlOpen(const fileName&)"
1113             << " : dlopen of " << lib << std::endl;
1114     }
1115     void* handle = ::dlopen(lib.c_str(), RTLD_LAZY|RTLD_GLOBAL);
1117     if (POSIX::debug)
1118     {
1119         std::cout
1120             << "dlOpen(const fileName&)"
1121             << " : dlopen of " << lib
1122             << " handle " << handle << std::endl;
1123     }
1125     return handle;
1129 bool Foam::dlClose(void* handle)
1131     if (POSIX::debug)
1132     {
1133         std::cout
1134             << "dlClose(void*)"
1135             << " : dlclose of handle " << handle << std::endl;
1136     }
1137     return ::dlclose(handle) == 0;
1141 void* Foam::dlSym(void* handle, const std::string& symbol)
1143     if (POSIX::debug)
1144     {
1145         std::cout
1146             << "dlSym(void*, const std::string&)"
1147             << " : dlsym of " << symbol << std::endl;
1148     }
1149     // clear any old errors - see manpage dlopen
1150     (void) ::dlerror();
1152     // get address of symbol
1153     void* fun = ::dlsym(handle, symbol.c_str());
1155     // find error (if any)
1156     char *error = ::dlerror();
1158     if (error)
1159     {
1160         WarningIn("dlSym(void*, const std::string&)")
1161             << "Cannot lookup symbol " << symbol << " : " << error
1162             << endl;
1163     }
1165     return fun;
1169 bool Foam::dlSymFound(void* handle, const std::string& symbol)
1171     if (handle && !symbol.empty())
1172     {
1173         if (POSIX::debug)
1174         {
1175             std::cout
1176                 << "dlSymFound(void*, const std::string&)"
1177                 << " : dlsym of " << symbol << std::endl;
1178         }
1180         // clear any old errors - see manpage dlopen
1181         (void) ::dlerror();
1183         // get address of symbol
1184         (void) ::dlsym(handle, symbol.c_str());
1186         // symbol can be found if there was no error
1187         return !::dlerror();
1188     }
1189     else
1190     {
1191         return false;
1192     }
1196 static int collectLibsCallback
1198     struct dl_phdr_info *info,
1199     size_t size,
1200     void *data
1203     Foam::DynamicList<Foam::fileName>* ptr =
1204         reinterpret_cast<Foam::DynamicList<Foam::fileName>*>(data);
1205     ptr->append(info->dlpi_name);
1206     return 0;
1210 Foam::fileNameList Foam::dlLoaded()
1212     DynamicList<fileName> libs;
1213     dl_iterate_phdr(collectLibsCallback, &libs);
1214     if (POSIX::debug)
1215     {
1216         std::cout
1217             << "dlLoaded()"
1218             << " : determined loaded libraries :" << libs.size() << std::endl;
1219     }
1220     return libs;
1224 // ************************************************************************* //