From 739b40730ea9f755b83ba6be1b40ac00bf647877 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Wed, 7 Oct 2009 11:09:11 +0000 Subject: [PATCH] moving file by copying if rename fails with EXDEV (SEMS-58). changed the debug level of error messages to WARN git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1508 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- apps/dsm/mods/mod_sys/ModSys.cpp | 52 +++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/apps/dsm/mods/mod_sys/ModSys.cpp b/apps/dsm/mods/mod_sys/ModSys.cpp index 35da97a8..0e03c34c 100644 --- a/apps/dsm/mods/mod_sys/ModSys.cpp +++ b/apps/dsm/mods/mod_sys/ModSys.cpp @@ -165,16 +165,60 @@ EXEC_ACTION_START(SCMkDirRecursiveAction) { } } EXEC_ACTION_END; +// copies ifp to ofp, blockwise +void filecopy(FILE* ifp, FILE* ofp) { + size_t nread; + char buf[1024]; + + rewind(ifp); + while (!feof(ifp)) { + nread = fread(buf, 1, 1024, ifp); + if (fwrite(buf, 1, nread, ofp) != nread) + break; + } +} + CONST_ACTION_2P(SCRenameAction, ',', true); EXEC_ACTION_START(SCRenameAction) { string src = resolveVars(par1, sess, sc_sess, event_params); string dst = resolveVars(par2, sess, sc_sess, event_params); - if (!rename(src.c_str(), dst.c_str())) { + int rres = rename(src.c_str(), dst.c_str()); + if (!rres) { sc_sess->SET_ERRNO(DSM_ERRNO_OK); + } else if (rres == EXDEV) { + FILE* f1 = fopen(src.c_str(), "r"); + if (NULL == f1) { + WARN("opening source file '%s' for copying failed: '%s'\n", + src.c_str(), strerror(errno)); + sc_sess->SET_ERRNO(DSM_ERRNO_FILE); + return false; + } + + FILE* f2 = fopen(dst.c_str(), "w"); + if (NULL == f2) { + WARN("opening destination file '%s' for copying failed: '%s'\n", + dst.c_str(), strerror(errno)); + sc_sess->SET_ERRNO(DSM_ERRNO_FILE); + return false; + } + + filecopy(f1, f2); + + fclose(f1); + fclose(f2); + + if (unlink(src.c_str())) { + WARN("unlinking source file '%s' for copying failed: '%s'\n", + src.c_str(), strerror(errno)); + sc_sess->SET_ERRNO(DSM_ERRNO_FILE); + return false; + } + + sc_sess->SET_ERRNO(DSM_ERRNO_OK); } else { - DBG("renaming '%s' to '%s' failed: '%s'\n", - src.c_str(), dst.c_str(), strerror(errno)); + WARN("renaming '%s' to '%s' failed: '%s'\n", + src.c_str(), dst.c_str(), strerror(errno)); sc_sess->SET_ERRNO(DSM_ERRNO_FILE); } @@ -188,7 +232,7 @@ EXEC_ACTION_START(SCUnlinkAction) { if (!unlink(fname.c_str())) { sc_sess->SET_ERRNO(DSM_ERRNO_OK); } else { - DBG("unlink '%s' failed: '%s'\n", + WARN("unlink '%s' failed: '%s'\n", fname.c_str(), strerror(errno)); sc_sess->SET_ERRNO(DSM_ERRNO_FILE); }