FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

POSIX.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025     POSIX versions of the functions declared in OSspecific.H
00026 
00027 \*---------------------------------------------------------------------------*/
00028 
00029 #ifdef solarisGcc
00030 # define _SYS_VNODE_H
00031 #endif
00032 
00033 #include <OpenFOAM/OSspecific.H>
00034 #include "POSIX.H"
00035 #include <OpenFOAM/foamVersion.H>
00036 #include <OpenFOAM/fileName.H>
00037 #include "fileStat.H"
00038 #include "timer.H"
00039 
00040 #include <fstream>
00041 #include <cstdlib>
00042 #include <cctype>
00043 
00044 #include <stdio.h>
00045 #include <unistd.h>
00046 #include <dirent.h>
00047 #include <pwd.h>
00048 #include <errno.h>
00049 #include <sys/types.h>
00050 #include <sys/stat.h>
00051 #include <sys/socket.h>
00052 #include <netdb.h>
00053 
00054 #include <netinet/in.h>
00055 
00056 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00057 
00058 defineTypeNameAndDebug(Foam::POSIX, 0);
00059 
00060 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00061 
00062 pid_t Foam::pid()
00063 {
00064     return getpid();
00065 }
00066 
00067 pid_t Foam::ppid()
00068 {
00069     return getppid();
00070 }
00071 
00072 pid_t Foam::pgid()
00073 {
00074     return getpgrp();
00075 }
00076 
00077 bool Foam::env(const word& envName)
00078 {
00079     return getenv(envName.c_str()) != NULL;
00080 }
00081 
00082 
00083 Foam::string Foam::getEnv(const word& envName)
00084 {
00085     char* env = getenv(envName.c_str());
00086 
00087     if (env)
00088     {
00089         return string(env);
00090     }
00091     else
00092     {
00093         // Return null-constructed string rather than string::null
00094         // to avoid cyclic dependencies in the construction of globals
00095         return string();
00096     }
00097 }
00098 
00099 
00100 bool Foam::setEnv
00101 (
00102     const word& envName,
00103     const string& value,
00104     const bool overwrite
00105 )
00106 {
00107     return setenv(envName.c_str(), value.c_str(), overwrite) == 0;
00108 }
00109 
00110 
00111 Foam::word Foam::hostName()
00112 {
00113     char buffer[256];
00114     gethostname(buffer, 256);
00115 
00116     return buffer;
00117 }
00118 
00119 
00120 Foam::word Foam::userName()
00121 {
00122     struct passwd* pw = getpwuid(getuid());
00123 
00124     if (pw != NULL)
00125     {
00126         return pw->pw_name;
00127     }
00128     else
00129     {
00130         return word::null;
00131     }
00132 }
00133 
00134 
00135 // use $HOME environment variable or passwd info
00136 Foam::fileName Foam::home()
00137 {
00138     char* env = getenv("HOME");
00139 
00140     if (env != NULL)
00141     {
00142         return fileName(env);
00143     }
00144     else
00145     {
00146         struct passwd* pw = getpwuid(getuid());
00147 
00148         if (pw != NULL)
00149         {
00150             return pw->pw_dir;
00151         }
00152         else
00153         {
00154             return fileName::null;
00155         }
00156     }
00157 }
00158 
00159 
00160 Foam::fileName Foam::home(const word& userName)
00161 {
00162     struct passwd* pw;
00163 
00164     if (userName.size())
00165     {
00166         pw = getpwnam(userName.c_str());
00167     }
00168     else
00169     {
00170         char* env = getenv("HOME");
00171 
00172         if (env != NULL)
00173         {
00174             return fileName(env);
00175         }
00176 
00177         pw = getpwuid(getuid());
00178     }
00179 
00180     if (pw != NULL)
00181     {
00182         return pw->pw_dir;
00183     }
00184     else
00185     {
00186         return fileName::null;
00187     }
00188 }
00189 
00190 
00191 Foam::fileName Foam::cwd()
00192 {
00193     char buf[255];
00194     if (getcwd(buf, 255))
00195     {
00196         return buf;
00197     }
00198     else
00199     {
00200         FatalErrorIn("Foam::cwd()")
00201             << "Couldn't get the current working directory"
00202             << exit(FatalError);
00203 
00204         return fileName::null;
00205     }
00206 }
00207 
00208 
00209 bool Foam::chDir(const fileName& dir)
00210 {
00211     return chdir(dir.c_str()) != 0;
00212 }
00213 
00214 
00215 Foam::fileName Foam::findEtcFile(const fileName& name, bool mandatory)
00216 {
00217     /* New search strategy:
00218      *  - first search in FREEFOAM_CONFIG_DIR
00219      *  - then in the users directory
00220      *  - finally in the ${FOAM_INSTALL_CONFIG_PATH}
00221      */
00222 
00223     // Search installation files:
00224     // ~~~~~~~~~~~~~~~~~~~~~~~~~~
00225     fileName searchDir;
00226     if(env("FREEFOAM_CONFIG_DIR"))
00227     {
00228         searchDir = getEnv("FREEFOAM_CONFIG_DIR");
00229     }
00230     if (isDir(searchDir))
00231     {
00232         // Check for shipped FreeFOAM file in $FREEFOAM_CONFIG_DIR
00233         fileName fullName = searchDir/name;
00234         if (isFile(fullName))
00235         {
00236             return fullName;
00237         }
00238     }
00239 
00240     // Search user files:
00241     // ~~~~~~~~~~~~~~~~~~
00242     searchDir = home()/".FreeFOAM";
00243     if (isDir(searchDir))
00244     {
00245         // Check for user file in ~/.FreeFOAM/VERSION
00246         fileName fullName = searchDir/FOAMversion/name;
00247         if (isFile(fullName))
00248         {
00249             return fullName;
00250         }
00251 
00252         // Check for version-independent user file in ~/.FreeFOAM
00253         fullName = searchDir/name;
00254         if (isFile(fullName))
00255         {
00256             return fullName;
00257         }
00258     }
00259 
00260     // Search installed config directory
00261     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00262     searchDir = FOAMConfigDir;
00263     if (isDir(searchDir))
00264     {
00265         // Check for installed FreeFOAM file in FOAMConfigDir
00266         fileName fullName = searchDir/name;
00267         if (isFile(fullName))
00268         {
00269             return fullName;
00270         }
00271     }
00272 
00273     // Not found
00274     // abort if the file is mandatory, otherwise return null
00275     if (mandatory)
00276     {
00277         cerr<< "--> FOAM FATAL ERROR in Foam::findEtcFile() :"
00278                " could not find mandatory file\n    '"
00279             << name.c_str() << "'\n\n" << std::endl;
00280         ::exit(1);
00281     }
00282 
00283     // Return null-constructed fileName rather than fileName::null
00284     // to avoid cyclic dependencies in the construction of globals
00285     return fileName();
00286 }
00287 
00288 
00289 bool Foam::mkDir(const fileName& pathName, mode_t mode)
00290 {
00291     // empty names are meaningless
00292     if (pathName.empty())
00293     {
00294         return false;
00295     }
00296 
00297     // Construct instance path directory if does not exist
00298     if (::mkdir(pathName.c_str(), mode) == 0)
00299     {
00300         // Directory made OK so return true
00301         return true;
00302     }
00303     else
00304     {
00305         switch (errno)
00306         {
00307             case EPERM:
00308             {
00309                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00310                     << "The filesystem containing " << pathName
00311                     << " does not support the creation of directories."
00312                     << exit(FatalError);
00313 
00314                 return false;
00315             }
00316 
00317             case EEXIST:
00318             {
00319                 // Directory already exists so simply return true
00320                 return true;
00321             }
00322 
00323             case EFAULT:
00324             {
00325                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00326                     << "" << pathName
00327                     << " points outside your accessible address space."
00328                     << exit(FatalError);
00329 
00330                 return false;
00331             }
00332 
00333             case EACCES:
00334             {
00335                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00336                     << "The parent directory does not allow write "
00337                        "permission to the process,"<< nl
00338                     << "or one of the directories in " << pathName
00339                     << " did not allow search (execute) permission."
00340                     << exit(FatalError);
00341 
00342                 return false;
00343             }
00344 
00345             case ENAMETOOLONG:
00346             {
00347                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00348                     << "" << pathName << " is too long."
00349                     << exit(FatalError);
00350 
00351                 return false;
00352             }
00353 
00354             case ENOENT:
00355             {
00356                 // Part of the path does not exist so try to create it
00357                 if (pathName.path().size() && mkDir(pathName.path(), mode))
00358                 {
00359                     return mkDir(pathName, mode);
00360                 }
00361                 else
00362                 {
00363                     FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00364                         << "Couldn't create directory " << pathName
00365                         << exit(FatalError);
00366 
00367                     return false;
00368                 }
00369             }
00370 
00371             case ENOTDIR:
00372             {
00373                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00374                     << "A component used as a directory in " << pathName
00375                     << " is not, in fact, a directory."
00376                     << exit(FatalError);
00377 
00378                 return false;
00379             }
00380 
00381             case ENOMEM:
00382             {
00383                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00384                     << "Insufficient kernel memory was available to make "
00385                        "directory " << pathName << '.'
00386                     << exit(FatalError);
00387 
00388                 return false;
00389             }
00390 
00391             case EROFS:
00392             {
00393                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00394                     << "" << pathName
00395                     << " refers to a file on a read-only filesystem."
00396                     << exit(FatalError);
00397 
00398                 return false;
00399             }
00400 
00401             case ELOOP:
00402             {
00403                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00404                     << "Too many symbolic links were encountered in resolving "
00405                     << pathName << '.'
00406                     << exit(FatalError);
00407 
00408                 return false;
00409             }
00410 
00411             case ENOSPC:
00412             {
00413                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00414                     << "The device containing " << pathName
00415                     << " has no room for the new directory or "
00416                     << "the user's disk quota is exhausted."
00417                     << exit(FatalError);
00418 
00419                 return false;
00420             }
00421 
00422             default:
00423             {
00424                 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00425                     << "Couldn't create directory " << pathName
00426                     << exit(FatalError);
00427 
00428                 return false;
00429             }
00430         }
00431     }
00432 }
00433 
00434 
00435 // Set the file mode
00436 bool Foam::chMod(const fileName& name, const mode_t m)
00437 {
00438     return ::chmod(name.c_str(), m) == 0;
00439 }
00440 
00441 
00442 // Return the file mode
00443 mode_t Foam::mode(const fileName& name)
00444 {
00445     fileStat fileStatus(name);
00446     if (fileStatus.isValid())
00447     {
00448         return fileStatus.status().st_mode;
00449     }
00450     else
00451     {
00452         return 0;
00453     }
00454 }
00455 
00456 
00457 // Return the file type: FILE or DIRECTORY
00458 Foam::fileName::Type Foam::type(const fileName& name)
00459 {
00460     mode_t m = mode(name);
00461 
00462     if (S_ISREG(m))
00463     {
00464         return fileName::FILE;
00465     }
00466     else if (S_ISDIR(m))
00467     {
00468         return fileName::DIRECTORY;
00469     }
00470     else
00471     {
00472         return fileName::UNDEFINED;
00473     }
00474 }
00475 
00476 
00477 // Does the name exist in the filing system?
00478 bool Foam::exists(const fileName& name, const bool checkGzip)
00479 {
00480     return mode(name) || isFile(name, checkGzip);
00481 }
00482 
00483 
00484 // Does the directory exist?
00485 bool Foam::isDir(const fileName& name)
00486 {
00487     return S_ISDIR(mode(name));
00488 }
00489 
00490 
00491 // Does the file exist?
00492 bool Foam::isFile(const fileName& name, const bool checkGzip)
00493 {
00494     return S_ISREG(mode(name)) || (checkGzip && S_ISREG(mode(name + ".gz")));
00495 }
00496 
00497 
00498 // Return size of file
00499 off_t Foam::fileSize(const fileName& name)
00500 {
00501     fileStat fileStatus(name);
00502     if (fileStatus.isValid())
00503     {
00504         return fileStatus.status().st_size;
00505     }
00506     else
00507     {
00508         return -1;
00509     }
00510 }
00511 
00512 
00513 // Return time of last file modification
00514 time_t Foam::lastModified(const fileName& name)
00515 {
00516     fileStat fileStatus(name);
00517     if (fileStatus.isValid())
00518     {
00519         return fileStatus.status().st_mtime;
00520     }
00521     else
00522     {
00523         return 0;
00524     }
00525 }
00526 
00527 
00528 // Read a directory and return the entries as a string list
00529 Foam::fileNameList Foam::readDir
00530 (
00531     const fileName& directory,
00532     const fileName::Type type,
00533     const bool filtergz
00534 )
00535 {
00536     // Initial filename list size
00537     // also used as increment if initial size found to be insufficient
00538     static const int maxNnames = 100;
00539 
00540     if (POSIX::debug)
00541     {
00542         Info<< "readDir(const fileName&, const fileType, const bool filtergz)"
00543             << " : reading directory " << directory << endl;
00544     }
00545 
00546     // Setup empty string list MAXTVALUES long
00547     fileNameList dirEntries(maxNnames);
00548 
00549     // Pointers to the directory entries
00550     DIR *source;
00551     struct dirent *list;
00552 
00553     // Temporary variables and counters
00554     label nEntries = 0;
00555 
00556     // Attempt to open directory and set the structure pointer
00557     if ((source = opendir(directory.c_str())) == NULL)
00558     {
00559         dirEntries.setSize(0);
00560 
00561         if (POSIX::debug)
00562         {
00563             Info<< "readDir(const fileName&, const fileType, "
00564                    "const bool filtergz) : cannot open directory "
00565                 << directory << endl;
00566         }
00567     }
00568     else
00569     {
00570         // Read and parse all the entries in the directory
00571         while ((list = readdir(source)) != NULL)
00572         {
00573             fileName fName(list->d_name);
00574 
00575             // ignore files begining with ., i.e. '.', '..' and '.*'
00576             if (fName.size() && fName[0] != '.')
00577             {
00578                 word fExt = fName.ext();
00579 
00580                 if
00581                 (
00582                     (type == fileName::DIRECTORY)
00583                  ||
00584                     (
00585                         type == fileName::FILE
00586                      && fName[fName.size()-1] != '~'
00587                      && fExt != "bak"
00588                      && fExt != "BAK"
00589                      && fExt != "old"
00590                      && fExt != "save"
00591                     )
00592                 )
00593                 {
00594                     if ((directory/fName).type() == type)
00595                     {
00596                         if (nEntries >= dirEntries.size())
00597                         {
00598                             dirEntries.setSize(dirEntries.size() + maxNnames);
00599                         }
00600 
00601                         if (filtergz && fExt == "gz")
00602                         {
00603                             dirEntries[nEntries++] = fName.lessExt();
00604                         }
00605                         else
00606                         {
00607                             dirEntries[nEntries++] = fName;
00608                         }
00609                     }
00610                 }
00611             }
00612         }
00613 
00614         // Reset the length of the entries list
00615         dirEntries.setSize(nEntries);
00616 
00617         closedir(source);
00618     }
00619 
00620     return dirEntries;
00621 }
00622 
00623 
00624 // Copy, recursively if necessary, the source to the destination
00625 bool Foam::cp(const fileName& src, const fileName& dest)
00626 {
00627     // Make sure source exists.
00628     if (!exists(src))
00629     {
00630         return false;
00631     }
00632 
00633     fileName destFile(dest);
00634 
00635     // Check type of source file.
00636     if (src.type() == fileName::FILE)
00637     {
00638         // If dest is a directory, create the destination file name.
00639         if (destFile.type() == fileName::DIRECTORY)
00640         {
00641             destFile = destFile/src.name();
00642         }
00643 
00644         // Make sure the destination directory exists.
00645         if (!isDir(destFile.path()) && !mkDir(destFile.path()))
00646         {
00647             return false;
00648         }
00649 
00650         // Open and check streams.
00651         std::ifstream srcStream(src.c_str());
00652         if (!srcStream)
00653         {
00654             return false;
00655         }
00656 
00657         std::ofstream destStream(destFile.c_str());
00658         if (!destStream)
00659         {
00660             return false;
00661         }
00662 
00663         // Copy character data.
00664         char ch;
00665         while (srcStream.get(ch))
00666         {
00667             destStream.put(ch);
00668         }
00669 
00670         // Final check.
00671         if (!srcStream.eof() || !destStream)
00672         {
00673             return false;
00674         }
00675     }
00676     else if (src.type() == fileName::DIRECTORY)
00677     {
00678         // If dest is a directory, create the destination file name.
00679         if (destFile.type() == fileName::DIRECTORY)
00680         {
00681             destFile = destFile/src.component(src.components().size() -1);
00682         }
00683 
00684         // Make sure the destination directory exists.
00685         if (!isDir(destFile) && !mkDir(destFile))
00686         {
00687             return false;
00688         }
00689 
00690         // Copy files
00691         fileNameList contents = readDir(src, fileName::FILE, false);
00692         forAll(contents, i)
00693         {
00694             if (POSIX::debug)
00695             {
00696                 Info<< "Copying : " << src/contents[i]
00697                     << " to " << destFile/contents[i] << endl;
00698             }
00699 
00700             // File to file.
00701             cp(src/contents[i], destFile/contents[i]);
00702         }
00703 
00704         // Copy sub directories.
00705         fileNameList subdirs = readDir(src, fileName::DIRECTORY);
00706         forAll(subdirs, i)
00707         {
00708             if (POSIX::debug)
00709             {
00710                 Info<< "Copying : " << src/subdirs[i]
00711                     << " to " << destFile << endl;
00712             }
00713 
00714             // Dir to Dir.
00715             cp(src/subdirs[i], destFile);
00716         }
00717     }
00718 
00719     return true;
00720 }
00721 
00722 
00723 // Create a softlink. dst should not exist. Returns true if successful.
00724 bool Foam::ln(const fileName& src, const fileName& dst)
00725 {
00726     if (POSIX::debug)
00727     {
00728         Info<< "Create softlink from : " << src << " to " << dst
00729             << endl;
00730     }
00731 
00732     if (exists(dst))
00733     {
00734         WarningIn("ln(const fileName&, const fileName&)")
00735             << "destination " << dst << " already exists. Not linking."
00736             << endl;
00737         return false;
00738     }
00739 
00740     if (!exists(src))
00741     {
00742         WarningIn("ln(const fileName&, const fileName&)")
00743             << "source " << src << " does not exist." << endl;
00744         return false;
00745     }
00746 
00747     if (symlink(src.c_str(), dst.c_str()) == 0)
00748     {
00749         return true;
00750     }
00751     else
00752     {
00753         WarningIn("ln(const fileName&, const fileName&)")
00754             << "symlink from " << src << " to " << dst << " failed." << endl;
00755         return false;
00756     }
00757 }
00758 
00759 
00760 // Rename srcFile dstFile
00761 bool Foam::mv(const fileName& src, const fileName& dst)
00762 {
00763     if (POSIX::debug)
00764     {
00765         Info<< "Move : " << src << " to " << dst << endl;
00766     }
00767 
00768     if
00769     (
00770         dst.type() == fileName::DIRECTORY
00771      && src.type() != fileName::DIRECTORY
00772     )
00773     {
00774         const fileName dstName(dst/src.name());
00775 
00776         return rename(src.c_str(), dstName.c_str()) == 0;
00777     }
00778     else
00779     {
00780         return rename(src.c_str(), dst.c_str()) == 0;
00781     }
00782 }
00783 
00784 
00785 //- Rename to a corresponding backup file
00786 //  If the backup file already exists, attempt with "01" .. "99" index
00787 bool Foam::mvBak(const fileName& src, const std::string& ext)
00788 {
00789     if (POSIX::debug)
00790     {
00791         Info<< "mvBak : " << src << " to extension " << ext << endl;
00792     }
00793 
00794     if (exists(src, false))
00795     {
00796         const int maxIndex = 99;
00797         char index[3];
00798 
00799         for (int n = 0; n <= maxIndex; n++)
00800         {
00801             fileName dstName(src + "." + ext);
00802             if (n)
00803             {
00804                 sprintf(index, "%02d", n);
00805                 dstName += index;
00806             }
00807 
00808             // avoid overwriting existing files, except for the last
00809             // possible index where we have no choice
00810             if (!exists(dstName, false) || n == maxIndex)
00811             {
00812                 return rename(src.c_str(), dstName.c_str()) == 0;
00813             }
00814 
00815         }
00816     }
00817 
00818     // fall-through: nothing to do
00819     return false;
00820 }
00821 
00822 
00823 
00824 // Remove a file, returning true if successful otherwise false
00825 bool Foam::rm(const fileName& file)
00826 {
00827     if (POSIX::debug)
00828     {
00829         Info<< "Removing : " << file << endl;
00830     }
00831 
00832     // Try returning plain file name; if not there, try with .gz
00833     if (remove(file.c_str()) == 0)
00834     {
00835         return true;
00836     }
00837     else
00838     {
00839         return remove(string(file + ".gz").c_str()) == 0;
00840     }
00841 }
00842 
00843 
00844 // Remove a dirctory and its contents
00845 bool Foam::rmDir(const fileName& directory)
00846 {
00847     if (POSIX::debug)
00848     {
00849         Info<< "rmDir(const fileName&) : "
00850             << "removing directory " << directory << endl;
00851     }
00852 
00853     // Pointers to the directory entries
00854     DIR *source;
00855     struct dirent *list;
00856 
00857     // Attempt to open directory and set the structure pointer
00858     if ((source = opendir(directory.c_str())) == NULL)
00859     {
00860         WarningIn("rmDir(const fileName&)")
00861             << "cannot open directory " << directory << endl;
00862 
00863         return false;
00864     }
00865     else
00866     {
00867         // Read and parse all the entries in the directory
00868         while ((list = readdir(source)) != NULL)
00869         {
00870             fileName fName(list->d_name);
00871 
00872             if (fName != "." && fName != "..")
00873             {
00874                 fileName path = directory/fName;
00875 
00876                 if (path.type() == fileName::DIRECTORY)
00877                 {
00878                     if (!rmDir(path))
00879                     {
00880                         WarningIn("rmDir(const fileName&)")
00881                             << "failed to remove directory " << fName
00882                             << " while removing directory " << directory
00883                             << endl;
00884 
00885                         closedir(source);
00886 
00887                         return false;
00888                     }
00889                 }
00890                 else
00891                 {
00892                     if (!rm(path))
00893                     {
00894                         WarningIn("rmDir(const fileName&)")
00895                             << "failed to remove file " << fName
00896                             << " while removing directory " << directory
00897                             << endl;
00898 
00899                         closedir(source);
00900 
00901                         return false;
00902                     }
00903                 }
00904             }
00905 
00906         }
00907 
00908         if (!rm(directory))
00909         {
00910             WarningIn("rmDir(const fileName&)")
00911                 << "failed to remove directory " << directory << endl;
00912 
00913             closedir(source);
00914 
00915             return false;
00916         }
00917 
00918         closedir(source);
00919 
00920         return true;
00921     }
00922 }
00923 
00924 
00925 unsigned int Foam::sleep(const unsigned int s)
00926 {
00927     return ::sleep(s);
00928 }
00929 
00930 
00931 void Foam::fdClose(const int fd)
00932 {
00933     if (close(fd) != 0)
00934     {
00935         FatalErrorIn
00936         (
00937             "fdClose(const int fd)"
00938         )   << "close error on " << fd << endl
00939             << abort(FatalError);
00940     }
00941 }
00942 
00943 
00944 bool Foam::ping
00945 (
00946     const word& destName,
00947     const label destPort,
00948     const label timeOut
00949 )
00950 {
00951     char *serverAddress;
00952     struct in_addr *ptr;
00953     struct hostent *hostPtr;
00954     volatile int sockfd;
00955     struct sockaddr_in destAddr;      // will hold the destination addr
00956     u_int addr;
00957 
00958     if ((hostPtr = gethostbyname(destName.c_str())) == NULL)
00959     {
00960         FatalErrorIn
00961         (
00962             "Foam::ping(const word&, const label)"
00963         )   << "gethostbyname error " << h_errno << " for host " << destName
00964             << abort(FatalError);
00965     }
00966 
00967     // Get first of the SLL of addresses
00968     serverAddress = *(hostPtr->h_addr_list);
00969     ptr = reinterpret_cast<struct in_addr*>(serverAddress);
00970     addr = ptr->s_addr;
00971 
00972     // Allocate socket
00973     sockfd = socket(AF_INET, SOCK_STREAM, 0);
00974     if (sockfd < 0)
00975     {
00976         FatalErrorIn
00977         (
00978             "Foam::ping(const word&, const label)"
00979         )   << "socket error"
00980             << abort(FatalError);
00981     }
00982 
00983     // Fill sockaddr_in structure with dest address and port
00984     memset (reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
00985     destAddr.sin_family = AF_INET;
00986     destAddr.sin_port = htons(ushort(destPort));
00987     destAddr.sin_addr.s_addr = addr;
00988 
00989 
00990     timer myTimer(timeOut);
00991 
00992     if (timedOut(myTimer))
00993     {
00994         // Setjmp from timer jumps back to here
00995         fdClose(sockfd);
00996         return false;
00997     }
00998 
00999     if
01000     (
01001         connect
01002         (
01003             sockfd,
01004             reinterpret_cast<struct sockaddr*>(&destAddr),
01005             sizeof(struct sockaddr)
01006         ) != 0
01007     )
01008     {
01009         // Connection refused. Check if network was actually used or not.
01010 
01011         int connectErr = errno;
01012 
01013         fdClose(sockfd);
01014 
01015         if (connectErr == ECONNREFUSED)
01016         {
01017             return true;
01018         }
01019         //perror("connect");
01020 
01021         return false;
01022     }
01023 
01024     fdClose(sockfd);
01025 
01026     return true;
01027 }
01028 
01029 
01030 bool Foam::ping(const word& hostname, const label timeOut)
01031 {
01032     return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
01033 }
01034 
01035 
01036 int Foam::system(const string& command)
01037 {
01038     return ::system(command.c_str());
01039 }
01040 
01041 
01042 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines