diff --git a/qse/include/qse/si/fs.h b/qse/include/qse/si/fs.h index 8ba2250f..300ea351 100644 --- a/qse/include/qse/si/fs.h +++ b/qse/include/qse/si/fs.h @@ -36,6 +36,58 @@ #include #include +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 diff --git a/qse/lib/si/Makefile.in b/qse/lib/si/Makefile.in index 514042a1..862652d6 100644 --- a/qse/lib/si/Makefile.in +++ b/qse/lib/si/Makefile.in @@ -410,6 +410,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/qse/lib/si/Path.cpp b/qse/lib/si/Path.cpp index c80ae6f5..3cb53702 100644 --- a/qse/lib/si/Path.cpp +++ b/qse/lib/si/Path.cpp @@ -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; } diff --git a/qse/lib/si/fs-attr.c b/qse/lib/si/fs-attr.c index 3d3dc241..d50a6022 100644 --- a/qse/lib/si/fs-attr.c +++ b/qse/lib/si/fs-attr.c @@ -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; diff --git a/qse/lib/si/fs-copy.c b/qse/lib/si/fs-copy.c index 64273d6e..28579a44 100644 --- a/qse/lib/si/fs-copy.c +++ b/qse/lib/si/fs-copy.c @@ -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) diff --git a/qse/lib/si/fs-make.c b/qse/lib/si/fs-make.c index 85734fb6..d6489f4f 100644 --- a/qse/lib/si/fs-make.c +++ b/qse/lib/si/fs-make.c @@ -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')) diff --git a/qse/lib/si/fs-prv.h b/qse/lib/si/fs-prv.h index 61cc43b1..83230e89 100644 --- a/qse/lib/si/fs-prv.h +++ b/qse/lib/si/fs-prv.h @@ -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 diff --git a/qse/lib/si/fs-util.c b/qse/lib/si/fs-util.c index 9106179c..c032c11f 100644 --- a/qse/lib/si/fs-util.c +++ b/qse/lib/si/fs-util.c @@ -30,10 +30,15 @@ #include #include #include "../cmn/syscall.h" +#include "../cmn/mem-prv.h" #include -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()); +}