added more file management functions
This commit is contained in:
		@ -36,6 +36,58 @@
 | 
			
		||||
#include <qse/macros.h>
 | 
			
		||||
#include <qse/cmn/time.h>
 | 
			
		||||
 | 
			
		||||
struct qse_fattr_t
 | 
			
		||||
{
 | 
			
		||||
	unsigned int isdir: 1;
 | 
			
		||||
	unsigned int islnk: 1;
 | 
			
		||||
	unsigned int isreg: 1;
 | 
			
		||||
	unsigned int isblk: 1;
 | 
			
		||||
	unsigned int ischr: 1;
 | 
			
		||||
 | 
			
		||||
	qse_uintptr_t mode;
 | 
			
		||||
 | 
			
		||||
	qse_uintmax_t size;
 | 
			
		||||
	qse_uintmax_t ino;
 | 
			
		||||
	qse_uintmax_t dev;
 | 
			
		||||
	qse_uintptr_t uid;
 | 
			
		||||
	qse_uintptr_t gid;
 | 
			
		||||
 | 
			
		||||
	qse_ntime_t atime; /* last access */
 | 
			
		||||
	qse_ntime_t mtime; /* last modification */
 | 
			
		||||
	qse_ntime_t ctime; /* last status change */
 | 
			
		||||
};
 | 
			
		||||
typedef struct qse_fattr_t qse_fattr_t;
 | 
			
		||||
 | 
			
		||||
enum qse_fperm_t
 | 
			
		||||
{
 | 
			
		||||
	QSE_FPERM_READ,
 | 
			
		||||
	QSE_FPERM_WRITE,
 | 
			
		||||
	QSE_FPERM_EXEC
 | 
			
		||||
};
 | 
			
		||||
typedef enum qse_fperm_t qse_fperm_t;
 | 
			
		||||
 | 
			
		||||
enum qse_file_attr_flag_t
 | 
			
		||||
{
 | 
			
		||||
	/* used in qse_set_file_attr() only */
 | 
			
		||||
	QSE_FILE_ATTR_TIME  = (1 << 0),
 | 
			
		||||
	QSE_FILE_ATTR_OWNER = (1 << 1),
 | 
			
		||||
	QSE_FILE_ATTR_MODE  = (1 << 2),
 | 
			
		||||
 | 
			
		||||
	/* effective in both qse_get_file_attr() and qse_set_file_attr()  */
 | 
			
		||||
	QSE_FILE_ATTR_SYMLINK = (1 << 15) /* work on the symbolic link itself. don't follow */
 | 
			
		||||
};
 | 
			
		||||
typedef enum qse_file_attr_flag_t qse_file_attr_flag_t;
 | 
			
		||||
 | 
			
		||||
enum qse_file_perm_flag_t
 | 
			
		||||
{
 | 
			
		||||
	QSE_FILE_PERM_SYMLINK = (1 << 15) /* don't follow symbolic link */
 | 
			
		||||
};
 | 
			
		||||
typedef enum qse_file_perm_flag_t qse_file_perm_flag_t;
 | 
			
		||||
 | 
			
		||||
/* ==========================================================================
 | 
			
		||||
 * FS OBJECT
 | 
			
		||||
 * ========================================================================== */
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && defined(QSE_CHAR_IS_WCHAR)
 | 
			
		||||
	typedef qse_wchar_t qse_fs_char_t;
 | 
			
		||||
#	define QSE_FS_CHAR_IS_WCHAR
 | 
			
		||||
@ -46,8 +98,6 @@
 | 
			
		||||
#	define QSE_SIZEOF_FS_CHAR_T QSE_SIZEOF_MCHAR_T
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef qse_fmode_t qse_fs_mode_t;
 | 
			
		||||
 | 
			
		||||
enum qse_fs_errnum_t
 | 
			
		||||
{
 | 
			
		||||
	QSE_FS_ENOERR = 0,
 | 
			
		||||
@ -119,44 +169,7 @@ struct qse_fs_ent_t
 | 
			
		||||
 | 
			
		||||
typedef struct qse_fs_ent_t qse_fs_ent_t;
 | 
			
		||||
 | 
			
		||||
struct qse_fs_attr_t
 | 
			
		||||
{
 | 
			
		||||
	unsigned int isdir: 1;
 | 
			
		||||
	unsigned int islnk: 1;
 | 
			
		||||
	unsigned int isreg: 1;
 | 
			
		||||
	unsigned int isblk: 1;
 | 
			
		||||
	unsigned int ischr: 1;
 | 
			
		||||
 | 
			
		||||
	qse_uintptr_t mode;
 | 
			
		||||
 | 
			
		||||
	qse_uintmax_t size;
 | 
			
		||||
	qse_uintmax_t ino;
 | 
			
		||||
	qse_uintmax_t dev;
 | 
			
		||||
	qse_uintptr_t uid;
 | 
			
		||||
	qse_uintptr_t gid;
 | 
			
		||||
 | 
			
		||||
	qse_ntime_t atime; /* last access */
 | 
			
		||||
	qse_ntime_t mtime; /* last modification */
 | 
			
		||||
	qse_ntime_t ctime; /* last status change */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct qse_fs_attr_t qse_fs_attr_t;
 | 
			
		||||
 | 
			
		||||
enum qse_fs_getattr_flag_t
 | 
			
		||||
{
 | 
			
		||||
	QSE_FS_GETATTR_SYMLINK = (1 << 15)
 | 
			
		||||
};
 | 
			
		||||
typedef enum qse_fs_getattr_flag_t qse_fs_getattr_flag_t;
 | 
			
		||||
 | 
			
		||||
enum qse_fs_setattr_flag_t
 | 
			
		||||
{
 | 
			
		||||
	QSE_FS_SETATTR_TIME  = (1 << 0),
 | 
			
		||||
	QSE_FS_SETATTR_OWNER = (1 << 1),
 | 
			
		||||
	QSE_FS_SETATTR_MODE  = (1 << 2),
 | 
			
		||||
 | 
			
		||||
	QSE_FS_SETATTR_SYMLINK = (1 << 15) /* work on the symbolic link itself. don't follow */
 | 
			
		||||
};
 | 
			
		||||
typedef enum qse_fs_setattr_flag_t qse_fs_setattr_flag_t;
 | 
			
		||||
typedef qse_fattr_t qse_fattr_t;
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
typedef void* qse_fs_handle_t;
 | 
			
		||||
@ -364,43 +377,43 @@ QSE_EXPORT int qse_fs_pop (
 | 
			
		||||
QSE_EXPORT int qse_fs_getattronfd (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	qse_fs_handle_t      fd,
 | 
			
		||||
	qse_fs_attr_t*       attr,
 | 
			
		||||
	qse_fattr_t*         attr,
 | 
			
		||||
	int                  flags
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_setattronfd (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	qse_fs_handle_t      fd,
 | 
			
		||||
	const qse_fs_attr_t* attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
 | 
			
		||||
	const qse_fattr_t*   attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_file_attr_flag_t enumerators */
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_getattrmbs (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	const qse_mchar_t*   path,
 | 
			
		||||
	qse_fs_attr_t*       attr,
 | 
			
		||||
	qse_fattr_t*         attr,
 | 
			
		||||
	int                  flags
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_getattrwcs (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	const qse_wchar_t*   path,
 | 
			
		||||
	qse_fs_attr_t*       attr,
 | 
			
		||||
	qse_fattr_t*       attr,
 | 
			
		||||
	int                  flags
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_setattrmbs (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	qse_mchar_t*         path,
 | 
			
		||||
	const qse_fs_attr_t* attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
 | 
			
		||||
	const qse_fattr_t*  attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_file_attr_flag_t enumerators */
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_setattrwcs (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	qse_wchar_t*         path,
 | 
			
		||||
	const qse_fs_attr_t* attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
 | 
			
		||||
	const qse_fattr_t*   attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_file_attr_flag_t enumerators */
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -420,10 +433,6 @@ QSE_EXPORT int qse_fs_move (
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_cpfilembs (
 | 
			
		||||
	qse_fs_t*          fs,
 | 
			
		||||
	const qse_mchar_t* srcpath,
 | 
			
		||||
@ -447,14 +456,14 @@ QSE_EXPORT int qse_fs_cpfilewcs (
 | 
			
		||||
QSE_EXPORT int qse_fs_mkdirmbs (
 | 
			
		||||
	qse_fs_t*          fs,
 | 
			
		||||
	const qse_mchar_t* path,
 | 
			
		||||
	qse_fs_mode_t      mode,
 | 
			
		||||
	qse_fmode_t        mode,
 | 
			
		||||
	int                flags
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_fs_mkdirwcs (
 | 
			
		||||
	qse_fs_t*          fs,
 | 
			
		||||
	const qse_wchar_t* path,
 | 
			
		||||
	qse_fs_mode_t      mode,
 | 
			
		||||
	qse_fmode_t        mode,
 | 
			
		||||
	int                flags
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -499,29 +508,61 @@ QSE_EXPORT int qse_fs_rmdirwcs (
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT qse_mchar_t* qse_get_current_mbsdir (
 | 
			
		||||
	qse_mchar_t* buf,
 | 
			
		||||
	qse_size_t   size,
 | 
			
		||||
	qse_mmgr_t*  mmgr
 | 
			
		||||
	qse_size_t   size
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT qse_wchar_t* qse_get_current_wcsdir (
 | 
			
		||||
	qse_wchar_t* buf,
 | 
			
		||||
	qse_size_t   size,
 | 
			
		||||
	qse_mmgr_t*  mmgr
 | 
			
		||||
	qse_size_t   size
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_get_mbsfile_attr (
 | 
			
		||||
	const qse_mchar_t* file,
 | 
			
		||||
	int                flags, /* 0 or bitwise-ORed of the qse_file_attr_flag_t enumerators */
 | 
			
		||||
	qse_fattr_t*       attr
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_get_wcsfile_attr (
 | 
			
		||||
	const qse_wchar_t* file,
 | 
			
		||||
	int                flags,  /* 0 or bitwise-ORed of the qse_file_attr_flag_t enumerators */
 | 
			
		||||
	qse_fattr_t*       attr
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_check_mbsfile_perm (
 | 
			
		||||
	const qse_mchar_t* file,
 | 
			
		||||
	int                flags, /* 0 or bitwise-ORed of the qse_file_perm_flag_t enumerators */
 | 
			
		||||
	qse_fperm_t        perm
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_check_wcsfile_perm (
 | 
			
		||||
	const qse_wchar_t* file,
 | 
			
		||||
	int                flags, /* 0 or bitwise-ORed of the qse_file_perm_flag_t enumerators */
 | 
			
		||||
	qse_fperm_t        perm
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
#if defined(QSE_CHAR_IS_MCHAR)
 | 
			
		||||
#	define qse_get_current_dir(buf,size,mmgr) qse_get_current_mbsdir(buf,size,mmgr)
 | 
			
		||||
#	define qse_get_current_dir(buf,size) qse_get_current_mbsdir(buf,size)
 | 
			
		||||
#	define qse_get_file_attr(file,flags,attr) qse_get_mbsfile_attr(file,flags,attr)
 | 
			
		||||
#	define qse_check_file_perm(file,flags,perm) qse_check_mbsfile_perm(file,flags,perm)
 | 
			
		||||
#else
 | 
			
		||||
#	define qse_get_current_dir(buf,size,mmgr) qse_get_current_wcsdir(buf,size,mmgr)
 | 
			
		||||
#	define qse_get_current_dir(buf,size) qse_get_current_wcsdir(buf,size)
 | 
			
		||||
#	define qse_get_file_attr(file,flags,attr) qse_get_wcsfile_attr(file,flags,attr)
 | 
			
		||||
#	define qse_check_file_perm(file,flags,perm) qse_check_wcsfile_perm(file,flags,perm)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_get_prog_path (
 | 
			
		||||
QSE_EXPORT int qse_get_prog_path_with_mmgr (
 | 
			
		||||
	const qse_char_t* argv0,
 | 
			
		||||
	qse_char_t*       buf,
 | 
			
		||||
	qse_size_t        size,
 | 
			
		||||
	qse_mmgr_t*       mmgr
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT int qse_get_prog_path (
 | 
			
		||||
	const qse_char_t* argv0,
 | 
			
		||||
	qse_char_t*       buf,
 | 
			
		||||
	qse_size_t        size
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -410,6 +410,7 @@ pdfdir = @pdfdir@
 | 
			
		||||
prefix = @prefix@
 | 
			
		||||
program_transform_name = @program_transform_name@
 | 
			
		||||
psdir = @psdir@
 | 
			
		||||
runstatedir = @runstatedir@
 | 
			
		||||
sbindir = @sbindir@
 | 
			
		||||
sharedstatedir = @sharedstatedir@
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
 | 
			
		||||
@ -291,7 +291,7 @@ int Path::setToSelf (const qse_mchar_t* argv0) QSE_CPP_NOEXCEPT
 | 
			
		||||
int Path::setToSelf (const qse_wchar_t* argv0) QSE_CPP_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
	qse_char_t p[MAX_LEN + 1];
 | 
			
		||||
	if (qse_get_prog_path(argv0, p, QSE_COUNTOF(p), this->getMmgr()) == -1) return -1;
 | 
			
		||||
	if (qse_get_prog_path_with_mmgr(argv0, p, QSE_COUNTOF(p), this->getMmgr()) == -1) return -1;
 | 
			
		||||
	this->setName (p);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,46 +27,7 @@
 | 
			
		||||
#include "fs-prv.h"
 | 
			
		||||
#include "../cmn/mem-prv.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void stat_to_attr (const qse_stat_t* st, qse_fs_attr_t* attr)
 | 
			
		||||
{
 | 
			
		||||
	QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
 | 
			
		||||
 | 
			
		||||
	if (S_ISDIR(st->st_mode)) attr->isdir = 1;
 | 
			
		||||
	if (S_ISLNK(st->st_mode)) attr->islnk = 1;
 | 
			
		||||
	if (S_ISREG(st->st_mode)) attr->isreg = 1;
 | 
			
		||||
	if (S_ISBLK(st->st_mode)) attr->isblk = 1;
 | 
			
		||||
	if (S_ISCHR(st->st_mode)) attr->ischr = 1;
 | 
			
		||||
 | 
			
		||||
	attr->mode = st->st_mode;
 | 
			
		||||
	attr->size = st->st_size;
 | 
			
		||||
	attr->ino = st->st_ino;
 | 
			
		||||
	attr->dev = st->st_dev;
 | 
			
		||||
	attr->uid = st->st_uid;
 | 
			
		||||
	attr->gid = st->st_gid;
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
 | 
			
		||||
	attr->atime.sec = st->st_atim.tv_sec;
 | 
			
		||||
	attr->atime.nsec = st->st_atim.tv_nsec;
 | 
			
		||||
	attr->mtime.sec = st->st_mtim.tv_sec;
 | 
			
		||||
	attr->mtime.nsec = st->st_mtim.tv_nsec;
 | 
			
		||||
	attr->ctime.sec = st->st_ctim.tv_sec;
 | 
			
		||||
	attr->ctime.nsec = st->st_ctim.tv_nsec;
 | 
			
		||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
 | 
			
		||||
	attr->atime.sec = st->st_atimespec.tv_sec;
 | 
			
		||||
	attr->atime.nsec = st->st_atimespec.tv_nsec;
 | 
			
		||||
	attr->mtime.sec = st->st_mtimespec.tv_sec;
 | 
			
		||||
	attr->mtime.nsec = st->st_mtimespec.tv_nsec;
 | 
			
		||||
	attr->ctime.sec = st->st_ctimespec.tv_sec;
 | 
			
		||||
	attr->ctime.nsec = st->st_ctimespec.tv_nsec;
 | 
			
		||||
#else
 | 
			
		||||
	attr->atime.sec = st->st_atime;
 | 
			
		||||
	attr->mtime.sec = st->st_mtime;
 | 
			
		||||
	attr->ctime.sec = st->st_ctime;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_getattronfd (qse_fs_t* fs, qse_fs_handle_t fd, qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_getattronfd (qse_fs_t* fs, qse_fs_handle_t fd, qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
 | 
			
		||||
@ -93,7 +54,7 @@ int qse_fs_getattronfd (qse_fs_t* fs, qse_fs_handle_t fd, qse_fs_attr_t* attr, i
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stat_to_attr (&st, attr);
 | 
			
		||||
	qse_stat_to_attr (&st, attr);
 | 
			
		||||
	return 0;
 | 
			
		||||
#else
 | 
			
		||||
	fs->errnum = QSE_FS_ENOIMPL;
 | 
			
		||||
@ -101,7 +62,7 @@ int qse_fs_getattronfd (qse_fs_t* fs, qse_fs_handle_t fd, qse_fs_attr_t* attr, i
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_getattrsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_getattrsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
 | 
			
		||||
@ -124,21 +85,21 @@ int qse_fs_getattrsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t*
 | 
			
		||||
	qse_fstatat_t st;
 | 
			
		||||
	int sysflags = 0;
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FS_GETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
	if (QSE_FSTATAT(AT_FDCWD, fspath, &st, sysflags) <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stat_to_attr (&st, attr);
 | 
			
		||||
	qse_stat_to_attr (&st, attr);
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	qse_stat_t st;
 | 
			
		||||
	int x;
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FS_GETATTR_SYMLINK)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_SYMLINK)
 | 
			
		||||
		x = QSE_LSTAT (fspath, &st);
 | 
			
		||||
	else
 | 
			
		||||
		x = QSE_STAT (fspath, &st);
 | 
			
		||||
@ -149,12 +110,12 @@ int qse_fs_getattrsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t*
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stat_to_attr (&st, attr);
 | 
			
		||||
	qse_stat_to_attr (&st, attr);
 | 
			
		||||
	return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* fspath;
 | 
			
		||||
	int ret;
 | 
			
		||||
@ -168,7 +129,7 @@ int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* att
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* fspath;
 | 
			
		||||
	int ret;
 | 
			
		||||
@ -184,7 +145,7 @@ int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* att
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
 | 
			
		||||
@ -203,7 +164,7 @@ int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fs_attr_t* a
 | 
			
		||||
	return -1;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	if (flags & QSE_FS_SETATTR_TIME)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_TIME)
 | 
			
		||||
	{
 | 
			
		||||
	#if defined(HAVE_FUTIMENS) && defined(HAVE_STRUCT_TIMESPEC)
 | 
			
		||||
		struct timespec ts[2];
 | 
			
		||||
@ -238,7 +199,7 @@ int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fs_attr_t* a
 | 
			
		||||
	#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FS_SETATTR_OWNER)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_OWNER)
 | 
			
		||||
	{
 | 
			
		||||
	#if defined(HAVE_FCHOWN)
 | 
			
		||||
		if (QSE_FCHOWN (fd, attr->uid, attr->gid) <= -1) 
 | 
			
		||||
@ -252,7 +213,7 @@ int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fs_attr_t* a
 | 
			
		||||
	#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FS_SETATTR_MODE)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_MODE)
 | 
			
		||||
	{
 | 
			
		||||
	#if defined(HAVE_FCHMOD)
 | 
			
		||||
		if (QSE_FCHMOD(fd, attr->mode) <= -1)
 | 
			
		||||
@ -270,7 +231,7 @@ int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fs_attr_t* a
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
@ -290,13 +251,13 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
	return -1;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	if (flags & QSE_FS_SETATTR_TIME)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_TIME)
 | 
			
		||||
	{
 | 
			
		||||
	#if defined(HAVE_UTIMENSAT) && defined(AT_SYMLINK_NOFOLLOW)
 | 
			
		||||
		struct timespec ts[2];
 | 
			
		||||
		int sysflags = 0;
 | 
			
		||||
 | 
			
		||||
		if (flags & QSE_FS_SETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
		if (flags & QSE_FILE_ATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
 | 
			
		||||
		QSE_MEMSET (&ts, 0, QSE_SIZEOF(ts));
 | 
			
		||||
		ts[0].tv_sec = attr->atime.sec;
 | 
			
		||||
@ -311,7 +272,7 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	#else
 | 
			
		||||
		if (flags & QSE_FS_SETATTR_SYMLINK)
 | 
			
		||||
		if (flags & QSE_FILE_ATTR_SYMLINK)
 | 
			
		||||
		{
 | 
			
		||||
		#if defined(HAVE_LUTIMES)
 | 
			
		||||
			struct timeval tv[2];
 | 
			
		||||
@ -369,12 +330,12 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
	#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FS_SETATTR_OWNER)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_OWNER)
 | 
			
		||||
	{
 | 
			
		||||
	#if defined(HAVE_FCHOWNAT) && defined(AT_SYMLINK_NOFOLLOW)
 | 
			
		||||
		int sysflags = 0;
 | 
			
		||||
 | 
			
		||||
		if (flags & QSE_FS_SETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
		if (flags & QSE_FILE_ATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
 | 
			
		||||
		if (QSE_FCHOWNAT(AT_FDCWD, path, attr->uid, attr->gid, sysflags) <= -1)
 | 
			
		||||
		{
 | 
			
		||||
@ -384,7 +345,7 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
	#else
 | 
			
		||||
		int x;
 | 
			
		||||
 | 
			
		||||
		if (flags & QSE_FS_SETATTR_SYMLINK)
 | 
			
		||||
		if (flags & QSE_FILE_ATTR_SYMLINK)
 | 
			
		||||
			x = QSE_LCHOWN (path, attr->uid, attr->gid);
 | 
			
		||||
		else
 | 
			
		||||
			x = QSE_CHOWN (path, attr->uid, attr->gid);
 | 
			
		||||
@ -397,12 +358,12 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
	#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FS_SETATTR_MODE)
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_MODE)
 | 
			
		||||
	{
 | 
			
		||||
	#if defined(HAVE_FCHMODAT) && defined(AT_SYMLINK_NOFOLLOW)
 | 
			
		||||
		int sysflags = 0;
 | 
			
		||||
 | 
			
		||||
		if (flags & QSE_FS_SETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
		if (flags & QSE_FILE_ATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
 | 
			
		||||
		if (QSE_FCHMODAT(AT_FDCWD, path, attr->mode, sysflags) <= -1)
 | 
			
		||||
		{
 | 
			
		||||
@ -410,7 +371,7 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	#else
 | 
			
		||||
		if (flags & QSE_FS_SETATTR_SYMLINK)
 | 
			
		||||
		if (flags & QSE_FILE_ATTR_SYMLINK)
 | 
			
		||||
		{
 | 
			
		||||
			/* not supported. symlink permission is kind of fixed.
 | 
			
		||||
			 * do nothing */
 | 
			
		||||
@ -431,7 +392,7 @@ int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int qse_fs_setattrmbs (qse_fs_t* fs, qse_mchar_t* path, const qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_setattrmbs (qse_fs_t* fs, qse_mchar_t* path, const qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* fspath;
 | 
			
		||||
	int ret;
 | 
			
		||||
@ -446,7 +407,7 @@ int qse_fs_setattrmbs (qse_fs_t* fs, qse_mchar_t* path, const qse_fs_attr_t* att
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int qse_fs_setattrwcs (qse_fs_t* fs, qse_wchar_t* path, const qse_fs_attr_t* attr, int flags)
 | 
			
		||||
int qse_fs_setattrwcs (qse_fs_t* fs, qse_wchar_t* path, const qse_fattr_t* attr, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* fspath;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
@ -47,13 +47,13 @@ struct cpfile_t
 | 
			
		||||
	int flags;
 | 
			
		||||
	qse_fs_char_t* src_fspath;
 | 
			
		||||
	qse_fs_char_t* dst_fspath;
 | 
			
		||||
	qse_fs_attr_t src_attr;
 | 
			
		||||
	qse_fs_attr_t dst_attr;
 | 
			
		||||
	qse_fattr_t src_attr;
 | 
			
		||||
	qse_fattr_t dst_attr;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
typedef struct cpfile_t cpfile_t;
 | 
			
		||||
 | 
			
		||||
static int is_dir_remembered (qse_fs_t* fs, qse_fs_attr_t* attr)
 | 
			
		||||
static int is_dir_remembered (qse_fs_t* fs, qse_fattr_t* attr)
 | 
			
		||||
{
 | 
			
		||||
	qse_size_t i;
 | 
			
		||||
	devino_t* di;
 | 
			
		||||
@ -67,7 +67,7 @@ static int is_dir_remembered (qse_fs_t* fs, qse_fs_attr_t* attr)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int remember_dir_to_history (qse_fs_t* fs, qse_fs_attr_t* attr)
 | 
			
		||||
static int remember_dir_to_history (qse_fs_t* fs, qse_fattr_t* attr)
 | 
			
		||||
{
 | 
			
		||||
	qse_size_t i;
 | 
			
		||||
	devino_t* di;
 | 
			
		||||
@ -126,7 +126,7 @@ static int merge_dstdir_and_srcbase (qse_fs_t* fs, cpfile_t* cpfile)
 | 
			
		||||
	qse_fs_freefspath (fs, QSE_NULL, cpfile->dst_fspath);
 | 
			
		||||
	cpfile->dst_fspath = fstmp;
 | 
			
		||||
 | 
			
		||||
	if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, QSE_FS_GETATTR_SYMLINK) <= -1) 
 | 
			
		||||
	if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, QSE_FILE_ATTR_SYMLINK) <= -1) 
 | 
			
		||||
	{
 | 
			
		||||
		/* attribute on the new destination is not available */
 | 
			
		||||
		cpfile->flags &= ~CPFILE_DST_ATTR;
 | 
			
		||||
@ -342,11 +342,11 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
 | 
			
		||||
 | 
			
		||||
		if (cpfile->flags & QSE_FS_CPFILE_PRESERVE)
 | 
			
		||||
		{
 | 
			
		||||
			if (qse_fs_setattronfd (fs, out, &cpfile->src_attr, QSE_FS_SETATTR_TIME | QSE_FS_SETATTR_OWNER | QSE_FS_SETATTR_MODE) <= -1)
 | 
			
		||||
			if (qse_fs_setattronfd (fs, out, &cpfile->src_attr, QSE_FILE_ATTR_TIME | QSE_FILE_ATTR_OWNER | QSE_FILE_ATTR_MODE) <= -1)
 | 
			
		||||
			{
 | 
			
		||||
				if (fs->errnum == QSE_FS_ENOIMPL)
 | 
			
		||||
				{
 | 
			
		||||
					if (qse_fs_setattrsys (fs, cpfile->dst_fspath, &cpfile->src_attr, QSE_FS_SETATTR_TIME | QSE_FS_SETATTR_OWNER | QSE_FS_SETATTR_MODE) <= -1) goto oops_2;
 | 
			
		||||
					if (qse_fs_setattrsys (fs, cpfile->dst_fspath, &cpfile->src_attr, QSE_FILE_ATTR_TIME | QSE_FILE_ATTR_OWNER | QSE_FILE_ATTR_MODE) <= -1) goto oops_2;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@ -374,8 +374,8 @@ static int prepare_cpfile (qse_fs_t* fs, cpfile_t* cpfile)
 | 
			
		||||
	/* error if the source file can't be stat'ed.
 | 
			
		||||
	 * ok if the destination file can't be stat'ed */
 | 
			
		||||
/* TODO: check if flags to getattrsys() is correct */
 | 
			
		||||
	if (qse_fs_getattrsys (fs, cpfile->src_fspath, &cpfile->src_attr, QSE_FS_GETATTR_SYMLINK) <= -1) return -1;
 | 
			
		||||
	if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, QSE_FS_GETATTR_SYMLINK) >= 0) cpfile->flags |= CPFILE_DST_ATTR;
 | 
			
		||||
	if (qse_fs_getattrsys (fs, cpfile->src_fspath, &cpfile->src_attr, QSE_FILE_ATTR_SYMLINK) <= -1) return -1;
 | 
			
		||||
	if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, QSE_FILE_ATTR_SYMLINK) >= 0) cpfile->flags |= CPFILE_DST_ATTR;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -522,7 +522,7 @@ start_over:
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* (re)load the attribute. */
 | 
			
		||||
		if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, QSE_FS_GETATTR_SYMLINK) <= -1) goto oops;
 | 
			
		||||
		if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, QSE_FILE_ATTR_SYMLINK) <= -1) goto oops;
 | 
			
		||||
		cpfile->flags |= CPFILE_DST_ATTR;
 | 
			
		||||
 | 
			
		||||
		if (remember_dir_to_history (fs, &cpfile->dst_attr) <= -1) 
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@
 | 
			
		||||
 | 
			
		||||
#include "fs-prv.h"
 | 
			
		||||
 | 
			
		||||
int qse_fs_mkdirsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_mode_t mode)
 | 
			
		||||
int qse_fs_mkdirsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fmode_t mode)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,7 @@ int qse_fs_mkdirsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_mode_t mo
 | 
			
		||||
 | 
			
		||||
/* --------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
static int make_directory_chain (qse_fs_t* fs, qse_fs_char_t* fspath, qse_fs_mode_t mode)
 | 
			
		||||
static int make_directory_chain (qse_fs_t* fs, qse_fs_char_t* fspath, qse_fmode_t mode)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* core, * p, c;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
@ -135,10 +135,10 @@ done:
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_mkdirmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_mode_t mode, int flags)
 | 
			
		||||
int qse_fs_mkdirmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fmode_t mode, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* fspath;
 | 
			
		||||
	qse_fs_mode_t oldmask;
 | 
			
		||||
	qse_fmode_t oldmask;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	if (*path == QSE_MT('\0')) 
 | 
			
		||||
@ -175,10 +175,10 @@ int qse_fs_mkdirmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_mode_t mode,
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_fs_mkdirwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_mode_t mode, int flags)
 | 
			
		||||
int qse_fs_mkdirwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fmode_t mode, int flags)
 | 
			
		||||
{
 | 
			
		||||
	qse_fs_char_t* fspath;
 | 
			
		||||
	qse_fs_mode_t oldmask;
 | 
			
		||||
	qse_fmode_t oldmask;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	if (*path == QSE_WT('\0')) 
 | 
			
		||||
 | 
			
		||||
@ -163,14 +163,14 @@ void qse_fs_freefspathforwcs (
 | 
			
		||||
int qse_fs_getattrsys (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	const qse_fs_char_t* fspath,
 | 
			
		||||
	qse_fs_attr_t*       attr,
 | 
			
		||||
	qse_fattr_t*       attr,
 | 
			
		||||
	int                  flags
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
int qse_fs_setattrsys (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	qse_fs_char_t*       path,
 | 
			
		||||
	const qse_fs_attr_t* attr,
 | 
			
		||||
	const qse_fattr_t* attr,
 | 
			
		||||
	int                  flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -183,7 +183,7 @@ int qse_fs_syscpfile (
 | 
			
		||||
int qse_fs_mkdirsys (
 | 
			
		||||
	qse_fs_t*            fs,
 | 
			
		||||
	const qse_fs_char_t* fspath,
 | 
			
		||||
	qse_fs_mode_t        mode
 | 
			
		||||
	qse_fmode_t          mode
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
int qse_fs_rmfilesys (
 | 
			
		||||
@ -206,6 +206,11 @@ int qse_fs_invokeactcb (
 | 
			
		||||
	qse_uintmax_t   bytes_done
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
void qse_stat_to_attr (
 | 
			
		||||
	const qse_stat_t* stat,
 | 
			
		||||
	qse_fattr_t*      attr
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -30,10 +30,15 @@
 | 
			
		||||
#include <qse/cmn/mem.h>
 | 
			
		||||
#include <qse/cmn/mbwc.h>
 | 
			
		||||
#include "../cmn/syscall.h"
 | 
			
		||||
#include "../cmn/mem-prv.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
qse_mchar_t* qse_get_current_mbsdir (qse_mchar_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
 | 
			
		||||
/* ==========================================================================
 | 
			
		||||
 * CURRENT WORKING DIRECTORY
 | 
			
		||||
 * ========================================================================== */
 | 
			
		||||
qse_mchar_t* qse_get_current_mbsdir (qse_mchar_t* buf, qse_size_t size)
 | 
			
		||||
{
 | 
			
		||||
	qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
 | 
			
		||||
	qse_mchar_t* tmp;
 | 
			
		||||
 | 
			
		||||
	if (buf)
 | 
			
		||||
@ -69,18 +74,19 @@ again:
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qse_wchar_t* qse_get_current_wcsdir (qse_wchar_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
 | 
			
		||||
qse_wchar_t* qse_get_current_wcsdir (qse_wchar_t* buf, qse_size_t size)
 | 
			
		||||
{
 | 
			
		||||
/* TODO: for WIN32, use the unicode API directly */
 | 
			
		||||
	qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
 | 
			
		||||
	qse_mchar_t* mbsdir;
 | 
			
		||||
	qse_wchar_t* wcsdir;
 | 
			
		||||
	qse_size_t wcslen;
 | 
			
		||||
 | 
			
		||||
	mbsdir = qse_get_current_mbsdir(QSE_NULL, 0, mmgr);
 | 
			
		||||
	mbsdir = qse_get_current_mbsdir(QSE_NULL, 0);
 | 
			
		||||
	if (!mbsdir) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	wcsdir = qse_mbstowcsdup(mbsdir, &wcslen, mmgr);
 | 
			
		||||
	QSE_MMGR_FREE (mmgr, mbsdir);
 | 
			
		||||
 | 
			
		||||
	if (!wcsdir) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	if (buf)
 | 
			
		||||
@ -92,24 +98,157 @@ qse_wchar_t* qse_get_current_wcsdir (qse_wchar_t* buf, qse_size_t size, qse_mmgr
 | 
			
		||||
			return QSE_NULL;
 | 
			
		||||
		}
 | 
			
		||||
		qse_wcscpy (buf, wcsdir);
 | 
			
		||||
		QSE_MMGR_FREE (mmgr, wcsdir);
 | 
			
		||||
		return buf;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return wcsdir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
int qse_get_mbsfile_stat (const qse_mchar_t* file, qse_fstat_t* stat)
 | 
			
		||||
 | 
			
		||||
/* ==========================================================================
 | 
			
		||||
 * FILE ATTRIBUTES
 | 
			
		||||
 * ========================================================================== */
 | 
			
		||||
void qse_stat_to_attr (const qse_stat_t* st, qse_fattr_t* attr)
 | 
			
		||||
{
 | 
			
		||||
	QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
 | 
			
		||||
 | 
			
		||||
	attr->isdir = !!S_ISDIR(st->st_mode);
 | 
			
		||||
	attr->islnk = !!S_ISLNK(st->st_mode);
 | 
			
		||||
	attr->isreg = !!S_ISREG(st->st_mode);
 | 
			
		||||
	attr->isblk = !!S_ISBLK(st->st_mode);
 | 
			
		||||
	attr->ischr = !!S_ISCHR(st->st_mode);
 | 
			
		||||
 | 
			
		||||
	attr->mode = st->st_mode;
 | 
			
		||||
	attr->size = st->st_size;
 | 
			
		||||
	attr->ino = st->st_ino;
 | 
			
		||||
	attr->dev = st->st_dev;
 | 
			
		||||
	attr->uid = st->st_uid;
 | 
			
		||||
	attr->gid = st->st_gid;
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
 | 
			
		||||
	attr->atime.sec = st->st_atim.tv_sec;
 | 
			
		||||
	attr->atime.nsec = st->st_atim.tv_nsec;
 | 
			
		||||
	attr->mtime.sec = st->st_mtim.tv_sec;
 | 
			
		||||
	attr->mtime.nsec = st->st_mtim.tv_nsec;
 | 
			
		||||
	attr->ctime.sec = st->st_ctim.tv_sec;
 | 
			
		||||
	attr->ctime.nsec = st->st_ctim.tv_nsec;
 | 
			
		||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
 | 
			
		||||
	attr->atime.sec = st->st_atimespec.tv_sec;
 | 
			
		||||
	attr->atime.nsec = st->st_atimespec.tv_nsec;
 | 
			
		||||
	attr->mtime.sec = st->st_mtimespec.tv_sec;
 | 
			
		||||
	attr->mtime.nsec = st->st_mtimespec.tv_nsec;
 | 
			
		||||
	attr->ctime.sec = st->st_ctimespec.tv_sec;
 | 
			
		||||
	attr->ctime.nsec = st->st_ctimespec.tv_nsec;
 | 
			
		||||
#else
 | 
			
		||||
	attr->atime.sec = st->st_atime;
 | 
			
		||||
	attr->mtime.sec = st->st_mtime;
 | 
			
		||||
	attr->ctime.sec = st->st_ctime;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_get_mbsfile_attr (const qse_mchar_t* file, int flags, qse_fattr_t* attr)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	return -1;
 | 
			
		||||
 | 
			
		||||
#elif defined(__OS2__)
 | 
			
		||||
	return -1;
 | 
			
		||||
 | 
			
		||||
#elif defined(__DOS__)
 | 
			
		||||
	return -1;
 | 
			
		||||
 | 
			
		||||
#elif defined(HAVE_FSTATAT) && defined(AT_SYMLINK_NOFOLLOW)
 | 
			
		||||
	qse_fstatat_t st;
 | 
			
		||||
	int sysflags = 0;
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
 | 
			
		||||
	if (QSE_FSTATAT(AT_FDCWD, file, &st, sysflags) <= -1) return -1;
 | 
			
		||||
 | 
			
		||||
	qse_stat_to_attr (&st, attr);
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	qse_stat_t st;
 | 
			
		||||
	int x;
 | 
			
		||||
 | 
			
		||||
	if (flags & QSE_FILE_ATTR_SYMLINK)
 | 
			
		||||
		x = QSE_LSTAT(file, &st);
 | 
			
		||||
	else
 | 
			
		||||
		x = QSE_STAT(file, &st);
 | 
			
		||||
	if (x <= -1) return -1;
 | 
			
		||||
 | 
			
		||||
	qse_stat_to_attr (&st, attr);
 | 
			
		||||
	return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_get_wcsfile_attr (const qse_wchar_t* file, int flags, qse_fattr_t* attr)
 | 
			
		||||
{
 | 
			
		||||
/* TODO: for WIN32, use the unicode API directly */
 | 
			
		||||
	qse_mchar_t* mbsfile;
 | 
			
		||||
	qse_mchar_t mbsfile_buf[QSE_PATH_MAX];
 | 
			
		||||
	qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
 | 
			
		||||
	qse_size_t wl, ml;
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
	ml = QSE_COUNTOF(mbsfile_buf);
 | 
			
		||||
	n = qse_wcstombs(file, &wl, mbsfile_buf, &ml);
 | 
			
		||||
	if (n == -2)
 | 
			
		||||
	{
 | 
			
		||||
		/* buffer too small */
 | 
			
		||||
		mbsfile = qse_wcstombsdup(file, QSE_NULL, mmgr);
 | 
			
		||||
		if (!mbsfile) return -1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (n <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		/* other errors */
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	else mbsfile = mbsfile_buf;
 | 
			
		||||
 | 
			
		||||
	n = qse_get_mbsfile_attr(mbsfile, flags, attr);
 | 
			
		||||
 | 
			
		||||
	if (mbsfile != mbsfile_buf)	QSE_MMGR_FREE (mmgr, mbsfile);
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_check_mbsfile_perm (const qse_mchar_t* file, int flags, qse_fperm_t perm)
 | 
			
		||||
{
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_get_wcsfile_stat (const qse_wchar_t* file, qse_fstat_t* stat)
 | 
			
		||||
int qse_check_wcsfile_perm (const qse_wchar_t* file, int flags, qse_fperm_t perm)
 | 
			
		||||
{
 | 
			
		||||
	return -1
 | 
			
		||||
}*/
 | 
			
		||||
/* TODO: for WIN32, use the unicode API directly */
 | 
			
		||||
	qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
 | 
			
		||||
	qse_mchar_t* mbsfile;
 | 
			
		||||
	qse_mchar_t mbsfile_buf[QSE_PATH_MAX];
 | 
			
		||||
	qse_size_t wl, ml;
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
 | 
			
		||||
	ml = QSE_COUNTOF(mbsfile_buf);
 | 
			
		||||
	n = qse_wcstombs(file, &wl, mbsfile_buf, &ml);
 | 
			
		||||
	if (n == -2)
 | 
			
		||||
	{
 | 
			
		||||
		/* buffer too small */
 | 
			
		||||
		mbsfile = qse_wcstombsdup(file, QSE_NULL, mmgr);
 | 
			
		||||
		if (!mbsfile) return -1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (n <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		/* other errors */
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	else mbsfile = mbsfile_buf;
 | 
			
		||||
 | 
			
		||||
	n = qse_check_mbsfile_perm(mbsfile, flags, perm);
 | 
			
		||||
 | 
			
		||||
	if (mbsfile != mbsfile_buf)	QSE_MMGR_FREE (mmgr, mbsfile);
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_get_prog_path_with_mmgr (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	if (GetModuleFileName(QSE_NULL, buf, size) == 0) return -1;
 | 
			
		||||
@ -123,14 +262,14 @@ int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size
 | 
			
		||||
	}
 | 
			
		||||
	else if (qse_strchr(argv0, QSE_T('/'))) 
 | 
			
		||||
	{
 | 
			
		||||
		if (!qse_get_current_dir(buf, size, mmgr)) return -1;
 | 
			
		||||
		if (!qse_get_current_dir(buf, size)) return -1;
 | 
			
		||||
		qse_strxcajoin (buf, size, QSE_T("/"), argv0, QSE_NULL);
 | 
			
		||||
		qse_canonpath (buf, buf, size);
 | 
			
		||||
	}
 | 
			
		||||
	else 
 | 
			
		||||
	{
 | 
			
		||||
		qse_char_t *p, *q, * px = QSE_NULL;
 | 
			
		||||
		qse_stat_t st;
 | 
			
		||||
		qse_fattr_t attr;
 | 
			
		||||
		qse_char_t dir[QSE_PATH_MAX + 1];
 | 
			
		||||
		qse_char_t pbuf[QSE_PATH_MAX + 1];
 | 
			
		||||
		int first = 1;
 | 
			
		||||
@ -149,7 +288,6 @@ int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size
 | 
			
		||||
			p = px;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		for (;;) 
 | 
			
		||||
		{
 | 
			
		||||
			while (*p == QSE_T(':')) p++;
 | 
			
		||||
@ -181,11 +319,14 @@ int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size
 | 
			
		||||
 | 
			
		||||
			qse_strxjoin (pbuf, QSE_COUNTOF(pbuf), dir, QSE_T("/"), argv0, QSE_NULL);
 | 
			
		||||
 | 
			
		||||
			if (qse_check_file_perm(pbuf, 0, QSE_FPERM_EXEC) >= 0 && 
 | 
			
		||||
			    qse_get_file_attr(pbuf, 0, &attr) >= 0 && attr.isreg) break;
 | 
			
		||||
			/*
 | 
			
		||||
			if (qse_access(pbuf, QSE_ACCESS_EXECUTE) == 0 && 
 | 
			
		||||
			    qse_stat(pbuf, &st) == 0 && S_ISREG(st.st_mode)) 
 | 
			
		||||
			{
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			}*/
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (px) QSE_MMGR_FREE (mmgr, px);
 | 
			
		||||
@ -193,7 +334,7 @@ int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size
 | 
			
		||||
		if (pbuf[0] == QSE_T('/')) qse_strxcpy (buf, size, pbuf);
 | 
			
		||||
		else 
 | 
			
		||||
		{
 | 
			
		||||
			if (!qse_get_current_dir(buf, size, mmgr)) return -1;
 | 
			
		||||
			if (!qse_get_current_dir(buf, size)) return -1;
 | 
			
		||||
			qse_strxcajoin (buf, size, QSE_T("/"), pbuf, QSE_NULL);
 | 
			
		||||
			qse_canonpath (buf, buf, size);
 | 
			
		||||
		}
 | 
			
		||||
@ -202,3 +343,8 @@ int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return qse_get_prog_path_with_mmgr(argv0, buf, size, QSE_MMGR_GETDFL());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user