Note: The correct function name in Ubuntu/Linux systems is opendir (not “copendir”), which is part of the POSIX standard for opening directories. Below are detailed operations for using opendir and related functions.
To use opendir, you must include the <dirent.h> header (for directory operations) and optionally <stdio.h>, <stdlib.h>, and <errno.h> for error handling and standard I/O.
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h> // For stat() (used in recursive traversal)
opendirThe opendir function takes a directory path as input and returns a DIR* pointer (representing the directory stream). If it fails (e.g., invalid path or permission issues), it returns NULL and sets errno.
DIR *dir = opendir("/path/to/target_directory");
if (dir == NULL) {
perror("Error opening directory"); // Prints error message (e.g., "No such file or directory")
exit(EXIT_FAILURE);
}
readdirUse readdir to iterate through directory entries. Each call returns a struct dirent* containing the entry name (d_name). Skip the special entries "." (current directory) and ".." (parent directory) to avoid recursion issues.
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
// Skip "." and ".."
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
printf("Entry: %s\n", entry->d_name); // Print entry name
}
closedirAlways close the directory stream after use to free system resources. Check the return value (0 for success, -1 for failure).
if (closedir(dir) == -1) {
perror("Error closing directory");
exit(EXIT_FAILURE);
}
A simple program that lists all files/subdirectories in a given path:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <directory_path>\n", argv[0]);
return EXIT_FAILURE;
}
DIR *dir = opendir(argv[1]);
if (dir == NULL) {
perror("opendir");
return EXIT_FAILURE;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
printf("%s\n", entry->d_name);
}
if (closedir(dir) == -1) {
perror("closedir");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Compile & Run:
gcc -o list_dir list_dir.c
./list_dir /path/to/target_directory
To recursively copy a directory (including subdirectories and files), extend the above logic with stat (to check file types) and file I/O operations. Below is a simplified version:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
void copy_file(const char *src, const char *dest) {
FILE *src_file = fopen(src, "rb");
if (!src_file) {
perror("fopen (src)");
return;
}
FILE *dest_file = fopen(dest, "wb");
if (!dest_file) {
perror("fopen (dest)");
fclose(src_file);
return;
}
char buffer[1024];
size_t bytes_read;
while ((bytes_read = fread(buffer, 1, sizeof(buffer), src_file)) > 0) {
fwrite(buffer, 1, bytes_read, dest_file);
}
fclose(src_file);
fclose(dest_file);
}
void copy_directory(const char *src, const char *dest) {
DIR *dir = opendir(src);
if (!dir) {
perror("opendir");
return;
}
// Create destination directory if it doesn't exist
struct stat st = {0};
if (stat(dest, &st) == -1) {
mkdir(dest, 0755);
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char src_path[1024], dest_path[1024];
snprintf(src_path, sizeof(src_path), "%s/%s", src, entry->d_name);
snprintf(dest_path, sizeof(dest_path), "%s/%s", dest, entry->d_name);
if (stat(src_path, &st) == -1) {
perror("stat");
continue;
}
if (S_ISDIR(st.st_mode)) {
copy_directory(src_path, dest_path); // Recurse for directories
} else {
copy_file(src_path, dest_path); // Copy files
}
}
closedir(dir);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <source_directory> <destination_directory>\n", argv[0]);
return EXIT_FAILURE;
}
copy_directory(argv[1], argv[2]);
printf("Directory copied successfully.\n");
return EXIT_SUCCESS;
}
Compile & Run:
gcc -o copy_dir copy_dir.c
./copy_dir /path/to/source /path/to/destination
opendir, readdir, and closedir. Use perror to print human-readable error messages."." and ".." to avoid infinite loops during recursion.lstat instead of stat if you need to process them differently.For actual directory copying, consider using the built-in cp -r command (more efficient and robust) unless you need custom logic.