enhanded qse_dir_read()
This commit is contained in:
parent
1b600ee20c
commit
e5a9693411
@ -34,7 +34,7 @@ POST_UNINSTALL = :
|
|||||||
build_triplet = @build@
|
build_triplet = @build@
|
||||||
host_triplet = @host@
|
host_triplet = @host@
|
||||||
subdir = .
|
subdir = .
|
||||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||||
$(srcdir)/Makefile.in $(srcdir)/README.in \
|
$(srcdir)/Makefile.in $(srcdir)/README.in \
|
||||||
$(top_srcdir)/configure ac/config.guess ac/config.sub \
|
$(top_srcdir)/configure ac/config.guess ac/config.sub \
|
||||||
ac/depcomp ac/install-sh ac/ltmain.sh ac/missing
|
ac/depcomp ac/install-sh ac/ltmain.sh ac/missing
|
||||||
|
30
qse/configure
vendored
30
qse/configure
vendored
@ -15745,6 +15745,36 @@ _ACEOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtime" "ac_cv_member_struct_stat_st_birthtime" "$ac_includes_default"
|
||||||
|
if test "x$ac_cv_member_struct_stat_st_birthtime" = x""yes; then :
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec" "ac_cv_member_struct_stat_st_mtim_tv_nsec" "$ac_includes_default"
|
||||||
|
if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = x""yes; then :
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec.tv_nsec" "ac_cv_member_struct_stat_st_mtimespec_tv_nsec" "$ac_includes_default"
|
||||||
|
if test "x$ac_cv_member_struct_stat_st_mtimespec_tv_nsec" = x""yes; then :
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# The cast to long int works around a bug in the HP C Compiler
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
@ -109,6 +109,9 @@ AC_CHECK_FUNCS([powf fmodf sinf cosf tanf atanf atan2f logf expf sqrtf])
|
|||||||
LIBS="$OLDLIBS"
|
LIBS="$OLDLIBS"
|
||||||
|
|
||||||
AC_STRUCT_DIRENT_D_TYPE
|
AC_STRUCT_DIRENT_D_TYPE
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_birthtime])
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec])
|
||||||
|
|
||||||
dnl check the size of primitive data types
|
dnl check the size of primitive data types
|
||||||
AC_CHECK_SIZEOF(char,,[[]])
|
AC_CHECK_SIZEOF(char,,[[]])
|
||||||
|
@ -53,12 +53,16 @@
|
|||||||
|
|
||||||
#define QSE_USECS_PER_MSEC (1000)
|
#define QSE_USECS_PER_MSEC (1000)
|
||||||
#define QSE_NSECS_PER_USEC (1000)
|
#define QSE_NSECS_PER_USEC (1000)
|
||||||
|
#define QSE_NSECS_PER_MSEC (QSE_NSECS_PER_USEC*QSE_USECS_PER_MSEC)
|
||||||
#define QSE_USECS_PER_SEC (QSE_USECS_PER_MSEC*QSE_MSECS_PER_SEC)
|
#define QSE_USECS_PER_SEC (QSE_USECS_PER_MSEC*QSE_MSECS_PER_SEC)
|
||||||
|
|
||||||
#define QSE_IS_LEAPYEAR(year) ((!((year)%4) && ((year)%100)) || !((year)%400))
|
#define QSE_IS_LEAPYEAR(year) ((!((year)%4) && ((year)%100)) || !((year)%400))
|
||||||
#define QSE_DAYS_PER_YEAR(year) \
|
#define QSE_DAYS_PER_YEAR(year) \
|
||||||
(QSE_IS_LEAPYEAR(year)? QSE_DAYS_PER_LEAPYEAR: QSE_DAYS_PER_NORMYEAR)
|
(QSE_IS_LEAPYEAR(year)? QSE_DAYS_PER_LEAPYEAR: QSE_DAYS_PER_NORMYEAR)
|
||||||
|
|
||||||
|
#define QSE_SECNSEC_TO_MSEC(sec,nsec) \
|
||||||
|
(((qse_ntime_t)(sec) * QSE_MSECS_PER_SEC) + ((qse_ntime_t)(nsec) / QSE_NSECS_PER_MSEC))
|
||||||
|
|
||||||
/* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970) */
|
/* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970) */
|
||||||
typedef qse_long_t qse_ntime_t;
|
typedef qse_long_t qse_ntime_t;
|
||||||
typedef struct qse_btime_t qse_btime_t;
|
typedef struct qse_btime_t qse_btime_t;
|
||||||
@ -95,7 +99,6 @@ int qse_gettime (
|
|||||||
int qse_settime (
|
int qse_settime (
|
||||||
qse_ntime_t nt
|
qse_ntime_t nt
|
||||||
);
|
);
|
||||||
/******/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,7 +140,7 @@ int qse_timelocal (
|
|||||||
* The qse_strftime() functions formats time.
|
* The qse_strftime() functions formats time.
|
||||||
*/
|
*/
|
||||||
qse_size_t qse_strftime (
|
qse_size_t qse_strftime (
|
||||||
qse_char_t* buf,
|
qse_char_t* buf,
|
||||||
qse_size_t size,
|
qse_size_t size,
|
||||||
const qse_char_t* fmt,
|
const qse_char_t* fmt,
|
||||||
qse_btime_t* bt
|
qse_btime_t* bt
|
||||||
|
@ -178,6 +178,15 @@
|
|||||||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||||||
#undef HAVE_STRUCT_DIRENT_D_TYPE
|
#undef HAVE_STRUCT_DIRENT_D_TYPE
|
||||||
|
|
||||||
|
/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
|
||||||
|
#undef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||||
|
|
||||||
|
/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
|
||||||
|
#undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||||
|
|
||||||
|
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||||
|
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||||
|
|
||||||
/* Define to 1 if you have the `sysconf' function. */
|
/* Define to 1 if you have the `sysconf' function. */
|
||||||
#undef HAVE_SYSCONF
|
#undef HAVE_SYSCONF
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <qse/types.h>
|
#include <qse/types.h>
|
||||||
#include <qse/macros.h>
|
#include <qse/macros.h>
|
||||||
|
#include <qse/cmn/time.h>
|
||||||
|
|
||||||
enum qse_dir_errnum_t
|
enum qse_dir_errnum_t
|
||||||
{
|
{
|
||||||
@ -38,20 +39,46 @@ enum qse_dir_errnum_t
|
|||||||
};
|
};
|
||||||
typedef enum qse_dir_errnum_t qse_dir_errnum_t;
|
typedef enum qse_dir_errnum_t qse_dir_errnum_t;
|
||||||
|
|
||||||
|
enum qse_dir_ent_flag_t
|
||||||
|
{
|
||||||
|
QSE_DIR_ENT_NAME = (1 << 0),
|
||||||
|
QSE_DIR_ENT_TYPE = (1 << 1),
|
||||||
|
QSE_DIR_ENT_SIZE = (1 << 2),
|
||||||
|
QSE_DIR_ENT_TIME = (1 << 3)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum qse_dir_ent_type_t
|
||||||
|
{
|
||||||
|
QSE_DIR_ENT_UNKNOWN,
|
||||||
|
QSE_DIR_ENT_SUBDIR,
|
||||||
|
QSE_DIR_ENT_REGULAR,
|
||||||
|
QSE_DIR_ENT_CHRDEV,
|
||||||
|
QSE_DIR_ENT_BLKDEV,
|
||||||
|
QSE_DIR_ENT_SYMLINK,
|
||||||
|
QSE_DIR_ENT_PIPE
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum qse_dir_ent_type_t qse_dir_ent_type_t;
|
||||||
|
|
||||||
struct qse_dir_ent_t
|
struct qse_dir_ent_t
|
||||||
{
|
{
|
||||||
enum
|
int flags;
|
||||||
|
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
QSE_DIR_ENT_UNKNOWN,
|
qse_char_t* base;
|
||||||
QSE_DIR_ENT_DIR,
|
qse_char_t* path;
|
||||||
QSE_DIR_ENT_REG,
|
} name;
|
||||||
QSE_DIR_ENT_FIFO,
|
qse_dir_ent_type_t type;
|
||||||
QSE_DIR_ENT_CHAR,
|
qse_foff_t size;
|
||||||
QSE_DIR_ENT_BLOCK,
|
|
||||||
QSE_DIR_ENT_LINK
|
struct
|
||||||
} type;
|
{
|
||||||
qse_char_t* name;
|
qse_ntime_t create;
|
||||||
qse_foff_t size;
|
qse_ntime_t access;
|
||||||
|
qse_ntime_t modify;
|
||||||
|
qse_ntime_t change; /* inode status change */
|
||||||
|
} time;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct qse_dir_ent_t qse_dir_ent_t;
|
typedef struct qse_dir_ent_t qse_dir_ent_t;
|
||||||
@ -70,10 +97,10 @@ typedef struct qse_dir_t qse_dir_t;
|
|||||||
enum qse_dir_option_t
|
enum qse_dir_option_t
|
||||||
{
|
{
|
||||||
/**< don't follow a symbolic link in qse_dir_change() */
|
/**< don't follow a symbolic link in qse_dir_change() */
|
||||||
QSE_DIR_NOFOLLOW = (1 << 0),
|
QSE_DIR_NOFOLLOW = (1 << 1),
|
||||||
|
|
||||||
/**< check directories against file system in qse_dir_change() */
|
/**< check directories against file system in qse_dir_change() */
|
||||||
QSE_DIR_REALPATH = (1 << 1)
|
QSE_DIR_REALPATH = (1 << 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -109,7 +136,8 @@ const qse_char_t* qse_dir_geterrmsg (
|
|||||||
);
|
);
|
||||||
|
|
||||||
qse_dir_ent_t* qse_dir_read (
|
qse_dir_ent_t* qse_dir_read (
|
||||||
qse_dir_t* dir
|
qse_dir_t* dir,
|
||||||
|
int flags
|
||||||
);
|
);
|
||||||
|
|
||||||
int qse_dir_change (
|
int qse_dir_change (
|
||||||
|
291
qse/lib/fs/dir.c
291
qse/lib/fs/dir.c
@ -415,11 +415,35 @@ static int set_entry_name (qse_dir_t* dir, const qse_mchar_t* name)
|
|||||||
len++;
|
len++;
|
||||||
qse_mbstowcs (name, info->name.ptr, &len);
|
qse_mbstowcs (name, info->name.ptr, &len);
|
||||||
#endif
|
#endif
|
||||||
dir->ent.name = info->name.ptr;
|
|
||||||
|
dir->ent.name.base = info->name.ptr;
|
||||||
|
dir->ent.flags |= QSE_DIR_ENT_NAME;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
|
#if defined(_WIN32)
|
||||||
|
static QSE_INLINE qse_ntime_t filetime_to_ntime (const FILETIME* ft)
|
||||||
|
{
|
||||||
|
/* reverse of http://support.microsoft.com/kb/167296/en-us */
|
||||||
|
ULARGE_INTEGER li;
|
||||||
|
li.LowPart = ft->dwLowDateTime;
|
||||||
|
li.HighPart = ft->dwHighDateTime;
|
||||||
|
|
||||||
|
#if (QSE_SIZEOF_LONG_LONG>=8)
|
||||||
|
li.QuadPart -= 116444736000000000ull;
|
||||||
|
#elif (QSE_SIZEOF___INT64>=8)
|
||||||
|
li.QuadPart -= 116444736000000000ui64;
|
||||||
|
#else
|
||||||
|
# error Unsupported 64bit integer type
|
||||||
|
#endif
|
||||||
|
/*li.QuadPart /= 10000000;*/
|
||||||
|
li.QuadPart /= 10000;
|
||||||
|
|
||||||
|
return li.QuadPart;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qse_dir_ent_t* qse_dir_read (qse_dir_t* dir, int flags)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
info_t* info;
|
info_t* info;
|
||||||
@ -455,26 +479,93 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
|
|||||||
|
|
||||||
/* call set_entry_name before changing other fields
|
/* call set_entry_name before changing other fields
|
||||||
* in dir->ent not to pollute it in case set_entry_name fails */
|
* in dir->ent not to pollute it in case set_entry_name fails */
|
||||||
|
QSE_MEMSET (&dir->ent, 0, QSE_SIZEOF(dir->ent));
|
||||||
if (set_entry_name (dir, info->wfd.cFileName) <= -1) return QSE_NULL;
|
if (set_entry_name (dir, info->wfd.cFileName) <= -1) return QSE_NULL;
|
||||||
|
|
||||||
if (info->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (flags & QSE_DIR_ENT_TYPE)
|
||||||
{
|
{
|
||||||
dir->ent.size = 0;
|
if (info->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
dir->ent.type = QSE_DIR_ENT_DIRECTORY;
|
{
|
||||||
|
dir->ent.type = QSE_DIR_ENT_SUBDIR;
|
||||||
|
}
|
||||||
|
else if ((info->wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||||
|
(info->wfd.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
|
||||||
|
{
|
||||||
|
dir->ent.type = QSE_DIR_ENT_SYMLINK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
qse_char_t* tmp_name[4];
|
||||||
|
qse_char_t* fname;
|
||||||
|
|
||||||
|
/* TODO: use a buffer in info... instead of allocating an deallocating every time */
|
||||||
|
tmp_name[0] = dir->curdir;
|
||||||
|
tmp_name[1] = QSE_T("\\");
|
||||||
|
tmp_name[2] = info->wfd.cFileName;
|
||||||
|
tmp_name[3] = QSE_NULL;
|
||||||
|
fname = qse_stradup (tmp_name, dir->mmgr);
|
||||||
|
if (fname == QSE_NULL)
|
||||||
|
{
|
||||||
|
dir->errnum = QSE_DIR_ENOMEM;
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = CreateFile (
|
||||||
|
fname,
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
QSE_NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_MMGR_FREE (dir->mmgr, fname);
|
||||||
|
|
||||||
|
if (h != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD t = GetFileType (h);
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case FILE_TYPE_CHAR:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_CHRDEV;
|
||||||
|
break;
|
||||||
|
case FILE_TYPE_DISK:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_BLKDEV;
|
||||||
|
break;
|
||||||
|
case FILE_TYPE_PIPE:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_PIPE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CloseHandle (h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dir->ent.type = QSE_DIR_ENT_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir->ent.type |= QSE_DIR_ENT_TYPE;
|
||||||
}
|
}
|
||||||
else if ((info->wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
|
||||||
(info->wfd.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
|
if (flags & QSE_DIR_ENT_SIZE)
|
||||||
{
|
{
|
||||||
dir->ent.size = 0;
|
ULARGE_INTEGER li;
|
||||||
dir->ent.type = QSE_DIR_ENT_LINK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LARGE_INTEGER li;
|
|
||||||
li.LowPart = info->wfd.nFileSizeLow;
|
li.LowPart = info->wfd.nFileSizeLow;
|
||||||
li.HighPart = info->wfd.nFileSizeHigh;
|
li.HighPart = info->wfd.nFileSizeHigh;
|
||||||
dir->ent.size = li.QuadPart;
|
dir->ent.size = li.QuadPart;
|
||||||
dir->ent.type = QSE_DIR_ENT_UNKNOWN;
|
dir->ent.type |= QSE_DIR_ENT_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & QSE_DIR_ENT_TIME)
|
||||||
|
{
|
||||||
|
dir->ent.time.create = filetime_to_ntime (&info->wfd.ftCreationTime);
|
||||||
|
dir->ent.time.access = filetime_to_ntime (&info->wfd.ftLastAccessTime);
|
||||||
|
dir->ent.time.modify = filetime_to_ntime (&info->wfd.ftLastWriteTime);
|
||||||
|
dir->ent.type |= QSE_DIR_ENT_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
@ -486,13 +577,13 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
|
|||||||
info_t* info;
|
info_t* info;
|
||||||
struct dirent* ent;
|
struct dirent* ent;
|
||||||
int x;
|
int x;
|
||||||
#if defined(QSE_LSTAT64)
|
|
||||||
|
int stat_needed;
|
||||||
|
#if defined(QSE_LSTAT64)
|
||||||
struct stat64 st;
|
struct stat64 st;
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
#endif
|
#endif
|
||||||
qse_mchar_t* tmp_name[4];
|
|
||||||
qse_mchar_t* mfname;
|
|
||||||
|
|
||||||
info = dir->info;
|
info = dir->info;
|
||||||
if (info == QSE_NULL)
|
if (info == QSE_NULL)
|
||||||
@ -509,48 +600,138 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_STRUCT_DIRENT_D_TYPE)
|
QSE_MEMSET (&dir->ent, 0, QSE_SIZEOF(dir->ent));
|
||||||
/* end->d_type */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* TODO: use a buffer in info... instead of allocating an deallocating every time */
|
|
||||||
tmp_name[0] = info->mcurdir;
|
|
||||||
tmp_name[1] = QSE_MT("/");
|
|
||||||
tmp_name[2] = ent->d_name;
|
|
||||||
tmp_name[3] = QSE_NULL;
|
|
||||||
mfname = qse_mbsadup (tmp_name, dir->mmgr);
|
|
||||||
if (mfname == QSE_NULL)
|
|
||||||
{
|
|
||||||
dir->errnum = QSE_DIR_ENOMEM;
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(QSE_LSTAT64)
|
|
||||||
x = QSE_LSTAT64 (mfname, &st);
|
|
||||||
#else
|
|
||||||
x = QSE_LSTAT (mfname, &st);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QSE_MMGR_FREE (dir->mmgr, mfname);
|
|
||||||
|
|
||||||
if (x == -1)
|
|
||||||
{
|
|
||||||
dir->errnum = syserr_to_errnum (errno);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set_entry_name (dir, ent->d_name) <= -1) return QSE_NULL;
|
if (set_entry_name (dir, ent->d_name) <= -1) return QSE_NULL;
|
||||||
|
|
||||||
|
stat_needed =
|
||||||
|
#if !defined(HAVE_STRUCT_DIRENT_D_TYPE)
|
||||||
|
(flags & QSE_DIR_ENT_TYPE) ||
|
||||||
|
#endif
|
||||||
|
(flags & QSE_DIR_ENT_SIZE) ||
|
||||||
|
(flags & QSE_DIR_ENT_TIME);
|
||||||
|
if (stat_needed)
|
||||||
|
{
|
||||||
|
qse_mchar_t* tmp_name[4];
|
||||||
|
qse_mchar_t* mfname;
|
||||||
|
|
||||||
dir->ent.size = st.st_size;
|
/* TODO: use a buffer in info... instead of allocating an deallocating every time */
|
||||||
|
tmp_name[0] = info->mcurdir;
|
||||||
|
tmp_name[1] = QSE_MT("/");
|
||||||
|
tmp_name[2] = ent->d_name;
|
||||||
|
tmp_name[3] = QSE_NULL;
|
||||||
|
mfname = qse_mbsadup (tmp_name, dir->mmgr);
|
||||||
|
if (mfname == QSE_NULL)
|
||||||
|
{
|
||||||
|
dir->errnum = QSE_DIR_ENOMEM;
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(QSE_LSTAT64)
|
||||||
|
x = QSE_LSTAT64 (mfname, &st);
|
||||||
|
#else
|
||||||
|
x = QSE_LSTAT (mfname, &st);
|
||||||
|
#endif
|
||||||
|
QSE_MMGR_FREE (dir->mmgr, mfname);
|
||||||
|
|
||||||
#define IS_TYPE(st,type) ((st.st_mode & S_IFMT) == S_IFDIR)
|
if (x == -1)
|
||||||
dir->ent.type = IS_TYPE(st,S_IFDIR)? QSE_DIR_ENT_DIR:
|
{
|
||||||
IS_TYPE(st,S_IFCHR)? QSE_DIR_ENT_CHAR:
|
dir->errnum = syserr_to_errnum (errno);
|
||||||
IS_TYPE(st,S_IFBLK)? QSE_DIR_ENT_BLOCK:
|
return QSE_NULL;
|
||||||
QSE_DIR_ENT_UNKNOWN;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & QSE_DIR_ENT_TYPE)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_STRUCT_DIRENT_D_TYPE)
|
||||||
|
switch (ent->d_type)
|
||||||
|
{
|
||||||
|
case DT_DIR:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_SUBDIR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DT_REG:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_REGULAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DT_LNK:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_SYMLINK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DT_BLK:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_BLKDEV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DT_CHR:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_CHRDEV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DT_FIFO:
|
||||||
|
#if defined(DT_SOCK)
|
||||||
|
case DT_SOCK:
|
||||||
|
#endif
|
||||||
|
dir->ent.type = QSE_DIR_ENT_PIPE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dir->ent.type = QSE_DIR_ENT_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define IS_TYPE(st,type) ((st.st_mode & S_IFMT) == S_IFDIR)
|
||||||
|
dir->ent.type = IS_TYPE(st,S_IFDIR)? QSE_DIR_ENT_SUBDIR:
|
||||||
|
IS_TYPE(st,S_IFREG)? QSE_DIR_ENT_REGULAR:
|
||||||
|
IS_TYPE(st,S_IFLNK)? QSE_DIR_ENT_SYMLINK:
|
||||||
|
IS_TYPE(st,S_IFCHR)? QSE_DIR_ENT_CHRDEV:
|
||||||
|
IS_TYPE(st,S_IFBLK)? QSE_DIR_ENT_BLKDEV:
|
||||||
|
IS_TYPE(st,S_IFIFO)? QSE_DIR_ENT_PIPE:
|
||||||
|
IS_TYPE(st,S_IFSOCK)? QSE_DIR_ENT_PIPE:
|
||||||
|
QSE_DIR_ENT_UNKNOWN;
|
||||||
|
#undef IS_TYPE
|
||||||
|
#endif
|
||||||
|
dir->ent.flags |= QSE_DIR_ENT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & QSE_DIR_ENT_SIZE)
|
||||||
|
{
|
||||||
|
dir->ent.size = st.st_size;
|
||||||
|
dir->ent.flags |= QSE_DIR_ENT_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & QSE_DIR_ENT_TIME)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
|
||||||
|
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
|
||||||
|
dir->ent.time.create =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_birthtim.tv_sec,st.st_birthtim.tv_nsec);
|
||||||
|
#endif
|
||||||
|
dir->ent.time.access =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_atim.tv_sec,st.st_atim.tv_nsec);
|
||||||
|
dir->ent.time.modify =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_mtim.tv_sec,st.st_mtim.tv_nsec);
|
||||||
|
dir->ent.time.change =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_ctim.tv_sec,st.st_ctim.tv_nsec);
|
||||||
|
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||||
|
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
|
||||||
|
dir->ent.time.create = st.st_birthtime;
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_birthtimespec.tv_sec,st.st_birthtimespec.tv_nsec);
|
||||||
|
#endif
|
||||||
|
dir->ent.time.access =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_atimespec.tv_sec,st.st_atimespec.tv_nsec);
|
||||||
|
dir->ent.time.modify =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_mtimespec.tv_sec,st.st_mtimespec.tv_nsec);
|
||||||
|
dir->ent.time.change =
|
||||||
|
QSE_SECNSEC_TO_MSEC(st.st_ctimespec.tv_sec,st.st_ctimespec.tv_nsec);
|
||||||
|
#else
|
||||||
|
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
|
||||||
|
dir->ent.time.create = st.st_birthtime * QSE_MSEC_PER_SEC;
|
||||||
|
#endif
|
||||||
|
dir->ent.time.access = st.st_atime * QSE_MSEC_PER_SEC;
|
||||||
|
dir->ent.time.modify = st.st_mtime * QSE_MSEC_PER_SEC;
|
||||||
|
dir->ent.time.change = st.st_ctime * QSE_MSEC_PER_SEC;
|
||||||
|
#endif
|
||||||
|
dir->ent.flags |= QSE_DIR_ENT_TIME;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return &dir->ent;
|
return &dir->ent;
|
||||||
|
@ -19,7 +19,9 @@ static void list (qse_dir_t* dir, const qse_char_t* name)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ent = qse_dir_read (dir);
|
qse_btime_t bt;
|
||||||
|
|
||||||
|
ent = qse_dir_read (dir, QSE_DIR_ENT_SIZE | QSE_DIR_ENT_TYPE | QSE_DIR_ENT_TIME);
|
||||||
if (ent == QSE_NULL)
|
if (ent == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_dir_errnum_t e = qse_dir_geterrnum(dir);
|
qse_dir_errnum_t e = qse_dir_geterrnum(dir);
|
||||||
@ -28,10 +30,13 @@ static void list (qse_dir_t* dir, const qse_char_t* name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->type == QSE_DIR_ENT_DIRECTORY)
|
qse_localtime (ent->time.modify, &bt);
|
||||||
qse_printf (QSE_T("<DIR> %16lu %s\n"), (unsigned long)ent->size, ent->name);
|
qse_printf (QSE_T("%s %16lu %04d-%02d-%02d %02d:%02d %s\n"),
|
||||||
else
|
((ent->type == QSE_DIR_ENT_SUBDIR)? QSE_T("<D>"): QSE_T(" ")),
|
||||||
qse_printf (QSE_T(" %16lu %s\n"), (unsigned long)ent->size, ent->name);
|
(unsigned long)ent->size,
|
||||||
|
bt.year + 1900, bt.mon+1, bt.mday, bt.hour, bt.min,
|
||||||
|
ent->name.base
|
||||||
|
);
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user