forked from enlightenment/efl
aaagh. dirent... bad! too many things in dirent that are not portable
- d_type for example... so put that into the direct_info struct and handle the compat in eina. SVN revision: 54015
This commit is contained in:
parent
3d6e44bd91
commit
a08524ea65
|
@ -50,6 +50,22 @@ typedef struct _Eina_File_Direct_Info Eina_File_Direct_Info;
|
||||||
*/
|
*/
|
||||||
typedef void (*Eina_File_Dir_List_Cb)(const char *name, const char *path, void *data);
|
typedef void (*Eina_File_Dir_List_Cb)(const char *name, const char *path, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Eina_File_Type
|
||||||
|
* file type in Eina_File_Direct_Info.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
EINA_FILE_UNKNOWN,
|
||||||
|
EINA_FILE_FIFO,
|
||||||
|
EINA_FILE_CHR,
|
||||||
|
EINA_FILE_DIR,
|
||||||
|
EINA_FILE_BLK,
|
||||||
|
EINA_FILE_REG,
|
||||||
|
EINA_FILE_LNK,
|
||||||
|
EINA_FILE_SOCK,
|
||||||
|
EINA_FILE_WHT
|
||||||
|
} Eina_File_Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct _Eina_File_Direct_Info
|
* @struct _Eina_File_Direct_Info
|
||||||
* A structure to store informations of a path.
|
* A structure to store informations of a path.
|
||||||
|
@ -60,7 +76,8 @@ struct _Eina_File_Direct_Info
|
||||||
size_t name_length; /**< size of the filename/basename component */
|
size_t name_length; /**< size of the filename/basename component */
|
||||||
size_t name_start; /**< where the filename/basename component starts */
|
size_t name_start; /**< where the filename/basename component starts */
|
||||||
char path[PATH_MAX]; /**< the path */
|
char path[PATH_MAX]; /**< the path */
|
||||||
const struct dirent *dirent; /**< the dirent structure of the path */
|
const struct dirent *dirent; /**< the dirent structure of the path - don't use this if you want compatibility */
|
||||||
|
Eina_File_Type type; /**< file type */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -101,7 +101,11 @@ _eina_file_ls_iterator_next(Eina_File_Iterator *it, void **data)
|
||||||
((dp->d_name[1] == '\0') ||
|
((dp->d_name[1] == '\0') ||
|
||||||
((dp->d_name[1] == '.') && (dp->d_name[2] == '\0'))));
|
((dp->d_name[1] == '.') && (dp->d_name[2] == '\0'))));
|
||||||
|
|
||||||
|
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||||
|
length = dp->d_namlen;
|
||||||
|
#else
|
||||||
length = strlen(dp->d_name);
|
length = strlen(dp->d_name);
|
||||||
|
#endif
|
||||||
name = alloca(length + 2 + it->length);
|
name = alloca(length + 2 + it->length);
|
||||||
|
|
||||||
memcpy(name, it->dir, it->length);
|
memcpy(name, it->dir, it->length);
|
||||||
|
@ -145,6 +149,9 @@ _eina_file_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
|
||||||
{
|
{
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
#ifndef _DIRENT_HAVE_D_TYPE
|
||||||
|
struct stat st;
|
||||||
|
#endif
|
||||||
|
|
||||||
dp = alloca(offsetof(struct dirent, d_name) + pathconf(it->dir, _PC_NAME_MAX) + 1);
|
dp = alloca(offsetof(struct dirent, d_name) + pathconf(it->dir, _PC_NAME_MAX) + 1);
|
||||||
|
|
||||||
|
@ -155,7 +162,11 @@ _eina_file_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
|
||||||
if (!dp)
|
if (!dp)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||||
|
length = dp->d_namlen;
|
||||||
|
#else
|
||||||
length = strlen(dp->d_name);
|
length = strlen(dp->d_name);
|
||||||
|
#endif
|
||||||
if (it->info.name_start + length + 1 >= PATH_MAX)
|
if (it->info.name_start + length + 1 >= PATH_MAX)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +179,60 @@ _eina_file_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
|
||||||
it->info.path_length = it->info.name_start + length;
|
it->info.path_length = it->info.name_start + length;
|
||||||
it->info.path[it->info.path_length] = '\0';
|
it->info.path[it->info.path_length] = '\0';
|
||||||
it->info.dirent = dp;
|
it->info.dirent = dp;
|
||||||
|
#ifdef _DIRENT_HAVE_D_TYPE
|
||||||
|
switch (dp->d_type)
|
||||||
|
{
|
||||||
|
case DT_FIFO:
|
||||||
|
it->info.type = EINA_FILE_FIFO;
|
||||||
|
break;
|
||||||
|
case DT_CHR:
|
||||||
|
it->info.type = EINA_FILE_CHR;
|
||||||
|
break;
|
||||||
|
case DT_DIR:
|
||||||
|
it->info.type = EINA_FILE_DIR;
|
||||||
|
break;
|
||||||
|
case DT_BLK:
|
||||||
|
it->info.type = EINA_FILE_BLK;
|
||||||
|
break;
|
||||||
|
case DT_REG:
|
||||||
|
it->info.type = EINA_FILE_REG;
|
||||||
|
break;
|
||||||
|
case DT_LNK:
|
||||||
|
it->info.type = EINA_FILE_LNK;
|
||||||
|
break;
|
||||||
|
case DT_SOCK:
|
||||||
|
it->info.type = EINA_FILE_SOCK;
|
||||||
|
break;
|
||||||
|
case DT_WHT:
|
||||||
|
it->info.type = EINA_FILE_WHT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
it->info.type = EINA_FILE_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (stat(it->info.path, &st))
|
||||||
|
it->info.type = EINA_FILE_UNKNOWN;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (S_ISREG(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_REG;
|
||||||
|
else if (S_ISDIR(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_DIR;
|
||||||
|
else if (S_ISCHR(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_CHR;
|
||||||
|
else if (S_ISBLK(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_BLK;
|
||||||
|
else if (S_ISFIFO(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_FIFO;
|
||||||
|
else if (S_ISLNK(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_LNK;
|
||||||
|
else if (S_ISSOCK(st.st_mode))
|
||||||
|
it->info.type = EINA_FILE_SOCK;
|
||||||
|
else
|
||||||
|
it->info.type = EINA_FILE_UNKNOWN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
*data = &it->info;
|
*data = &it->info;
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -235,8 +300,12 @@ eina_file_dir_list(const char *dir,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
int dlength;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
DIR *d;
|
DIR *d;
|
||||||
|
#ifndef _DIRENT_HAVE_D_TYPE
|
||||||
|
struct stat st;
|
||||||
|
#endif
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE);
|
||||||
|
@ -246,6 +315,7 @@ eina_file_dir_list(const char *dir,
|
||||||
if (!d)
|
if (!d)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
dlength = strlen(dir);
|
||||||
de = alloca(offsetof(struct dirent, d_name) + pathconf(dir, _PC_NAME_MAX) + 1);
|
de = alloca(offsetof(struct dirent, d_name) + pathconf(dir, _PC_NAME_MAX) + 1);
|
||||||
|
|
||||||
while ((!readdir_r(d, de, &de) && de))
|
while ((!readdir_r(d, de, &de) && de))
|
||||||
|
@ -259,30 +329,26 @@ eina_file_dir_list(const char *dir,
|
||||||
if (recursive == EINA_TRUE)
|
if (recursive == EINA_TRUE)
|
||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
|
int length;
|
||||||
|
|
||||||
path = alloca(strlen(dir) + strlen(de->d_name) + 2);
|
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||||
|
length = de->d_namlen;
|
||||||
|
#else
|
||||||
|
length = strlen(de->d_name);
|
||||||
|
#endif
|
||||||
|
path = alloca(dlength + length + 2);
|
||||||
strcpy(path, dir);
|
strcpy(path, dir);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
strcat(path, de->d_name);
|
strcat(path, de->d_name);
|
||||||
#ifndef sun
|
#ifdef _DIRENT_HAVE_D_TYPE
|
||||||
if (de->d_type == DT_UNKNOWN)
|
if (de->d_type != DT_DIR)
|
||||||
{
|
continue;
|
||||||
#endif
|
#else
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(path, &st))
|
if (stat(path, &st))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode))
|
if (!S_ISDIR(st.st_mode))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#ifndef sun
|
|
||||||
}
|
|
||||||
else if (de->d_type != DT_DIR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
eina_file_dir_list(path, recursive, cb, data);
|
eina_file_dir_list(path, recursive, cb, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue