私のプログラムは、コマンド ラインで指定されたディレクトリの内容を読み取ります。ディレクトリを再帰的に読み取ります。つまり、ディレクトリ「test」の内容を読み取り、その中に別のディレクトリ「inside」がある場合、「inside」という名前のディレクトリの内容も読み取ります。問題は、隠しディレクトリ、つまり「。」で始まるディレクトリを読み取らなくても正常に機能することです。. しかし、隠しディレクトリも読んだ場合、セグメンテーション違反と表示されます。
コードは次のとおりです。
メインファイル:
#include "helper.h"
/*
* Display's content of String array passed to it,
* that should conatin full path to files.
*/
void display(char **);
/*
* Free's the memory utilized by the program
*/
void cleanup(char **);
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
printf("Usage: %s [dir]\n\n", argv[0]);
return 1;
}
char **files = calloc(1, sizeof(char *));
// get files from the directory specified
getFiles(&files, argv[1]);
// display files
display(files);
// free memory utilized by files array
cleanup(files);
// that's all folks
return 0;
}
/*
* Display's content of String array passed to it,
* that should conatin full path to files.
*/
void display(char **files)
{
// Color Red
// printf("[0;31;40m");
// display files
for (int i = 0; files[i]; i++)
{
printf("%s\n", files[i]);
}
// turn off color
// printf("[0;37;40m");
}
/*
* Free's the memory utilized by the program
*/
void cleanup(char **files)
{
// free memory utilized by files array
for (int i = 0; files[i]; i++)
free(files[i]);
free(files);
}
getFiles 関数は、次のコードを含む helpers.c ファイルで定義されています。
#include "helper.h"
#include <dirent.h>
#include <stdlib.h>
#include <sys/types.h>
/*
* Stores the list of files present in direectory pointed by 'dir'
* in array of strings pointed by 'files'
*/
void getFiles(char ***files, const char* dir)
{
static int i;
// ensure directory is valid
if (dir == NULL)
{
printf("Error: Invalid Directory\n\n");
exit(1);
}
// declare and initialize directory handler
DIR *dd = opendir(dir);
if (dd == NULL)
{
printf("Error: Directory Not Found\n\n");
exit(2);
}
// structure that store file attributes read
struct dirent *content;
// read directory until all files are scanned
while ((content = readdir(dd)) != NULL)
{
// ignore '.' and '..' directories
if (strcmp(content->d_name, ".") == 0 ||
strcmp(content->d_name, "..") == 0)
continue;
/*if (content->d_name[0] == '.')
continue;*/
//store full file path from current directory
char temp[1024] = {0};
// make full path
makepath(temp, dir, content->d_name);
// recall itself if another directory found
if (isdir(temp))
{
// read this new directory found
getFiles(files, temp);
continue;
}
// allocate memory to store locations of char *
*files = realloc(*files, (i + 2)*(sizeof(char *)));
// allocate heap memory and store location
*(*(files + 0) + i) = (char *)strdup(temp);
// move to next location
i++;
}
// free directory handler
closedir(dd);
// set NULL after last file name
*(*(files + 0) + i) = '\0';
}
/*
* returns true if 'dir' refers to a directory, false otherwise
*/
bool isdir(const char * dir)
{
DIR *temp;
temp = opendir(dir);
if (temp != NULL)
{
closedir(temp);
return true;
}
return false;
}
/*
* appends dir and file/directory name to src,
* thus makes a full file/directory path, from current directory
*/
void makepath(char src[], const char *dir, const char *file)
{
// prepend directory name
strcat(src, dir);
strcat(src, "/");
// append file/directory name
strcat(src, file);
}
必要なヘッダー ファイルは、helper.h ファイルに含まれています。
また、メモリ割り当てを間違えているのか知りたいと思っていました。(getFiles 関数の realloc で)。
隠しファイルを無視する行は、現時点で私がコメントしています。
/*if (content->d_name[0] == '.')
continue;*/
上記の行のコメントを外すと、プログラムは正常に動作します。
readdir関数で読み取ったファイル名を保存している理由を考えている場合は、これらの名前が後で必要になるため、すぐにファイル名を表示しないのです。
このプログラムをより適切に実装する方法と、隠しディレクトリを読み取ったときに発生する問題を修正する方法についての提案。