Use the opendir Function in C

Use the opendir Function in C

Lasha Khintibidze Mar-05, 2021 Feb-20, 2021 C C File
  1. Use the opendir Function to Open a Directory Stream
  2. Use the readdir Function to Iterate Over Directory Entries

This article will explain several methods of how to use the opendir function in C.

Use the opendir Function to Open a Directory Stream

The opendir function is part of the POSIX specification and is defined in <dirent.h> header file. The function takes a single char pointer argument to specify the directory name to open. opendir returns DIR* structure or NULL if an error is encountered. DIR data type is implemented to represent directory stream, but the user should not allocate objects of the DIR type. In the following example code, we take the directory name from the first command-line argument and pass the value to the opendir function.

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

int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./program directory_name\n");
        exit(EXIT_FAILURE);
    }

    dp = opendir(argv[1]);

    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    closedir(dp);
    exit(EXIT_SUCCESS);
}

Use the readdir Function to Iterate Over Directory Entries

Once the directory stream is open and we retrieved the valid DIR*, we can read each entry in it using the readdir function. Each call to readdir function returns a pointer to dirent structure representing the next directory entry. When the end of the directory stream is reached, readdir returns NULL. Thus, we implemented a simple while loop that prints every entry in the opened directory stream. We modified code around opendir and closedir function calls to check for errors and output the corresponding message for debugging. It’s always good and secure practice to check if the library functions returned successfully.

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

int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./program directory_name\n");
        exit(EXIT_FAILURE);
    }

    errno = 0;
    if ((dp = opendir(argv[1])) == NULL) {
        switch (errno) {
            case EACCES: printf("Permission denied\n"); break;
            case ENOENT: printf("Directory does not exist\n"); break;
            case ENOTDIR: printf("'%s' is not a directory\n", argv[1]); break;
        }
        exit(EXIT_FAILURE);
    }

    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    if (closedir(dp) == -1)
        perror("closedir");

    exit(EXIT_SUCCESS);
}

Alternatively, we can add some error checking conditional statements for the readdir function because the previous example may yield unclear output when the directory name is invalid or a different error occurred. The following code will additionally output the end-of-directory reached status after the successful iteration.

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

int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./program directory_name\n");
        exit(EXIT_FAILURE);
    }

    errno = 0;
    if ((dp = opendir(argv[1])) == NULL) {
        switch (errno) {
            case EACCES: printf("Permission denied\n"); break;
            case ENOENT: printf("Directory does not exist\n"); break;
            case ENOTDIR: printf("'%s' is not a directory\n", argv[1]); break;
        }
        exit(EXIT_FAILURE);
    }

    errno = 0;
    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    if (errno != 0) {
        if (errno == EBADF)
            printf("Invalid directory stream descriptor\n");
        else
            perror("readdir");
    } else {
        printf("End-of-directory reached\n");
    }

    if (closedir(dp) == -1)
        perror("closedir");

    exit(EXIT_SUCCESS);
}

Related Article - C File

  • File Descriptor in C
  • Read Until End of File in C
  • Get Extended Attributes of File in C
  • Read Binary File in C
  • Read File Line by Line Using fscanf in C