私はプログラムの一部がすべてのディレクトリ(特に/から始まっている)をリストしていますが、/ proc/selfは無限に再帰的です(proc /タスク/ 4300/fd/3/proc/self /タスク/ 4300/fd/3/proc/self/task/4300/fd/3/proc/...など)。それに対処する良い方法は何ですか?linuxにディレクトリを列挙しているときに無限再帰
EDIT:プログラムはC言語で書かれていると私は(opendir関数を使用)、readdir関数()
私はプログラムの一部がすべてのディレクトリ(特に/から始まっている)をリストしていますが、/ proc/selfは無限に再帰的です(proc /タスク/ 4300/fd/3/proc/self /タスク/ 4300/fd/3/proc/self/task/4300/fd/3/proc/...など)。それに対処する良い方法は何ですか?linuxにディレクトリを列挙しているときに無限再帰
EDIT:プログラムはC言語で書かれていると私は(opendir関数を使用)、readdir関数()
S_ISLNK macro to test the st_mode fieldは、lstatの呼び出しによって返されます。ファイルがシンボリックリンクの場合は、それに従わないでください。
[[email protected]:~]:./list | grep link
/proc/mounts is a symbolic link
/proc/self is a symbolic link
例コード
#include <stdio.h> // For perror
#include <stdlib.h>
#include <sys/types.h> // For stat, opendir, readdir
#include <sys/stat.h> // For stat
#include <unistd.h> // For stat
#include <dirent.h> // For opendir, readdir
const char *prefix = "/proc";
int main(void)
{
DIR *dir;
struct dirent *entry;
int result;
struct stat status;
char path[PATH_MAX];
dir = opendir(prefix);
if (!dir)
{
perror("opendir");
exit(1);
}
entry = readdir(dir);
while (entry)
{
result = snprintf(path, sizeof(path), "%s", prefix);
snprintf(&path[result], sizeof(path) - result, "/%s", entry->d_name);
printf("%s", path);
result = lstat(path, &status);
if (-1 == result)
{
printf("\n");
perror("stat");
exit(2);
}
if (S_ISLNK(status.st_mode))
{
printf("%s", " is a symbolic link");
}
printf("\n");
entry = readdir(dir);
}
return(0);
}
path_resolution(7)
から:
Length limit There is a maximum length for pathnames. If the pathname (or some intermediate pathname obtained while resolving symbolic links) is too long, an ENAMETOOLONG error is returned ("File name too long").
私はあなたが同様の行動を採用すべきだと思う:あまりにをチェック長いですパス名。
私は便利な* nix端末を持っていませんが、いつでもls.c
のソースを見て、それがどのように完了したかを見てください。
gnuコアの一部としてのソースは、hereで見つけることができます。
私は数年前に学校でlsクローンを作成しました。私は、ulidtkoが言及したように、パス名のサイズを見て周りにいると思います。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/param.h>
/* Short & sweet recursive directory scan, finds regular files only.
Good starting point, should work on Linux OS.
Pass the root path, and returns number of dirs and number of files
found.
*/
char *tree_scan(const char *path, int *ndirs, int *nfiles){
DIR *dir;
struct dirent *entry;
char spath[MAXPATHLEN] = "";
if(!(dir = opendir(path))){ perror("opendir"); exit(1);}
for(entry = readdir(dir); entry; entry = readdir(dir)){
sprintf(spath, "%s/%s", path, entry->d_name);
if(entry->d_type == DT_REG){ (*nfiles)++; printf("%s\n", spath);}
if(entry->d_type == DT_DIR &&
(strcmp(".", entry->d_name)) &&
(strcmp("..", entry->d_name))){
(*ndirs)++; tree_scan(spath, ndirs, nfiles);
}
}
closedir(dir);
return(0);
}
/*そう*/
int i = 0, l = 0;
tree_scan("/path", &i, &l);
printf("Scanned %d directories, %d files.\n", i, l);
あなたはすべてのディレクトリinodeを追跡し、横断ないと考えているようにそれを呼び出しますあなたがすでにそれを見たことがあれば? – Gabe
はい、私は、より洗練された解決策があり、あまりにも多くのメモリを消費しないと考えていました。 – chris
あなたが見たすべてのinodeを追跡する必要はなく、同じパスの以前の要素のiノード番号だけを追跡する必要はありません。 –