Implementing rmdir using C/ C++

Binary Tree Problems books

Get FREE domain for 1st year and build your brand new site

Today we are going to talk about a command which is widely used in bash for removing files/directories that command is named as rmdir command. The command rmdir stands for "removing directories", it's another way to remove a directory from UNIX based systems from command line. Using this command we can also remove multiple files and folders. So now, let's move to the initial setup of the program,

Initial Setup

So for the implementation of rmdir using C++ we will need the dirent.h header file in our directory, so first we will download the dirent repository and place it in our folder. We can download the header file from here : https://github.com/tronkko/dirent

So place it in the include folder of your project directory along with the rmdir.cpp file,

Tree listing of directory

Once we are done with this, we'll move to the implementation part of the program,

Implementation

So we will write our main code in the rmdir.cpp file, we'll open that file using any text editor and first include the header files required,

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <ftw.h>

So let's look into the header files and list them why are we using,

  • stdio.h : This file is used for input and output streams to the console.
  • dirent.h : This header file is used for directory pointers and objects.
  • stdlib.h : This header file is used for inbuilt library functions.
  • ftw.h : This header file is used for using the nftw function which is the traversion of the directory tree.

After this for removing the file/directory we'll create a function named rmFiles which takes in several arguments as parameters.

Let's cover the rmFiles function at the end and cover the main function now, so we have,

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr,"usage: %s path\n",argv[0]);
        exit(1);
    }
}

First we will cover the case if the number of arguments passed is more than 2 then we'll give the error message to the output, so if the argc != 2 then it'll print usage: path_of_file path. So now if the number of arguments is 2 then we'll remove the file or the directory addressed,

    if (nftw(argv[1],rmFiles,10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
    {
        perror("ERROR: ntfw");
        exit(1);
    }

Here we are using the nftw function to go into the directory and delete all it's interior contents, it the directory or the file doesn't exist it'll print out error, else will move to the rmFilesfunction passed in the argument. The ntfw function takes several argument such as,

  • argv[1] : This is the filename that we will pass to the function.
  • rmFiles : Name of the function which is to be called.
  • integer : Used to specify the depth
  • FTW_DEPTH : If set, nftw() shall report all files in a directory before reporting the directory itself. If clear, nftw() shall report any directory before reporting the files in that directory.
  • FTW_MOUNT : If set, nftw() shall only report files in the same file system as path. If clear, nftw() shall report all files encountered during the walk.
  • FTW_PHYS : If set, nftw() shall perform a physical walk and shall not follow symbolic links.

Below is the implementation of rmFiles function with the followed explanation of the function,

static int rmFiles(const char *pathname, const struct stat *sbuf, int type, struct FTW *ftwb)
{
    if(remove(pathname) < 0)
    {
        perror("ERROR: remove");
        return -1;
    }
    return 0;
}

The "static" keyword in the function tells that it doesn't require any object to call the function, so following this the function takes 4 arguments :

  • pathname : This specifies the path to be deleted.
  • sbuf : This specifies the stat object which gives the data about
  • type : This specifies the type of file to be deleted

Now in this function we'll use the remove() function, if the file is not removable we will return the error output else we will delete the file/directory,

static int rmFiles(const char *pathname, const struct stat *sbuf, int type, struct FTW *ftwb)
{
    if(remove(pathname) < 0)
    {
        perror("ERROR: remove");
        return -1;
    }
    return 0;
}

Let's quote the complete implementation below,

#include <stdio.h>
#include <stdlib.h>
#include <ftw.h>

static int rmFiles(const char *pathname, const struct stat *sbuf, int type, struct FTW *ftwb)
{
    if(remove(pathname) < 0)
    {
        perror("ERROR: remove");
        return -1;
    }
    return 0;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr,"usage: %s path\n",argv[0]);
        exit(1);
    }

    // Delete the directory and its contents by traversing the tree in reverse order, without crossing mount boundaries and symbolic links

    if (nftw(argv[1], rmFiles,10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
    {
        perror("ERROR: ntfw");
        exit(1);
    }

    return 0;
}

So let's compile and execute the program,

Execution

After writing the code we'll save the file and let's get back to the terminal where for compiling the code we'll type,

$ make rmdir

This command will create an excecutable file and we can run that file,
first lets create a directory named test that we will delete.

Listing the directory with  folder in it

So for executing the program we'll type the following,

$ ./rmdir test

Execution

As we can see that the folder named test is removed we can conclude that our program works correctly and hereby end this blog! Thankyou for reading!