LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2008 INRIA | 3 * Copyright (c) 2008 INRIA |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 /** | 68 /** |
69 * \file | 69 * \file |
70 * \ingroup systempath | 70 * \ingroup systempath |
71 * ns3::SystemPath implementation. | 71 * ns3::SystemPath implementation. |
72 */ | 72 */ |
73 | 73 |
74 namespace ns3 { | 74 namespace ns3 { |
75 | 75 |
76 NS_LOG_COMPONENT_DEFINE ("SystemPath"); | 76 NS_LOG_COMPONENT_DEFINE ("SystemPath"); |
77 | 77 |
78 namespace SystemPath { | |
79 | |
80 /** | 78 /** |
81 * \ingroup systempath | 79 * \ingroup systempath |
82 * \brief Get the directory path for a file. | 80 * \brief Get the directory path for a file. |
83 * | 81 * |
84 * This is an internal function (by virtue of not being | 82 * This is an internal function (by virtue of not being |
85 * declared in a \c .h file); the public API is FindSelfDirectory(). | 83 * declared in a \c .h file); the public API is FindSelfDirectory(). |
86 *· | 84 *· |
87 * \param [in] path The full path to a file. | 85 * \param [in] path The full path to a file. |
88 * \returns The full path to the containing directory. | 86 * \returns The full path to the containing directory. |
89 */ | 87 */ |
90 std::string Dirname (std::string path) | 88 std::string |
| 89 SystemPath::Dirname (std::string path) |
91 { | 90 { |
92 NS_LOG_FUNCTION (path); | 91 NS_LOG_FUNCTION (path); |
93 std::list<std::string> elements = Split (path); | 92 std::list<std::string> elements = Split (path); |
94 std::list<std::string>::const_iterator last = elements.end(); | 93 std::list<std::string>::const_iterator last = elements.end(); |
95 last--; | 94 last--; |
96 return Join (elements.begin (), last); | 95 return Join (elements.begin (), last); |
97 } | 96 } |
98 | 97 |
99 std::string FindSelfDirectory (void) | 98 std::string |
| 99 SystemPath::FindSelfDirectory (void) |
100 { | 100 { |
101 /**· | 101 /**· |
102 * This function returns the path to the running $PREFIX. | 102 * This function returns the path to the running $PREFIX. |
103 * Mac OS X: _NSGetExecutablePath() (man 3 dyld) | 103 * Mac OS X: _NSGetExecutablePath() (man 3 dyld) |
104 * Linux: readlink /proc/self/exe | 104 * Linux: readlink /proc/self/exe |
105 * Solaris: getexecname() | 105 * Solaris: getexecname() |
106 * FreeBSD: sysctl CTL_KERN KERN_PROC KERN_PROC_PATHNAME -1 | 106 * FreeBSD: sysctl CTL_KERN KERN_PROC KERN_PROC_PATHNAME -1 |
107 * BSD with procfs: readlink /proc/curproc/file | 107 * BSD with procfs: readlink /proc/curproc/file |
108 * Windows: GetModuleFileName() with hModule = NULL | 108 * Windows: GetModuleFileName() with hModule = NULL |
109 */ | 109 */ |
(...skipping 17 matching lines...) Expand all Loading... |
127 buffer = (char*)malloc (size); | 127 buffer = (char*)malloc (size); |
128 memset (buffer, 0, size); | 128 memset (buffer, 0, size); |
129 } | 129 } |
130 if (status == -1) | 130 if (status == -1) |
131 { | 131 { |
132 NS_FATAL_ERROR ("Oops, could not find self directory."); | 132 NS_FATAL_ERROR ("Oops, could not find self directory."); |
133 } | 133 } |
134 filename = buffer; | 134 filename = buffer; |
135 free (buffer); | 135 free (buffer); |
136 } | 136 } |
137 #elif defined (__win32__) | 137 #elif defined (_WIN32) |
138 { | 138 { |
139 /** \todo untested. it should work if code is compiled with | 139 /** \todo untested. it should work if code is compiled with |
140 * LPTSTR = char * | 140 * LPTSTR = char * |
141 */ | 141 */ |
142 DWORD size = 1024; | 142 DWORD size = 1024; |
143 LPTSTR lpFilename = (LPTSTR) malloc (sizeof(TCHAR) * size); | 143 LPTSTR lpFilename = (LPTSTR) malloc (sizeof(TCHAR) * size); |
144 DWORD status = GetModuleFilename (0, lpFilename, size); | 144 DWORD status = GetModuleFileName(0, lpFilename, size); |
145 while (status == size) | 145 while (status == size) |
146 { | 146 { |
147 size = size * 2; | 147 size = size * 2; |
148 free (lpFilename); | 148 free (lpFilename); |
149 lpFilename = (LPTSTR) malloc (sizeof(TCHAR) * size); | 149 lpFilename = (LPTSTR) malloc (sizeof(TCHAR) * size); |
150 » status = GetModuleFilename (0, lpFilename, size); | 150 » status = GetModuleFileName(0, lpFilename, size); |
151 } | 151 } |
152 NS_ASSERT (status != 0); | 152 NS_ASSERT (status != 0); |
153 filename = lpFilename; | 153 filename = lpFilename; |
154 free (lpFilename); | 154 free (lpFilename); |
155 } | 155 } |
156 #elif defined (__APPLE__) | 156 #elif defined (__APPLE__) |
157 { | 157 { |
158 uint32_t bufsize = 1024; | 158 uint32_t bufsize = 1024; |
159 char *buffer = (char *) malloc (bufsize); | 159 char *buffer = (char *) malloc (bufsize); |
160 NS_ASSERT (buffer != 0); | 160 NS_ASSERT (buffer != 0); |
(...skipping 19 matching lines...) Expand all Loading... |
180 mib[2] = KERN_PROC_PATHNAME; | 180 mib[2] = KERN_PROC_PATHNAME; |
181 mib[3] = -1; | 181 mib[3] = -1; |
182 | 182 |
183 sysctl(mib, 4, buf, &bufSize, NULL, 0); | 183 sysctl(mib, 4, buf, &bufSize, NULL, 0); |
184 filename = buf; | 184 filename = buf; |
185 } | 185 } |
186 #endif | 186 #endif |
187 return Dirname (filename); | 187 return Dirname (filename); |
188 } | 188 } |
189 ·· | 189 ·· |
190 std::string Append (std::string left, std::string right) | 190 std::string |
| 191 SystemPath::Append (std::string left, std::string right) |
191 { | 192 { |
192 // removing trailing separators from 'left' | 193 // removing trailing separators from 'left' |
193 NS_LOG_FUNCTION (left << right); | 194 NS_LOG_FUNCTION (left << right); |
194 while (true) | 195 while (true) |
195 { | 196 { |
196 std::string::size_type lastSep = left.rfind (SYSTEM_PATH_SEP); | 197 std::string::size_type lastSep = left.rfind (SYSTEM_PATH_SEP); |
197 if (lastSep != left.size () - 1) | 198 if (lastSep != left.size () - 1) |
198 { | 199 { |
199 break; | 200 break; |
200 } | 201 } |
201 left = left.substr (0, left.size () - 1); | 202 left = left.substr (0, left.size () - 1); |
202 }· | 203 }· |
203 std::string retval = left + SYSTEM_PATH_SEP + right; | 204 std::string retval = left + SYSTEM_PATH_SEP + right; |
204 return retval; | 205 return retval; |
205 } | 206 } |
206 | 207 |
207 std::list<std::string> Split (std::string path) | 208 std::list<std::string> |
| 209 SystemPath::Split (std::string path) |
208 { | 210 { |
209 NS_LOG_FUNCTION (path); | 211 NS_LOG_FUNCTION (path); |
210 std::list<std::string> retval; | 212 std::list<std::string> retval; |
211 std::string::size_type current = 0, next = 0; | 213 std::string::size_type current = 0, next = 0; |
212 next = path.find (SYSTEM_PATH_SEP, current); | 214 next = path.find (SYSTEM_PATH_SEP, current); |
213 while (next != std::string::npos) | 215 while (next != std::string::npos) |
214 { | 216 { |
215 std::string item = path.substr (current, next - current); | 217 std::string item = path.substr (current, next - current); |
216 retval.push_back (item); | 218 retval.push_back (item); |
217 current = next + 1; | 219 current = next + 1; |
218 next = path.find (SYSTEM_PATH_SEP, current); | 220 next = path.find (SYSTEM_PATH_SEP, current); |
219 } | 221 } |
220 std::string item = path.substr (current, next - current); | 222 std::string item = path.substr (current, next - current); |
221 retval.push_back (item); | 223 retval.push_back (item); |
222 return retval; | 224 return retval; |
223 } | 225 } |
224 | 226 |
225 std::string Join (std::list<std::string>::const_iterator begin, | 227 std::string |
| 228 SystemPath::Join (std::list<std::string>::const_iterator begin, |
226 std::list<std::string>::const_iterator end) | 229 std::list<std::string>::const_iterator end) |
227 { | 230 { |
228 NS_LOG_FUNCTION (&begin << &end); | 231 NS_LOG_FUNCTION (&begin << &end); |
229 std::string retval = ""; | 232 std::string retval = ""; |
230 for (std::list<std::string>::const_iterator i = begin; i != end; i++) | 233 for (std::list<std::string>::const_iterator i = begin; i != end; i++) |
231 { | 234 { |
232 if (i == begin) | 235 if (i == begin) |
233 { | 236 { |
234 retval = *i; | 237 retval = *i; |
235 } | 238 } |
236 else | 239 else |
237 { | 240 { |
238 retval = retval + SYSTEM_PATH_SEP + *i; | 241 retval = retval + SYSTEM_PATH_SEP + *i; |
239 } | 242 } |
240 } | 243 } |
241 return retval; | 244 return retval; |
242 } | 245 } |
243 ·· | 246 ·· |
244 std::list<std::string> ReadFiles (std::string path) | 247 std::list<std::string> |
| 248 SystemPath::ReadFiles (std::string path) |
245 { | 249 { |
246 NS_LOG_FUNCTION (path); | 250 NS_LOG_FUNCTION (path); |
247 std::list<std::string> files; | 251 std::list<std::string> files; |
248 #if defined HAVE_OPENDIR | 252 #if defined HAVE_OPENDIR |
249 DIR *dp = opendir (path.c_str ()); | 253 DIR *dp = opendir (path.c_str ()); |
250 if (dp == NULL) | 254 if (dp == NULL) |
251 { | 255 { |
252 NS_FATAL_ERROR ("Could not open directory=" << path); | 256 NS_FATAL_ERROR ("Could not open directory=" << path); |
253 } | 257 } |
254 struct dirent *de = readdir (dp); | 258 struct dirent *de = readdir (dp); |
255 while (de != 0) | 259 while (de != 0) |
256 { | 260 { |
257 files.push_back (de->d_name); | 261 files.push_back (de->d_name); |
258 de = readdir (dp); | 262 de = readdir (dp); |
259 } | 263 } |
260 closedir (dp); | 264 closedir (dp); |
261 #elif defined (HAVE_FIND_FIRST_FILE) | 265 #elif defined (HAVE_FIND_FIRST_FILE) |
262 /** \todo untested */ | 266 /** \todo untested */ |
263 HANDLE hFind; | 267 HANDLE hFind; |
264 WIN32_FIND_DATA fileData; | 268 WIN32_FIND_DATA fileData; |
265 ·· | 269 std::string wildcard = path + "\\*"; |
266 hFind = FindFirstFile (path.c_str (), &FindFileData); | 270 |
| 271 hFind = FindFirstFile (wildcard.c_str (), &fileData); |
267 if (hFind == INVALID_HANDLE_VALUE) | 272 if (hFind == INVALID_HANDLE_VALUE) |
268 { | 273 { |
269 NS_FATAL_ERROR ("Could not open directory=" << path); | 274 NS_FATAL_ERROR ("Could not open directory=" << path); |
270 } | 275 } |
271 do | 276 do |
272 { | 277 { |
273 files.push_back (fileData.cFileName); | 278 » if (strcmp(fileData.cFileName, ".") != 0 && strcmp(fileData.cFileName, "
..") != 0) |
| 279 files.push_back (fileData.cFileName); |
274 } while (FindNextFile (hFind, &fileData)); | 280 } while (FindNextFile (hFind, &fileData)); |
275 FindClose(hFind); | 281 FindClose(hFind); |
276 #else | 282 #else |
277 #error "No support for reading a directory on this platform" | 283 #error "No support for reading a directory on this platform" |
278 #endif | 284 #endif |
279 return files; | 285 return files; |
280 } | 286 } |
281 | 287 |
282 std::string· | 288 std::string· |
283 MakeTemporaryDirectoryName (void) | 289 SystemPath::MakeTemporaryDirectoryName (void) |
284 { | 290 { |
285 NS_LOG_FUNCTION_NOARGS (); | 291 NS_LOG_FUNCTION_NOARGS (); |
286 char *path = NULL; | 292 char *path = NULL; |
287 | 293 |
288 path = getenv ("TMP"); | 294 path = getenv ("TMP"); |
289 if (path == NULL) | 295 if (path == NULL) |
290 { | 296 { |
291 path = getenv ("TEMP"); | 297 path = getenv ("TEMP"); |
292 if (path == NULL) | 298 if (path == NULL) |
293 { | 299 { |
294 path = const_cast<char *> ("/tmp"); | 300 path = const_cast<char *> ("/tmp"); |
295 } | 301 } |
296 } | 302 } |
297 | 303 |
298 // | 304 // |
299 // Just in case the user wants to go back and find the output, we give | 305 // Just in case the user wants to go back and find the output, we give |
300 // a hint as to which dir we created by including a time hint. | 306 // a hint as to which dir we created by including a time hint. |
301 // | 307 // |
302 time_t now = time (NULL); | 308 time_t now = time (NULL); |
303 struct tm *tm_now = localtime (&now); | 309 struct tm *tm_now = localtime (&now); |
304 // | 310 // |
305 // But we also randomize the name in case there are multiple users doing | 311 // But we also randomize the name in case there are multiple users doing |
306 // this at the same time | 312 // this at the same time |
307 // | 313 // |
308 srand (time (0)); | 314 srand (static_cast<unsigned int>(time (0))); |
309 long int n = rand (); | 315 long int n = rand (); |
310 | 316 |
311 // | 317 // |
312 // The final path to the directory is going to look something like | 318 // The final path to the directory is going to look something like |
313 //· | 319 //· |
314 // /tmp/ns3-14.30.29.32767 | 320 // /tmp/ns3-14.30.29.32767 |
315 // | 321 // |
316 // The first segment comes from one of the temporary directory env· | 322 // The first segment comes from one of the temporary directory env· |
317 // variables or /tmp if not found. The directory name starts with an | 323 // variables or /tmp if not found. The directory name starts with an |
318 // identifier telling folks who is making all of the temp directories | 324 // identifier telling folks who is making all of the temp directories |
319 // and then the local time (in this case 14.30.29 -- which is 2:30 and | 325 // and then the local time (in this case 14.30.29 -- which is 2:30 and |
320 // 29 seconds PM). | 326 // 29 seconds PM). |
321 // | 327 // |
322 std::ostringstream oss; | 328 std::ostringstream oss; |
323 oss << path << SYSTEM_PATH_SEP << "ns-3." << tm_now->tm_hour << "." | 329 oss << path << SYSTEM_PATH_SEP << "ns-3." << tm_now->tm_hour << "." |
324 << tm_now->tm_min << "." << tm_now->tm_sec << "." << n; | 330 << tm_now->tm_min << "." << tm_now->tm_sec << "." << n; |
325 | 331 |
326 return oss.str (); | 332 return oss.str (); |
327 } | 333 } |
328 | 334 |
329 void· | 335 void· |
330 MakeDirectories (std::string path) | 336 SystemPath::MakeDirectories (std::string path) |
331 { | 337 { |
332 NS_LOG_FUNCTION (path); | 338 NS_LOG_FUNCTION (path); |
333 | 339 |
334 // Make sure all directories on the path exist | 340 // Make sure all directories on the path exist |
335 std::list<std::string> elements = Split (path); | 341 std::list<std::string> elements = Split (path); |
336 for (std::list<std::string>::const_iterator i = elements.begin (); i != elemen
ts.end (); ++i) | 342 auto i = elements.begin (); |
337 { | 343 while (i != elements.end ()) |
| 344 { |
| 345 if (*i == "") |
| 346 { |
| 347 NS_LOG_LOGIC ("skipping empty directory name"); |
| 348 ++i; |
| 349 continue; |
| 350 } |
| 351 NS_LOG_LOGIC ("creating directory " << *i); |
| 352 ++i; // Now points to one past the directory we want to create |
338 std::string tmp = Join (elements.begin (), i); | 353 std::string tmp = Join (elements.begin (), i); |
| 354 ······ |
339 #if defined(HAVE_MKDIR_H) | 355 #if defined(HAVE_MKDIR_H) |
340 if (mkdir (tmp.c_str (), S_IRWXU)) | 356 bool makeDirErr = false; |
| 357 makeDirErr = mkdir (tmp.c_str (), S_IRWXU); |
| 358 |
| 359 if (makeDirErr) |
341 { | 360 { |
342 NS_LOG_ERROR ("failed creating directory " << tmp); | 361 NS_LOG_ERROR ("failed creating directory " << tmp); |
343 } | 362 } |
344 #else | 363 #else |
345 #ifdef _WIN32 | 364 #ifdef _WIN32 |
346 if (CreateDirectory(tmp.c_str(), NULL)) | 365 if (CreateDirectory(tmp.c_str(), NULL)) |
347 { | 366 { |
348 NS_LOG_ERROR("failed creating directory " << path); | 367 NS_LOG_ERROR("failed creating directory " << path); |
349 } | 368 } |
350 #endif | 369 #endif |
(...skipping 10 matching lines...) Expand all Loading... |
361 #ifdef _WIN32 | 380 #ifdef _WIN32 |
362 if (CreateDirectory(path.c_str(), NULL)) | 381 if (CreateDirectory(path.c_str(), NULL)) |
363 { | 382 { |
364 NS_LOG_ERROR("failed creating directory " << path); | 383 NS_LOG_ERROR("failed creating directory " << path); |
365 } | 384 } |
366 #endif | 385 #endif |
367 #endif | 386 #endif |
368 | 387 |
369 } | 388 } |
370 | 389 |
371 } // namespace SystemPath | 390 std::string |
| 391 SystemPath::GetTopLevelSourceDir(void) |
| 392 { |
| 393 NS_LOG_FUNCTION_NOARGS(); |
| 394 std::string self = SystemPath::FindSelfDirectory(); |
| 395 std::list<std::string> elements = SystemPath::Split(self); |
| 396 while (!elements.empty()) |
| 397 { |
| 398 std::string path = SystemPath::Join(elements.begin(), elements.end()); |
| 399 if (IsTopLevelSourceDir(path)) |
| 400 { |
| 401 return path; |
| 402 } |
| 403 elements.pop_back(); |
| 404 } |
| 405 NS_FATAL_ERROR("Could not find source directory from self=" << self); |
| 406 } |
| 407 |
| 408 bool |
| 409 SystemPath::IsTopLevelSourceDir(std::string path) |
| 410 { |
| 411 NS_LOG_FUNCTION(path); |
| 412 bool haveVersion = false; |
| 413 bool haveLicense = false; |
| 414 |
| 415 // |
| 416 // If there's a file named VERSION and a file named LICENSE in this |
| 417 // directory, we assume it's our top level source directory. |
| 418 // |
| 419 |
| 420 std::list<std::string> files = SystemPath::ReadFiles(path); |
| 421 for (std::list<std::string>::const_iterator i = files.begin(); i != files.end(
); ++i) |
| 422 { |
| 423 if (*i == "VERSION") |
| 424 { |
| 425 haveVersion = true; |
| 426 } |
| 427 else if (*i == "LICENSE") |
| 428 { |
| 429 haveLicense = true; |
| 430 } |
| 431 } |
| 432 |
| 433 return haveVersion && haveLicense; |
| 434 } |
372 | 435 |
373 } // namespace ns3 | 436 } // namespace ns3 |
LEFT | RIGHT |