From 206065f904eff236c157e0ae7c06e0ce9259d57d Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 17 Dec 2014 15:29:05 +0000 Subject: [PATCH] simplified file copying --- qse/bld/qse.bkl | 1 + qse/include/qse/cmn/fs.h | 24 +++++- qse/lib/cmn/Makefile.am | 1 + qse/lib/cmn/Makefile.in | 65 ++++++++-------- qse/lib/cmn/fs-attr.c | 135 ++++++++++++++++++++++++++++++++ qse/lib/cmn/fs-copy.c | 162 ++++++++++++++++----------------------- qse/lib/cmn/fs.c | 76 ------------------ qse/lib/cmn/fs.h | 11 ++- 8 files changed, 268 insertions(+), 207 deletions(-) create mode 100644 qse/lib/cmn/fs-attr.c diff --git a/qse/bld/qse.bkl b/qse/bld/qse.bkl index 73c69cf7..52571ace 100644 --- a/qse/bld/qse.bkl +++ b/qse/bld/qse.bkl @@ -172,6 +172,7 @@ fmt-intmax.c fmt-out.c fs.c + fs-attr.c fs-copy.c fs-delete.c fs-err.c diff --git a/qse/include/qse/cmn/fs.h b/qse/include/qse/cmn/fs.h index 401bf690..773823aa 100644 --- a/qse/include/qse/cmn/fs.h +++ b/qse/include/qse/cmn/fs.h @@ -111,7 +111,7 @@ struct qse_fs_ent_t qse_ntime_t create; qse_ntime_t access; qse_ntime_t modify; - qse_ntime_t change; /* inode status change */ + qse_ntime_t change; /* inode status change */ } time; }; @@ -124,11 +124,15 @@ struct qse_fs_attr_t 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 */ @@ -314,6 +318,24 @@ QSE_EXPORT int qse_fs_pop ( const qse_char_t* name ); +QSE_EXPORT int qse_fs_getattrmbs ( + qse_fs_t* fs, + const qse_mchar_t* path, + qse_fs_attr_t* attr +); + +QSE_EXPORT int qse_fs_getattrwcs ( + qse_fs_t* fs, + const qse_wchar_t* path, + qse_fs_attr_t* attr +); + +#if defined(QSE_CHAR_IS_MCHAR) +# define qse_fs_getattr(fs,path,attr) qse_fs_getattrmbs(fs,path,attr) +#else +# define qse_fs_getattr(fs,path,attr) qse_fs_getattrwcs(fs,path,attr) +#endif + QSE_EXPORT int qse_fs_move ( qse_fs_t* fs, const qse_char_t* oldpath, diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index 52d10e14..211de1c4 100644 --- a/qse/lib/cmn/Makefile.am +++ b/qse/lib/cmn/Makefile.am @@ -46,6 +46,7 @@ libqsecmn_la_SOURCES = \ fmt-intmax.c \ fmt-out.c \ fs.c \ + fs-attr.c \ fs-copy.c \ fs-delete.c \ fs-err.c \ diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in index 28bdd2b6..8d249d42 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -107,38 +107,40 @@ libqsecmn_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \ alg-sort.c assert.c chr.c dir.c dll.c env.c gdl.c htb.c fio.c \ - fma.c fmt-intmax.c fmt-out.c fs.c fs-copy.c fs-delete.c \ - fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \ - mb8.c mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \ - nwif-cfg.c nwio.c oht.c opt.c path-base.c path-canon.c \ - path-core.c path-merge.c pio.c pma.c rbt.c rex.c sck.c sio.c \ - sll.c slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \ - str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \ - str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \ - str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \ - str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \ - str-trm.c str-word.c task.c time.c tio.c tmr.c tre.c tre-ast.c \ - tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \ - tre-stack.c uri.c utf8.c xma.c uni.c cp949.c cp950.c + fma.c fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c \ + fs-delete.c fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c \ + lda.c main.c mb8.c mbwc.c mbwc-str.c mem.c mux.c nwad.c \ + nwad-skad.c nwif.c nwif-cfg.c nwio.c oht.c opt.c path-base.c \ + path-canon.c path-core.c path-merge.c pio.c pma.c rbt.c rex.c \ + sck.c sio.c sll.c slmb.c str-beg.c str-cat.c str-chr.c \ + str-cnv.c str-cmp.c str-cpy.c str-del.c str-dup.c str-dyn.c \ + str-end.c str-excl.c str-fcpy.c str-fmt.c str-fnmat.c \ + str-incl.c str-join.c str-len.c str-pac.c str-pbrk.c str-put.c \ + str-rev.c str-rot.c str-set.c str-spl.c str-spn.c str-str.c \ + str-subst.c str-tok.c str-trm.c str-word.c task.c time.c tio.c \ + tmr.c tre.c tre-ast.c tre-compile.c tre-match-bt.c \ + tre-match-pa.c tre-parse.c tre-stack.c uri.c utf8.c xma.c \ + uni.c cp949.c cp950.c @ENABLE_BUNDLED_UNICODE_TRUE@am__objects_1 = uni.lo @ENABLE_XCMGRS_TRUE@am__objects_2 = cp949.lo cp950.lo am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \ alg-sort.lo assert.lo chr.lo dir.lo dll.lo env.lo gdl.lo \ - htb.lo fio.lo fma.lo fmt-intmax.lo fmt-out.lo fs.lo fs-copy.lo \ - fs-delete.lo fs-err.lo fs-make.lo fs-move.lo glob.lo hton.lo \ - ipad.lo lda.lo main.lo mb8.lo mbwc.lo mbwc-str.lo mem.lo \ - mux.lo nwad.lo nwad-skad.lo nwif.lo nwif-cfg.lo nwio.lo oht.lo \ - opt.lo path-base.lo path-canon.lo path-core.lo path-merge.lo \ - pio.lo pma.lo rbt.lo rex.lo sck.lo sio.lo sll.lo slmb.lo \ - str-beg.lo str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo \ - str-cpy.lo str-del.lo str-dup.lo str-dyn.lo str-end.lo \ - str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo str-incl.lo \ - str-join.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \ - str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \ - str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \ - task.lo time.lo tio.lo tmr.lo tre.lo tre-ast.lo tre-compile.lo \ - tre-match-bt.lo tre-match-pa.lo tre-parse.lo tre-stack.lo \ - uri.lo utf8.lo xma.lo $(am__objects_1) $(am__objects_2) + htb.lo fio.lo fma.lo fmt-intmax.lo fmt-out.lo fs.lo fs-attr.lo \ + fs-copy.lo fs-delete.lo fs-err.lo fs-make.lo fs-move.lo \ + glob.lo hton.lo ipad.lo lda.lo main.lo mb8.lo mbwc.lo \ + mbwc-str.lo mem.lo mux.lo nwad.lo nwad-skad.lo nwif.lo \ + nwif-cfg.lo nwio.lo oht.lo opt.lo path-base.lo path-canon.lo \ + path-core.lo path-merge.lo pio.lo pma.lo rbt.lo rex.lo sck.lo \ + sio.lo sll.lo slmb.lo str-beg.lo str-cat.lo str-chr.lo \ + str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo str-dup.lo \ + str-dyn.lo str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo \ + str-fnmat.lo str-incl.lo str-join.lo str-len.lo str-pac.lo \ + str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \ + str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \ + str-trm.lo str-word.lo task.lo time.lo tio.lo tmr.lo tre.lo \ + tre-ast.lo tre-compile.lo tre-match-bt.lo tre-match-pa.lo \ + tre-parse.lo tre-stack.lo uri.lo utf8.lo xma.lo \ + $(am__objects_1) $(am__objects_2) libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -415,9 +417,9 @@ noinst_HEADERS = \ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \ assert.c chr.c dir.c dll.c env.c gdl.c htb.c fio.c fma.c \ - fmt-intmax.c fmt-out.c fs.c fs-copy.c fs-delete.c fs-err.c \ - fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c mb8.c \ - mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \ + fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c fs-delete.c \ + fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \ + mb8.c mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \ nwif-cfg.c nwio.c oht.c opt.c path-base.c path-canon.c \ path-core.c path-merge.c pio.c pma.c rbt.c rex.c sck.c sio.c \ sll.c slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \ @@ -529,6 +531,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-intmax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-out.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-attr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-copy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-delete.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-err.Plo@am__quote@ diff --git a/qse/lib/cmn/fs-attr.c b/qse/lib/cmn/fs-attr.c new file mode 100644 index 00000000..d1794ff0 --- /dev/null +++ b/qse/lib/cmn/fs-attr.c @@ -0,0 +1,135 @@ +/* + * $Id$ + * + Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fs.h" +#include "mem.h" + +int qse_fs_sysgetattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr) +{ +#if defined(_WIN32) + + fs->errnum = QSE_FS_ENOIMPL; + return -1; + +#elif defined(__OS2__) + + /* TODO */ + fs->errnum = QSE_FS_ENOIMPL; + return -1; + +#elif defined(__DOS__) + + fs->errnum = QSE_FS_ENOIMPL; + return -1; + +#else + #if defined(HAVE_LSTAT) + qse_lstat_t st; + #else + qse_stat_t st; + #endif + + #if defined(HAVE_LSTAT) + if (QSE_LSTAT (fspath, &st) == -1) + { + fs->errnum = qse_fs_syserrtoerrnum (fs, errno); + return -1; + } + #else + /* is this ok to use stat? */ + if (QSE_STAT (fspath, &st) == -1) + { + fs->errnum = qse_fs_syserrtoerrnum (fs, errno); + return -1; + } + #endif + + 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 + return 0; +#endif +} + + +int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* attr) +{ + qse_fs_char_t* fspath; + int ret; + + fspath = qse_fs_makefspathformbs (fs, path); + if (!fspath) return -1; + + ret = qse_fs_sysgetattr (fs, fspath, attr); + + qse_fs_freefspathformbs (fs, path, fspath); + return ret; +} + +int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* attr) +{ + qse_fs_char_t* fspath; + int ret; + + fspath = qse_fs_makefspathforwcs (fs, path); + if (!fspath) return -1; + + ret = qse_fs_sysgetattr (fs, fspath, attr); + + qse_fs_freefspathforwcs (fs, path, fspath); + return ret; +} diff --git a/qse/lib/cmn/fs-copy.c b/qse/lib/cmn/fs-copy.c index d21e2443..5e50274d 100644 --- a/qse/lib/cmn/fs-copy.c +++ b/qse/lib/cmn/fs-copy.c @@ -30,9 +30,7 @@ #include "mem.h" /* internal flags. it must not overlap with qse_fs_cpfile_flag_t enumerators */ -#define CPFILE_DST_ATTR (1 << 27) -#define CPFILE_DST_PATH_DUP (1 << 28) -#define CPFILE_DST_FSPATH_DUP (1 << 29) +#define CPFILE_DST_ATTR (1 << 29) #define CPFILE_DST_FSPATH_MERGED (1 << 30) struct cpfile_t @@ -42,14 +40,12 @@ struct cpfile_t qse_fs_char_t* src_fspath; qse_fs_char_t* dst_fspath; - qse_char_t* src_path; - qse_char_t* dst_path; - qse_fs_attr_t src_attr; qse_fs_attr_t dst_attr; }; typedef struct cpfile_t cpfile_t; + static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile) { qse_fs_char_t* fstmp; @@ -59,25 +55,6 @@ static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile) * in the directory */ QSE_ASSERT (cpfile->dst_attr.isdir); - if (cpfile->dst_path) - { - qse_char_t* tmp; - - tmp = qse_mergepathdup (cpfile->dst_path, qse_basename (cpfile->src_path), fs->mmgr); - if (!tmp) - { - fs->errnum = QSE_FS_ENOMEM; - return -1; - } - - if (cpfile->flags & CPFILE_DST_PATH_DUP) - QSE_MMGR_FREE (fs->mmgr, cpfile->dst_path); - - cpfile->dst_path = tmp; - cpfile->flags |= CPFILE_DST_PATH_DUP; - } - - fstmp = merge_fspath_dup (cpfile->dst_fspath, get_fspath_base (cpfile->src_fspath), fs->mmgr); if (!fstmp) { @@ -85,28 +62,25 @@ static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile) return -1; } - if (cpfile->flags & CPFILE_DST_FSPATH_DUP) - QSE_MMGR_FREE (fs->mmgr, cpfile->dst_fspath); + qse_fs_freefspath (fs, QSE_NULL, cpfile->dst_fspath); cpfile->dst_fspath = fstmp; - cpfile->flags |= CPFILE_DST_FSPATH_DUP; - if (qse_fs_getattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0) + if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) <= -1) { - cpfile->flags |= CPFILE_DST_ATTR; + /* attribute on the new destination is not available */ + cpfile->flags &= ~CPFILE_DST_ATTR; } else { - cpfile->flags &= ~CPFILE_DST_ATTR; + /* the attribute has been updated to reflect the new destination */ + cpfile->flags |= CPFILE_DST_ATTR; } cpfile->flags |= CPFILE_DST_FSPATH_MERGED; - - return 0; } - /* #if defined(_WIN32) DWORD copy_file_progress ( @@ -229,12 +203,12 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile) goto oops; } - out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, 0777); /* TODO: proper mode */ + out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, cpfile->src_attr.mode); if (out <= -1 && (cpfile->flags & QSE_FS_CPFILE_FORCE)) { /* if forced, delete it and try to open it again */ QSE_UNLINK (cpfile->dst_fspath); - out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, 0777); /* TODO: proper mode */ + out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, cpfile->src_attr.mode); } if (out <= -1) { @@ -267,7 +241,8 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile) struct timeval tv[2]; #endif - if (QSE_FCHOWN (out, cpfile->src_attr.uid, cpfile->src_attr.gid) <= -1) + if (QSE_FCHOWN (out, cpfile->src_attr.uid, cpfile->src_attr.gid) <= -1 || + QSE_FCHMOD (out, cpfile->src_attr.mode) <= -1) { fs->errnum = qse_fs_syserrtoerrnum (fs, errno); goto oops; @@ -311,6 +286,29 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile) #endif } +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 */ + if (qse_fs_sysgetattr (fs, cpfile->src_fspath, &cpfile->src_attr) <= -1) return -1; + if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0) cpfile->flags |= CPFILE_DST_ATTR; + return 0; +} + +static void clear_cpfile (qse_fs_t* fs, cpfile_t* cpfile) +{ + if (cpfile->src_fspath) + { + QSE_MMGR_FREE (fs->mmgr, cpfile->src_fspath); + cpfile->src_fspath = QSE_NULL; + } + if (cpfile->dst_fspath) + { + QSE_MMGR_FREE (fs->mmgr, cpfile->dst_fspath); + cpfile->dst_fspath = QSE_NULL; + } +} + static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) { if (cpfile->src_attr.isdir) @@ -320,11 +318,11 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) qse_dir_t* dir; qse_dir_errnum_t direrr; qse_dir_ent_t dirent; - qse_char_t* src_path, * dst_path; + cpfile_t sub_cpfile; int x; copy_dir: - if (cpfile->flags & CPFILE_DST_ATTR) + if (cpfile->flags & CPFILE_DST_ATTR) { if (!cpfile->dst_attr.isdir) { @@ -361,12 +359,20 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) if (!(cpfile->flags & QSE_FS_CPFILE_RECURSIVE)) { - /* cann not copy a directory without recursion */ + /* cannot copy a directory without recursion */ fs->errnum = QSE_FS_EISDIR; return -1; } - dir = qse_dir_open (fs->mmgr, 0, cpfile->src_path, QSE_DIR_SKIPSPCDIR, &direrr); + dir = qse_dir_open ( + fs->mmgr, 0, (const qse_char_t*)cpfile->src_fspath, + #if defined(QSE_FS_CHAR_IS_MCHAR) + QSE_DIR_SKIPSPCDIR | QSE_DIR_MBSPATH, + #else + QSE_DIR_SKIPSPCDIR | QSE_DIR_WCSPATH, + #endif + &direrr + ); if (!dir) { fs->errnum = qse_fs_direrrtoerrnum (fs, direrr); @@ -390,21 +396,21 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) } if (x == 0) break; /* no more entries */ - - src_path = qse_mergepathdup (cpfile->src_path, dirent.name, fs->mmgr); - dst_path = qse_mergepathdup (cpfile->dst_path, dirent.name, fs->mmgr); - if (!src_path || !dst_path) + QSE_MEMSET (&sub_cpfile, 0, QSE_SIZEOF(sub_cpfile)); + sub_cpfile.flags = cpfile->flags & QSE_FS_CPFILE_ALL; /* inherit public flags */ + sub_cpfile.src_fspath = merge_fspath_dup (cpfile->src_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr); + sub_cpfile.dst_fspath = merge_fspath_dup (cpfile->dst_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr); + if (!sub_cpfile.src_fspath || !sub_cpfile.dst_fspath || prepare_cpfile (fs, &sub_cpfile) <= -1) { - if (dst_path) QSE_MMGR_FREE (fs->mmgr, dst_path); - if (src_path) QSE_MMGR_FREE (fs->mmgr, src_path); + clear_cpfile (fs, &sub_cpfile); qse_dir_close (dir); return -1; } - x = qse_fs_cpfile (fs, src_path, dst_path, (cpfile->flags & QSE_FS_CPFILE_ALL)); + x = copy_file (fs, &sub_cpfile); /* TODO: remove recursion */ + + clear_cpfile (fs, &sub_cpfile); - QSE_MMGR_FREE (fs->mmgr, dst_path); - QSE_MMGR_FREE (fs->mmgr, src_path); if (x <= -1) { qse_dir_close (dir); @@ -469,34 +475,17 @@ int qse_fs_cpfilembs (qse_fs_t* fs, const qse_mchar_t* srcpath, const qse_mchar_ cpfile.flags = flags & QSE_FS_CPFILE_ALL; /* keep public flags only */ - cpfile.src_fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, srcpath); - cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, dstpath); - cpfile.src_path = (qse_char_t*)make_str_with_mbs (fs, srcpath); - cpfile.dst_path = (qse_char_t*)make_str_with_mbs (fs, dstpath); - if (!cpfile.src_fspath || !cpfile.dst_fspath || !cpfile.src_path || !cpfile.dst_path) goto oops; - - if (cpfile.dst_fspath != dstpath) - { - /* mark that it's been duplicated. */ - cpfile.flags |= CPFILE_DST_FSPATH_DUP; - } - - if (qse_fs_getattr (fs, cpfile.src_fspath, &cpfile.src_attr) <= -1) goto oops; - if (qse_fs_getattr (fs, cpfile.dst_fspath, &cpfile.dst_attr) >= 0) cpfile.flags |= CPFILE_DST_ATTR; + cpfile.src_fspath = (qse_fs_char_t*)qse_fs_dupfspathformbs (fs, srcpath); + cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_dupfspathformbs (fs, dstpath); + if (!cpfile.src_fspath || !cpfile.dst_fspath || prepare_cpfile (fs, &cpfile) <= -1) goto oops; ret = copy_file (fs, &cpfile); - free_str_with_mbs (fs, dstpath, cpfile.dst_path); - free_str_with_mbs (fs, srcpath, cpfile.src_path); - qse_fs_freefspathformbs (fs, dstpath, cpfile.dst_fspath); - qse_fs_freefspathformbs (fs, srcpath, cpfile.src_fspath); + clear_cpfile (fs, &cpfile); return ret; oops: - if (cpfile.dst_path) free_str_with_mbs (fs, dstpath, cpfile.dst_path); - if (cpfile.src_path) free_str_with_mbs (fs, srcpath, cpfile.src_path); - if (cpfile.dst_fspath) qse_fs_freefspathformbs (fs, srcpath, cpfile.dst_fspath); - if (cpfile.src_fspath) qse_fs_freefspathformbs (fs, dstpath, cpfile.src_fspath); + clear_cpfile (fs, &cpfile); return -1; } @@ -509,35 +498,16 @@ int qse_fs_cpfilewcs (qse_fs_t* fs, const qse_wchar_t* srcpath, const qse_wchar_ cpfile.flags = flags & QSE_FS_CPFILE_ALL; /* keep public flags only */ - cpfile.src_fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, srcpath); - cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, dstpath); - cpfile.src_path = (qse_char_t*)make_str_with_wcs (fs, srcpath); - cpfile.dst_path = (qse_char_t*)make_str_with_wcs (fs, dstpath); - if (!cpfile.src_fspath || !cpfile.dst_fspath || !cpfile.src_path || !cpfile.dst_path) goto oops; - - if (cpfile.dst_fspath != dstpath) - { - /* mark that it's been duplicated */ - cpfile.flags |= CPFILE_DST_FSPATH_DUP; - } - - if (qse_fs_getattr (fs, cpfile.src_fspath, &cpfile.src_attr) <= -1) goto oops; - if (qse_fs_getattr (fs, cpfile.dst_fspath, &cpfile.dst_attr) >= 0) cpfile.flags |= CPFILE_DST_ATTR; + cpfile.src_fspath = (qse_fs_char_t*)qse_fs_dupfspathforwcs (fs, srcpath); + cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_dupfspathforwcs (fs, dstpath); + if (!cpfile.src_fspath || !cpfile.dst_fspath || prepare_cpfile (fs, &cpfile) <= -1) goto oops; ret = copy_file (fs, &cpfile); - free_str_with_wcs (fs, dstpath, cpfile.dst_path); - free_str_with_wcs (fs, srcpath, cpfile.src_path); - qse_fs_freefspathforwcs (fs, dstpath, cpfile.dst_fspath); - qse_fs_freefspathforwcs (fs, srcpath, cpfile.src_fspath); + clear_cpfile (fs, &cpfile); return ret; oops: - if (cpfile.dst_path) free_str_with_wcs (fs, dstpath, cpfile.dst_path); - if (cpfile.src_path) free_str_with_wcs (fs, srcpath, cpfile.src_path); - if (cpfile.dst_fspath) qse_fs_freefspathforwcs (fs, srcpath, cpfile.dst_fspath); - if (cpfile.src_fspath) qse_fs_freefspathforwcs (fs, dstpath, cpfile.src_fspath); + clear_cpfile (fs, &cpfile); return -1; } - - diff --git a/qse/lib/cmn/fs.c b/qse/lib/cmn/fs.c index c5643799..2f1c60de 100644 --- a/qse/lib/cmn/fs.c +++ b/qse/lib/cmn/fs.c @@ -815,79 +815,3 @@ void qse_fs_freefspathforwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_char } -int qse_fs_getattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr) -{ -#if defined(_WIN32) - - fs->errnum = QSE_FS_ENOIMPL; - return -1; - -#elif defined(__OS2__) - - /* TODO */ - fs->errnum = QSE_FS_ENOIMPL; - return -1; - -#elif defined(__DOS__) - - fs->errnum = QSE_FS_ENOIMPL; - return -1; - -#else - #if defined(HAVE_LSTAT) - qse_lstat_t st; - #else - qse_stat_t st; - #endif - - #if defined(HAVE_LSTAT) - if (QSE_LSTAT (fspath, &st) == -1) - { - fs->errnum = qse_fs_syserrtoerrnum (fs, errno); - return -1; - } - #else - /* is this ok to use stat? */ - if (QSE_STAT (fspath, &st) == -1) - { - fs->errnum = qse_fs_syserrtoerrnum (fs, errno); - return -1; - } - #endif - - 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->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 - return 0; -#endif -} diff --git a/qse/lib/cmn/fs.h b/qse/lib/cmn/fs.h index c5f2a90a..47575d60 100644 --- a/qse/lib/cmn/fs.h +++ b/qse/lib/cmn/fs.h @@ -143,11 +143,16 @@ void qse_fs_freefspathforwcs ( # define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathforwcs(fs,path,fspath); #endif - -int qse_fs_getattr ( +int qse_fs_sysgetattr ( qse_fs_t* fs, const qse_fs_char_t* fspath, - qse_fs_attr_t* attr + qse_fs_attr_t* attr +); + +int qse_fs_syscpfile ( + qse_fs_t* fs, + const qse_fs_char_t* srcpath, + const qse_fs_char_t* dstpath ); int qse_fs_sysmkdir (