Listing 7: Illustrates an exception class

// ddir4.cpp:  Remove subdirectory tree

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include <sys/stat.h>
#include <setjmp.h>
#include <dirent.h>
#include <dir.h>

#include <stdexcept>
#include <string>
using namespace std;

// Exception class
struct dir_error : public runtime_error
{
    dir_error(const string& msg) : runtime_error(msg){}
};

main(int argc, char** argv)
{
    char* old_path = getcwd(NULL,64);
    void rd(const char*);

    while (--argc)
    {
        try
        {
            rd((const char*) *++argv);
        }
        catch (const dir_error& x)
        {
            printf("Directory error: %s\n",x.what());
        }
        catch (const exception& x)
        {
            printf("Error: %s\n",x.what());
        }
        catch (...)
        {
            puts("Unknown error");
        }
    }
    
    // Clean-up :
    chdir(old_path);
}

void rd(const char* dir)
{
    if (chdir(dir) != 0)
        throw dir_error("Invalid directory");
    system("del /q *.* > nul");

    erase_dir();

    chdir("..");
    if (rmdir(dir) != 0)
        throw dir_error("Error deleting directory");
}

void erase_dir()
{
    if ((dirp = opendir(".")) == NULL)
        throw dir_error("Error opening directory");
    struct dirent* entry;

    while ((entry = readdir(dirp)) != NULL)
    {
        if (entry->d_name[0] == '.')
            continue;
        struct stat finfo;
        stat(entry->d_name,&finfo);
        if (finfo.st_mode & S_IFDIR)
            rd(entry->d_name);      
        else
        {
            chmod(entry->d_name,S_IWRITE);
            if (unlink(entry->d_name))
            {
                closedir(dirp);
                throw dir_error("Error deleting file");
            }
        }
    }
    closedir(dirp);
}
//End of File