enhanded qse_dir_read()
This commit is contained in:
parent
1b600ee20c
commit
e5a9693411
@ -34,7 +34,7 @@ POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/README.in \
|
||||
$(top_srcdir)/configure ac/config.guess ac/config.sub \
|
||||
ac/depcomp ac/install-sh ac/ltmain.sh ac/missing
|
||||
|
30
qse/configure
vendored
30
qse/configure
vendored
@ -15745,6 +15745,36 @@ _ACEOF
|
||||
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
|
||||
# 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"
|
||||
|
||||
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
|
||||
AC_CHECK_SIZEOF(char,,[[]])
|
||||
|
@ -53,12 +53,16 @@
|
||||
|
||||
#define QSE_USECS_PER_MSEC (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_IS_LEAPYEAR(year) ((!((year)%4) && ((year)%100)) || !((year)%400))
|
||||
#define QSE_DAYS_PER_YEAR(year) \
|
||||
(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) */
|
||||
typedef qse_long_t qse_ntime_t;
|
||||
typedef struct qse_btime_t qse_btime_t;
|
||||
@ -95,7 +99,6 @@ int qse_gettime (
|
||||
int qse_settime (
|
||||
qse_ntime_t nt
|
||||
);
|
||||
/******/
|
||||
|
||||
|
||||
/**
|
||||
@ -137,7 +140,7 @@ int qse_timelocal (
|
||||
* The qse_strftime() functions formats time.
|
||||
*/
|
||||
qse_size_t qse_strftime (
|
||||
qse_char_t* buf,
|
||||
qse_char_t* buf,
|
||||
qse_size_t size,
|
||||
const qse_char_t* fmt,
|
||||
qse_btime_t* bt
|
||||
|
@ -178,6 +178,15 @@
|
||||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||||
#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. */
|
||||
#undef HAVE_SYSCONF
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/cmn/time.h>
|
||||
|
||||
enum qse_dir_errnum_t
|
||||
{
|
||||
@ -38,20 +39,46 @@ enum 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
|
||||
{
|
||||
enum
|
||||
int flags;
|
||||
|
||||
struct
|
||||
{
|
||||
QSE_DIR_ENT_UNKNOWN,
|
||||
QSE_DIR_ENT_DIR,
|
||||
QSE_DIR_ENT_REG,
|
||||
QSE_DIR_ENT_FIFO,
|
||||
QSE_DIR_ENT_CHAR,
|
||||
QSE_DIR_ENT_BLOCK,
|
||||
QSE_DIR_ENT_LINK
|
||||
} type;
|
||||
qse_char_t* name;
|
||||
qse_foff_t size;
|
||||
qse_char_t* base;
|
||||
qse_char_t* path;
|
||||
} name;
|
||||
qse_dir_ent_type_t type;
|
||||
qse_foff_t size;
|
||||
|
||||
struct
|
||||
{
|
||||
qse_ntime_t create;
|
||||
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;
|
||||
@ -70,10 +97,10 @@ typedef struct qse_dir_t qse_dir_t;
|
||||
enum qse_dir_option_t
|
||||
{
|
||||
/**< 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() */
|
||||
QSE_DIR_REALPATH = (1 << 1)
|
||||
QSE_DIR_REALPATH = (1 << 2)
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -109,7 +136,8 @@ const qse_char_t* qse_dir_geterrmsg (
|
||||
);
|
||||
|
||||
qse_dir_ent_t* qse_dir_read (
|
||||
qse_dir_t* dir
|
||||
qse_dir_t* dir,
|
||||
int flags
|
||||
);
|
||||
|
||||
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++;
|
||||
qse_mbstowcs (name, info->name.ptr, &len);
|
||||
#endif
|
||||
dir->ent.name = info->name.ptr;
|
||||
|
||||
dir->ent.name.base = info->name.ptr;
|
||||
dir->ent.flags |= QSE_DIR_ENT_NAME;
|
||||
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)
|
||||
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
|
||||
* 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 (info->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
if (flags & QSE_DIR_ENT_TYPE)
|
||||
{
|
||||
dir->ent.size = 0;
|
||||
dir->ent.type = QSE_DIR_ENT_DIRECTORY;
|
||||
if (info->wfd.dwFileAttributes & FILE_ATTRIBUTE_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;
|
||||
dir->ent.type = QSE_DIR_ENT_LINK;
|
||||
}
|
||||
else
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
ULARGE_INTEGER li;
|
||||
li.LowPart = info->wfd.nFileSizeLow;
|
||||
li.HighPart = info->wfd.nFileSizeHigh;
|
||||
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__)
|
||||
@ -486,13 +577,13 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
|
||||
info_t* info;
|
||||
struct dirent* ent;
|
||||
int x;
|
||||
#if defined(QSE_LSTAT64)
|
||||
|
||||
int stat_needed;
|
||||
#if defined(QSE_LSTAT64)
|
||||
struct stat64 st;
|
||||
#else
|
||||
#else
|
||||
struct stat st;
|
||||
#endif
|
||||
qse_mchar_t* tmp_name[4];
|
||||
qse_mchar_t* mfname;
|
||||
#endif
|
||||
|
||||
info = dir->info;
|
||||
if (info == QSE_NULL)
|
||||
@ -509,48 +600,138 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
#if defined(HAVE_STRUCT_DIRENT_D_TYPE)
|
||||
/* 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;
|
||||
}
|
||||
|
||||
QSE_MEMSET (&dir->ent, 0, QSE_SIZEOF(dir->ent));
|
||||
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)
|
||||
dir->ent.type = IS_TYPE(st,S_IFDIR)? QSE_DIR_ENT_DIR:
|
||||
IS_TYPE(st,S_IFCHR)? QSE_DIR_ENT_CHAR:
|
||||
IS_TYPE(st,S_IFBLK)? QSE_DIR_ENT_BLOCK:
|
||||
QSE_DIR_ENT_UNKNOWN;
|
||||
if (x == -1)
|
||||
{
|
||||
dir->errnum = syserr_to_errnum (errno);
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
return &dir->ent;
|
||||
|
@ -19,7 +19,9 @@ static void list (qse_dir_t* dir, const qse_char_t* name)
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (ent->type == QSE_DIR_ENT_DIRECTORY)
|
||||
qse_printf (QSE_T("<DIR> %16lu %s\n"), (unsigned long)ent->size, ent->name);
|
||||
else
|
||||
qse_printf (QSE_T(" %16lu %s\n"), (unsigned long)ent->size, ent->name);
|
||||
qse_localtime (ent->time.modify, &bt);
|
||||
qse_printf (QSE_T("%s %16lu %04d-%02d-%02d %02d:%02d %s\n"),
|
||||
((ent->type == QSE_DIR_ENT_SUBDIR)? QSE_T("<D>"): QSE_T(" ")),
|
||||
(unsigned long)ent->size,
|
||||
bt.year + 1900, bt.mon+1, bt.mday, bt.hour, bt.min,
|
||||
ent->name.base
|
||||
);
|
||||
}
|
||||
while (1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user