| 1 |
chuckv |
1492 |
#include "utils/SystemUtilities.hpp" |
| 2 |
|
|
|
| 3 |
|
|
#include "utils/StringUtils.hpp" |
| 4 |
|
|
#include "utils/Exception.hpp" |
| 5 |
|
|
|
| 6 |
|
|
#ifdef _WIN32 |
| 7 |
|
|
|
| 8 |
|
|
#define WIN32_LEAN_AND_MEAN |
| 9 |
|
|
#include <windows.h> /* for GetFullPathName */ |
| 10 |
|
|
|
| 11 |
|
|
//____ Define the missing symbols from <unistd.h> for M$ .... |
| 12 |
|
|
#include <direct.h> |
| 13 |
|
|
#define CHDIR _chdir |
| 14 |
|
|
#define PATHSEP '\\' |
| 15 |
|
|
#define PATHSEPSTR "\\" |
| 16 |
|
|
#define access _access |
| 17 |
|
|
#include <fcntl.h> |
| 18 |
|
|
#include <io.h> |
| 19 |
|
|
#define F_OK 0 |
| 20 |
|
|
#define W_OK 2 |
| 21 |
|
|
#define R_OK 4 |
| 22 |
|
|
|
| 23 |
|
|
#else // _WIN32 |
| 24 |
|
|
|
| 25 |
|
|
#include <libgen.h> |
| 26 |
|
|
#include <unistd.h> |
| 27 |
|
|
#define CHDIR chdir |
| 28 |
|
|
#define PATHSEP '/' |
| 29 |
|
|
#define PATHSEPSTR "/" |
| 30 |
|
|
#endif |
| 31 |
|
|
|
| 32 |
|
|
#include <fstream> |
| 33 |
|
|
#include <sys/stat.h> |
| 34 |
|
|
|
| 35 |
|
|
#ifdef BUILD_FOR_FAH |
| 36 |
|
|
#include <fah/core/chksum/overrides.h> |
| 37 |
|
|
#endif |
| 38 |
|
|
|
| 39 |
|
|
using namespace std; |
| 40 |
|
|
|
| 41 |
|
|
namespace OpenMD { |
| 42 |
|
|
//____ changeDirectory |
| 43 |
|
|
bool changeDirectory(const string &fileName) { |
| 44 |
|
|
char *confFile = (char *)fileName.c_str(); |
| 45 |
|
|
char *currentdir = confFile; |
| 46 |
|
|
char *tmp = NULL; |
| 47 |
|
|
|
| 48 |
|
|
#ifdef WIN32 |
| 49 |
|
|
// Replace all '/' by '\' |
| 50 |
|
|
for (tmp = confFile; *tmp; ++tmp) |
| 51 |
|
|
if (*tmp == '/') |
| 52 |
|
|
*tmp = '\\'; |
| 53 |
|
|
#endif |
| 54 |
|
|
|
| 55 |
|
|
|
| 56 |
|
|
for (tmp = confFile; *tmp; ++tmp) ; |
| 57 |
|
|
|
| 58 |
|
|
// find final null |
| 59 |
|
|
for (; tmp != confFile && *tmp != PATHSEP; --tmp) ; |
| 60 |
|
|
|
| 61 |
|
|
// find last '/' |
| 62 |
|
|
if (tmp != confFile) { |
| 63 |
|
|
*tmp = 0; |
| 64 |
|
|
confFile = tmp + 1; |
| 65 |
|
|
if (CHDIR(currentdir)) |
| 66 |
|
|
return false; |
| 67 |
|
|
} else if (*tmp == PATHSEP) // config file in / is odd, but it might happen |
| 68 |
|
|
if (CHDIR(PATHSEPSTR)) |
| 69 |
|
|
return false; |
| 70 |
|
|
|
| 71 |
|
|
return true; |
| 72 |
|
|
} |
| 73 |
|
|
|
| 74 |
|
|
//____ isAccessible |
| 75 |
|
|
bool isAccessible(const string &fileName) { |
| 76 |
|
|
return ::access(fileName.c_str(), F_OK) == 0; |
| 77 |
|
|
} |
| 78 |
|
|
|
| 79 |
|
|
void splitFileName(const string &filename, string &dirname, |
| 80 |
|
|
string &basename, string &extension) { |
| 81 |
|
|
string::size_type pos = filename.rfind(PATHSEP); |
| 82 |
|
|
|
| 83 |
|
|
if (pos == string::npos) basename = filename; |
| 84 |
|
|
else { |
| 85 |
|
|
dirname = filename.substr(0, pos); |
| 86 |
|
|
basename = filename.substr(pos + 1); |
| 87 |
|
|
} |
| 88 |
|
|
|
| 89 |
|
|
pos = basename.rfind('.'); |
| 90 |
|
|
|
| 91 |
|
|
if (pos != string::npos) { |
| 92 |
|
|
extension = basename.substr(pos + 1); |
| 93 |
|
|
basename = basename.substr(0, pos); |
| 94 |
|
|
} |
| 95 |
|
|
} |
| 96 |
|
|
|
| 97 |
|
|
unsigned int getFileSize(const string &filename) { |
| 98 |
|
|
ifstream f(filename.c_str()); |
| 99 |
|
|
if (!f.is_open()) THROWS("Failed to open '" << filename << "'"); |
| 100 |
|
|
|
| 101 |
|
|
f.seekg(0, ios::end); |
| 102 |
|
|
return (unsigned int)f.tellg(); |
| 103 |
|
|
} |
| 104 |
|
|
|
| 105 |
|
|
//____ openMDAbort |
| 106 |
|
|
|
| 107 |
|
|
static void (*myAbortFunction)() = NULL; |
| 108 |
|
|
|
| 109 |
|
|
void openMDAbort() { |
| 110 |
|
|
if (myAbortFunction) (*myAbortFunction)(); |
| 111 |
|
|
|
| 112 |
|
|
THROW("EXIT"); |
| 113 |
|
|
} |
| 114 |
|
|
|
| 115 |
|
|
//____ setOpenMDAbort |
| 116 |
|
|
void setOpenMDAbort(void (*abortFunction)()) { |
| 117 |
|
|
myAbortFunction = abortFunction; |
| 118 |
|
|
} |
| 119 |
|
|
|
| 120 |
|
|
//____ openMDExit |
| 121 |
|
|
|
| 122 |
|
|
static void (*myExitFunction)() = NULL; |
| 123 |
|
|
|
| 124 |
|
|
void openMDExit() { |
| 125 |
|
|
if (myExitFunction) (*myExitFunction)(); |
| 126 |
|
|
|
| 127 |
|
|
THROW("EXIT"); |
| 128 |
|
|
} |
| 129 |
|
|
|
| 130 |
|
|
//____ setOpenMDExit |
| 131 |
|
|
void setOpenMDExit(void (*exitFunction)()) { |
| 132 |
|
|
myExitFunction = exitFunction; |
| 133 |
|
|
} |
| 134 |
|
|
|
| 135 |
|
|
//____ openMDStartSerial |
| 136 |
|
|
static void (*myStartSerial)(bool) = NULL; |
| 137 |
|
|
|
| 138 |
|
|
void openMDStartSerial(bool exludeMaster) { |
| 139 |
|
|
if (myStartSerial != NULL) |
| 140 |
|
|
(*myStartSerial)(exludeMaster); |
| 141 |
|
|
} |
| 142 |
|
|
|
| 143 |
|
|
//____ setOpenMDStartSerial |
| 144 |
|
|
void setOpenMDStartSerial(void (*startSerialFunction)(bool)) { |
| 145 |
|
|
myStartSerial = startSerialFunction; |
| 146 |
|
|
} |
| 147 |
|
|
|
| 148 |
|
|
//____ openMDEndSerial |
| 149 |
|
|
static void (*myEndSerial)(bool) = NULL; |
| 150 |
|
|
|
| 151 |
|
|
void openMDEndSerial(bool exludeMaster) { |
| 152 |
|
|
if (myEndSerial != NULL) |
| 153 |
|
|
(*myEndSerial)(exludeMaster); |
| 154 |
|
|
} |
| 155 |
|
|
|
| 156 |
|
|
//____ setOpenMDExit |
| 157 |
|
|
void setOpenMDEndSerial(void (*endSerialFunction)(bool)) { |
| 158 |
|
|
myEndSerial = endSerialFunction; |
| 159 |
|
|
} |
| 160 |
|
|
|
| 161 |
|
|
//____ ISLITTLEENDIAN |
| 162 |
|
|
struct Endian { |
| 163 |
|
|
// Helper class to make sure that we get endianess correct ... M$ |
| 164 |
|
|
static bool isLittleEndian() { |
| 165 |
|
|
unsigned int tmp = 1; |
| 166 |
|
|
return 0 != *(reinterpret_cast<const char *> ( &tmp)); |
| 167 |
|
|
} |
| 168 |
|
|
}; |
| 169 |
|
|
const bool ISLITTLEENDIAN = Endian::isLittleEndian(); |
| 170 |
|
|
|
| 171 |
|
|
string getCanonicalPath(const string &path) { |
| 172 |
|
|
char buf[4096]; |
| 173 |
|
|
|
| 174 |
|
|
#ifdef _WIN32 |
| 175 |
|
|
char *finalpart; |
| 176 |
|
|
DWORD len = GetFullPathName(path.c_str(), 4096, buf, &finalpart); |
| 177 |
|
|
if (len == 0 || len > 4095) |
| 178 |
|
|
THROW(string("GetFullPathName '") + path + "' failed."); |
| 179 |
|
|
|
| 180 |
|
|
return buf; |
| 181 |
|
|
|
| 182 |
|
|
#else |
| 183 |
|
|
char tmp[path.length() + 3]; |
| 184 |
|
|
|
| 185 |
|
|
// The file might not exist yet but its directory must. |
| 186 |
|
|
strcpy(tmp, path.c_str()); |
| 187 |
|
|
char *dir = dirname(tmp); |
| 188 |
|
|
|
| 189 |
|
|
if (!realpath(dir, buf)) |
| 190 |
|
|
THROW(string("realpath '") + path + "' failed."); |
| 191 |
|
|
|
| 192 |
|
|
strcpy(tmp, path.c_str()); |
| 193 |
|
|
|
| 194 |
|
|
return string(buf) + "/" + basename(tmp); |
| 195 |
|
|
#endif |
| 196 |
|
|
} |
| 197 |
|
|
|
| 198 |
|
|
bool SystemUtilities::unlink(const string &path) { |
| 199 |
|
|
#ifdef BUILD_FOR_FAH |
| 200 |
|
|
return fah_unlink(path.c_str()) == 0; |
| 201 |
|
|
#else |
| 202 |
|
|
return ::unlink(path.c_str()) == 0; |
| 203 |
|
|
#endif |
| 204 |
|
|
} |
| 205 |
|
|
|
| 206 |
|
|
void SystemUtilities::rename(const string &src, const string &dst) { |
| 207 |
|
|
unlink(dst); |
| 208 |
|
|
#ifdef BUILD_FOR_FAH |
| 209 |
|
|
fah_rename(src.c_str(), dst.c_str()); |
| 210 |
|
|
#else |
| 211 |
|
|
::rename(src.c_str(), dst.c_str()); |
| 212 |
|
|
#endif |
| 213 |
|
|
} |
| 214 |
|
|
} |
| 215 |
|
|
|
| 216 |
|
|
|
| 217 |
|
|
|
| 218 |
|
|
|
| 219 |
|
|
|
| 220 |
|
|
|
| 221 |
|
|
|
| 222 |
|
|
|
| 223 |
|
|
|