Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * main.cpp
- *
- * Created on: 23.08.2013
- * Author: artem
- *
- * You can use c++ online compiler to test the behaviour.
- * Compiler: http://www.compileonline.com/compile_cpp_online.php
- *
- *Test case 1:
- * Input to command line argument string (without " symbols) "./../"
- * Should work ok.
- *
- * Test case 2:
- * Input: "./.."
- * Fails silently. (Current dir is shown by me, before call to readdir_r and stat.)
- */
- #include <stdexcept>
- #include <cerrno>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <unistd.h>
- #include <cstddef>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <stack>
- using namespace std;
- class IOFileAccessException : public std::runtime_error {
- public:
- IOFileAccessException(const std::string& filename, const std::string& operation, int errcode);
- IOFileAccessException(const IOFileAccessException& exc);
- virtual ~IOFileAccessException() throw() {}
- };
- IOFileAccessException::IOFileAccessException(
- const std::string& filename,
- const std::string& operation,
- int errcode)
- : runtime_error("Error on access to file \'" + filename +
- "\'. Failed operation: \'" + operation + "\'. Error message: " + strerror(errcode)) {
- }
- IOFileAccessException::IOFileAccessException(const IOFileAccessException& exc)
- : runtime_error(exc.what()) {
- }
- void ClearDirs(const string& dir) {
- // stack<string> files;
- stack<string> dirs;
- // Выделим память под структуру
- long int name_max = pathconf(dir.c_str(), _PC_NAME_MAX);
- if (name_max == -1) /* Limit not defined, or error */
- name_max = 255; /* Take a guess */
- long int len = offsetof(struct dirent, d_name) + name_max + 1;
- struct dirent *thedir = static_cast<struct dirent*>(malloc(len));
- dirs.push(dir);
- try {
- while (!dirs.empty()) {
- string currentdir = dirs.top();
- dirs.pop();
- cout << endl << "current dir: " << currentdir << endl;
- DIR* d = opendir(currentdir.c_str());
- if (d == NULL) {
- int err = errno;
- throw IOFileAccessException(dir, "opendir", err);
- }
- struct dirent *result = NULL;
- do {
- int res = readdir_r(d, thedir, &result);
- if (res > 0) {
- throw IOFileAccessException(currentdir, "readdir_r", res);
- }
- if (result == NULL) {
- continue;
- }
- if (strncmp(result->d_name, ".", 1) == 0 ||
- strncmp(result->d_name, "..", 2) == 0) {
- continue;
- }
- string d_name = currentdir + result->d_name;
- //files.push(d_name);
- struct stat buf;
- res = stat(d_name.c_str(), &buf);
- if (res == -1) {
- int err = errno;
- throw IOFileAccessException(d_name, "stat (directory is \'" + currentdir + "\')", err);
- }
- if (S_ISDIR(buf.st_mode)) {
- d_name += "/";
- dirs.push(d_name);
- cout << "dir: " << d_name << endl;
- }
- else {
- cout << "file: " << d_name << endl;
- }
- } while (result != NULL);
- int res = closedir(d);
- if (res == -1) {
- int err = errno;
- throw IOFileAccessException(currentdir, "closedir", err);
- }
- }
- free(thedir); thedir = NULL;
- }
- catch(...) {
- free(thedir); thedir = NULL;
- }
- // идём вглубь и складываем имена папок и файлов в стэк
- }
- int main(int argc, char *argv[]) {
- for (int i = 0; i < argc; ++i) {
- cout << argv[i] << endl;
- }
- cout << "------" << endl;
- string dir = "./";
- if (argc > 1) {
- dir = argv[1];
- }
- try {
- ClearDirs(dir);
- }
- catch(const exception& exc) {
- cerr << exc.what() << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement