Advertisement
Guest User

readdir_r example works ok but on exception terminates app

a guest
Aug 23rd, 2013
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.57 KB | None | 0 0
  1. /*
  2.  * main.cpp
  3.  *
  4.  *  Created on: 23.08.2013
  5.  *      Author: artem
  6.  *
  7.  * You can use c++ online compiler to test the behaviour.
  8.  * Compiler: http://www.compileonline.com/compile_cpp_online.php
  9.  *
  10.  *Test case 1:
  11.  * Input to command line argument string (without " symbols) "./../"
  12.  * Should work ok.
  13.  *
  14.  * Test case 2:
  15.  * Input: "./.."
  16.  * Fails silently. (Current dir is shown by me, before call to readdir_r and stat.)
  17.  */
  18.  
  19. #include <stdexcept>
  20. #include <cerrno>
  21. #include <cstring>
  22. #include <cstdlib>
  23. #include <iostream>
  24. #include <unistd.h>
  25.  
  26. #include <cstddef>
  27. #include <sys/stat.h>
  28. #include <sys/types.h>
  29. #include <dirent.h>
  30.  
  31. #include <stack>
  32.  
  33.  
  34. using namespace std;
  35.  
  36.  
  37. class IOFileAccessException : public std::runtime_error {
  38. public:
  39.     IOFileAccessException(const std::string& filename, const std::string& operation, int errcode);
  40.     IOFileAccessException(const IOFileAccessException& exc);
  41.     virtual ~IOFileAccessException() throw() {}
  42. };
  43.  
  44. IOFileAccessException::IOFileAccessException(
  45.         const std::string& filename,
  46.         const std::string& operation,
  47.         int errcode)
  48.     : runtime_error("Error on access to file \'" + filename +
  49.             "\'. Failed operation: \'" + operation + "\'. Error message: " + strerror(errcode)) {
  50.     }
  51.  
  52. IOFileAccessException::IOFileAccessException(const IOFileAccessException& exc)
  53. : runtime_error(exc.what()) {
  54. }
  55.  
  56. void ClearDirs(const string& dir) {
  57. //  stack<string> files;
  58.     stack<string> dirs;
  59.  
  60.     // Выделим память под структуру
  61.  
  62.     long int name_max = pathconf(dir.c_str(), _PC_NAME_MAX);
  63.     if (name_max == -1)         /* Limit not defined, or error */
  64.         name_max = 255;         /* Take a guess */
  65.     long int len = offsetof(struct dirent, d_name) + name_max + 1;
  66.  
  67.     struct dirent *thedir = static_cast<struct dirent*>(malloc(len));
  68.  
  69.     dirs.push(dir);
  70.  
  71.     try {
  72.         while (!dirs.empty()) {
  73.             string currentdir = dirs.top();
  74.             dirs.pop();
  75.  
  76.             cout << endl << "current dir: " << currentdir << endl;
  77.  
  78.             DIR* d = opendir(currentdir.c_str());
  79.             if (d == NULL) {
  80.                 int err = errno;
  81.                 throw IOFileAccessException(dir, "opendir", err);
  82.             }
  83.  
  84.             struct dirent *result = NULL;
  85.             do {
  86.                 int res = readdir_r(d, thedir, &result);
  87.                 if (res > 0) {
  88.                     throw IOFileAccessException(currentdir, "readdir_r", res);
  89.                 }
  90.                 if (result == NULL) {
  91.                     continue;
  92.                 }
  93.  
  94.                 if (strncmp(result->d_name, ".", 1) == 0 ||
  95.                     strncmp(result->d_name, "..", 2) == 0) {
  96.                     continue;
  97.                 }
  98.  
  99.                 string d_name = currentdir + result->d_name;
  100.                 //files.push(d_name);
  101.  
  102.                 struct stat buf;
  103.                 res = stat(d_name.c_str(), &buf);
  104.                 if (res == -1) {
  105.                     int err = errno;
  106.                     throw IOFileAccessException(d_name, "stat (directory is \'" + currentdir + "\')", err);
  107.                 }
  108.  
  109.                 if (S_ISDIR(buf.st_mode)) {
  110.                     d_name += "/";
  111.                     dirs.push(d_name);
  112.                     cout << "dir: " << d_name << endl;
  113.                 }
  114.                 else {
  115.                     cout << "file: " << d_name << endl;
  116.                 }
  117.  
  118.             } while (result != NULL);
  119.  
  120.             int res = closedir(d);
  121.             if (res == -1) {
  122.                 int err = errno;
  123.                 throw IOFileAccessException(currentdir, "closedir", err);
  124.             }
  125.         }
  126.  
  127.         free(thedir); thedir = NULL;
  128.     }
  129.     catch(...) {
  130.         free(thedir); thedir = NULL;
  131.     }
  132.  
  133.     // идём вглубь и складываем имена папок и файлов в стэк
  134. }
  135.  
  136. int main(int argc, char *argv[]) {
  137.     for (int i = 0; i < argc; ++i) {
  138.         cout << argv[i] << endl;
  139.     }
  140.     cout << "------" << endl;
  141.     string dir = "./";
  142.     if (argc > 1) {
  143.         dir = argv[1];
  144.     }
  145.  
  146.     try {
  147.         ClearDirs(dir);
  148.     }
  149.     catch(const exception& exc) {
  150.         cerr << exc.what() << endl;
  151.     }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement