This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efm2.
View the commit online.
commit 575fbfa026df5575e0d68132c3f92450c49c7bdf
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Mon Apr 29 19:14:25 2024 +0100
move fs working code into fs.c and make it also do rm and cp
---
src/backends/default/{mv.c => fs.c} | 379 +++++++++++++-----------------
src/backends/default/fs.h | 10 +
src/backends/default/meson.build | 1 +
src/backends/default/mv.c | 447 +-----------------------------------
4 files changed, 175 insertions(+), 662 deletions(-)
diff --git a/src/backends/default/mv.c b/src/backends/default/fs.c
similarity index 57%
copy from src/backends/default/mv.c
copy to src/backends/default/fs.c
index 740357e..593fef3 100644
--- a/src/backends/default/mv.c
+++ b/src/backends/default/fs.c
@@ -1,16 +1,10 @@
// for copy_file_range()
-#include <asm-generic/errno-base.h>
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <Eina.h>
-#include <Ecore.h>
#include <Ecore_File.h>
-#include <Efreet.h>
-#include <Efreet_Mime.h>
-#include <Eet.h>
-#include <asm-generic/errno.h>
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
@@ -18,10 +12,8 @@
#include <unistd.h>
#include <fcntl.h>
-#include "meta.h"
#include "status.h"
-
-static const char *config_dir = NULL;
+#include "fs.h"
// generic error handler. special case handling all errnos for everything is
// pretty insane - so handle non-errors in switches and otherwise pass to
@@ -107,7 +99,7 @@ _error_handle(const char *src, const char *dst, int errno_in)
// not be 100% right as the fs can change while the scan happens and after
// so any move that devolves into a cp + rm isn't going to be atomic and
// handle a changing fs while it works anyway
-static Eina_Bool
+Eina_Bool
fs_scan(const char *src)
{
Eina_Bool res = EINA_TRUE;
@@ -150,14 +142,14 @@ fs_scan(const char *src)
// or a char or block device etc.
status_count(1, ecore_file_file_get(src));
// in addition each byte in the file count as a progress item too
- if (st.st_size > 0)
- status_count(st.st_size, ecore_file_file_get(src));
+ if (st.st_size > 0) status_count(st.st_size, ecore_file_file_get(src));
}
return res;
}
-static Eina_Bool
-fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
+Eina_Bool
+fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
+ Eina_Bool rm)
{ // cp_rm /path/to/src/filename /path/to/dst/filename
// XXX: ecore_file_mv() ? <- look at it
// XXX: utime()/utimes() -> utimensat()
@@ -196,7 +188,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
// fs_chmod(src_meta, dst_meta)
// fs_chown(src_meta, dst_meta)
// fs_rm(src_meta)
- Eina_Bool res = EINA_TRUE;
+ Eina_Bool res = EINA_TRUE;
Eina_Iterator *it;
const char *s;
struct stat st;
@@ -225,16 +217,19 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
old_umask = umask(0);
if (S_ISDIR(st.st_mode))
{ // it's a dir - scan this recursively
- if (mkdir(dst, st.st_mode) != 0)
+ if (cp)
{
- switch (errno)
+ if (mkdir(dst, st.st_mode) != 0)
{
- case EEXIST: // ignore - mv would mv over this anyway
- break;
- default: // WAT
- _error_handle(NULL, dst, errno);
- res = EINA_FALSE;
- goto err;
+ switch (errno)
+ {
+ case EEXIST: // ignore - mv would mv over this anyway
+ break;
+ default: // WAT
+ _error_handle(NULL, dst, errno);
+ res = EINA_FALSE;
+ goto err;
+ }
}
}
it = eina_file_ls(src);
@@ -243,7 +238,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
EINA_ITERATOR_FOREACH(it, s)
{
Eina_Strbuf *buf = eina_strbuf_new();
- const char *fs = ecore_file_file_get(s);
+ const char *fs = ecore_file_file_get(s);
if (buf)
{
@@ -252,7 +247,8 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
eina_strbuf_append(buf, dst);
eina_strbuf_append(buf, "/");
eina_strbuf_append(buf, fs);
- if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err))
+ if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err,
+ cp, rm))
res = EINA_FALSE;
}
eina_strbuf_free(buf);
@@ -261,149 +257,194 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
}
eina_iterator_free(it);
}
- if (res) rmdir(src);
+ if ((rm) && (res))
+ {
+ if (rmdir(src) != 0)
+ {
+ switch (errno)
+ {
+ case ENOENT: // ignore missing
+ break;
+ default:
+ _error_handle(src, NULL, errno);
+ res = EINA_FALSE;
+ goto err;
+ }
+ }
+ }
}
else if (S_ISLNK(st.st_mode))
{
- char link[PATH_MAX];
- ssize_t lnsz;
+ if (cp)
+ {
+ char link[PATH_MAX];
+ ssize_t lnsz;
- lnsz = readlink(src, link, sizeof(link));
- if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
- {
- if (symlink(link, dst) < 0)
- { // XXX: soft error? e.g. mv on FAT fs?
- status_pos(1, "Move - Error creating symlink");
- }
- }
- else if (lnsz < 0)
- { // XXX: handle read link err
- switch (errno)
+ lnsz = readlink(src, link, sizeof(link));
+ if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
{
- case ENOENT: // ignore this error - file removed during scan ?
- status_pos(1, "Move - File vanished");
- break;
- default:
- _error_handle(src, dst, errno);
- return EINA_FALSE;
+ if (symlink(link, dst) < 0)
+ { // XXX: soft error? e.g. mv on FAT fs?
+ status_pos(1, "Move - Error creating symlink");
+ }
+ }
+ else if (lnsz < 0)
+ { // XXX: handle read link err
+ switch (errno)
+ {
+ case ENOENT: // ignore this error - file removed during scan ?
+ status_pos(1, "Move - File vanished");
+ break;
+ default:
+ _error_handle(src, dst, errno);
+ return EINA_FALSE;
+ }
+ }
+ else // 0 sized symlink ... WAT?
+ { // XXX: handle this
}
- }
- else // 0 sized symlink ... WAT?
- {
}
}
else if (S_ISFIFO(st.st_mode))
{
- if (mkfifo(dst, st.st_mode) < 0)
- { // XXX: soft error? ignore?
+ if (cp)
+ {
+ if (mkfifo(dst, st.st_mode) < 0)
+ { // XXX: soft error? ignore?
+ }
}
}
else if (S_ISSOCK(st.st_mode))
{
- // we can't just make sockets - so ignore but have this here to document
+ if (cp)
+ {
+ // we can't just make sockets - so ignore but document here
+ }
}
else if ((S_ISCHR(st.st_mode)) || (S_ISBLK(st.st_mode)))
{
- if (mknod(dst, st.st_mode, st.st_dev) < 0)
- { // XXX: soft error? ignore?
+ if (cp)
+ {
+ if (mknod(dst, st.st_mode, st.st_dev) < 0)
+ { // XXX: soft error? ignore?
+ }
}
}
else
{
- int fd_in, fd_ou;
- void *old_copy_buf = NULL;
-
- fd_in = open(src, O_RDONLY);
- fd_ou = open(dst, O_WRONLY | O_CREAT, st.st_mode);
- if ((fd_in >= 0) && (fd_ou >= 0))
+ if (cp)
{
- ssize_t size = 1 * 1024 * 1024; // 1mb default
- ssize_t ret, ret2;
- off_t off_in = 0, off_ou = 0;
- Eina_Bool old_copy = EINA_FALSE;
+ int fd_in, fd_ou;
+ void *old_copy_buf = NULL;
- for (;;)
+ fd_in = open(src, O_RDONLY);
+ fd_ou = open(dst, O_WRONLY | O_CREAT, st.st_mode);
+ if ((fd_in >= 0) && (fd_ou >= 0))
{
- if (old_copy)
+ ssize_t size = 1 * 1024 * 1024; // 1mb default
+ ssize_t ret, ret2;
+ off_t off_in = 0, off_ou = 0;
+ Eina_Bool old_copy = EINA_FALSE;
+
+ for (;;)
{
- if (!old_copy_buf)
+ if (old_copy)
{
- size = 256 * 1024; // drop to 256k buffer
- old_copy_buf = malloc(size);
if (!old_copy_buf)
{
- res = EINA_FALSE;
- goto err_copy;
+ size = 256 * 1024; // drop to 256k buffer
+ old_copy_buf = malloc(size);
+ if (!old_copy_buf)
+ {
+ res = EINA_FALSE;
+ goto err_copy;
+ }
}
- }
again_read:
- ret = read(fd_in, old_copy_buf, size);
- if (ret < 0)
- {
- switch (errno)
- {
- case EAGAIN:
- case EINTR:
- goto again_read;
- default:
- _error_handle(src, NULL, errno);
- res = EINA_FALSE;
- goto err_copy;
- }
- }
- else
- {
- off_in += ret;
-again_write:
- ret2 = write(fd_ou, old_copy_buf, ret);
- if (ret2 < 0)
+ ret = read(fd_in, old_copy_buf, size);
+ if (ret < 0)
{
switch (errno)
{
case EAGAIN:
case EINTR:
- goto again_write;
+ goto again_read;
default:
- _error_handle(NULL, dst, errno);
+ _error_handle(src, NULL, errno);
res = EINA_FALSE;
goto err_copy;
}
}
- else if (ret2 == ret)
+ else
{
- off_ou += ret;
- if (ret < size) break; // end of file
+ off_in += ret;
+again_write:
+ ret2 = write(fd_ou, old_copy_buf, ret);
+ if (ret2 < 0)
+ {
+ switch (errno)
+ {
+ case EAGAIN:
+ case EINTR:
+ goto again_write;
+ default:
+ _error_handle(NULL, dst, errno);
+ res = EINA_FALSE;
+ goto err_copy;
+ }
+ }
+ else if (ret2 == ret)
+ {
+ off_ou += ret;
+ if (ret < size) break; // end of file
+ }
}
}
- }
- else
- {
- ret = copy_file_range(fd_in, &off_in, fd_ou, &off_ou, size, 0);
- if (ret < 0)
+ else
{
- switch (errno)
- {
- case EOPNOTSUPP:
- case EXDEV:
- old_copy = EINA_TRUE;
- break;
- case EBADF:
- default: // WAT
- _error_handle(src, dst, errno);
- res = EINA_FALSE;
- goto err_copy;
- }
+ ret = copy_file_range(fd_in, &off_in, fd_ou, &off_ou,
+ size, 0);
+ if (ret < 0)
+ {
+ switch (errno)
+ {
+ case EOPNOTSUPP:
+ case EXDEV:
+ old_copy = EINA_TRUE;
+ break;
+ case EBADF:
+ default: // WAT
+ _error_handle(src, dst, errno);
+ res = EINA_FALSE;
+ goto err_copy;
+ }
+ }
+ else if (ret < size) break; // end of file
}
- else if (ret < size) break; // end of file
+ }
+ }
+err_copy:
+ if (old_copy_buf) free(old_copy_buf);
+ if (fd_in >= 0) close(fd_in);
+ if (fd_ou >= 0) close(fd_ou);
+ }
+ if ((rm) && (res))
+ {
+ if (unlink(src) != 0)
+ {
+ switch (errno)
+ {
+ case ENOENT: // ignore missing
+ break;
+ default:
+ _error_handle(src, NULL, errno);
+ res = EINA_FALSE;
+ goto err_unlink;
}
}
}
-err_copy:
- if (old_copy_buf) free(old_copy_buf);
- if (fd_in >= 0) close(fd_in);
- if (fd_ou >= 0) close(fd_ou);
- if (res) unlink(src);
}
+err_unlink:
chown(dst, st.st_uid, st.st_gid);
#ifdef STAT_NSEC
#ifdef st_mtime
@@ -435,11 +476,11 @@ err:
return res;
}
-static Eina_Bool
+Eina_Bool
fs_mv(const char *src, const char *dst, Eina_Bool report_err)
{ // mv /path/to/src/filename /path/to/dst/filename
Eina_Bool res = EINA_TRUE;
- int ret;
+ int ret;
status_op("mv");
status_count(1, src);
@@ -450,7 +491,7 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
switch (errno)
{
case EXDEV: // revert to cp + rm
- return fs_cp_rm(src, dst, report_err);
+ return fs_cp_rm(src, dst, report_err, EINA_TRUE, EINA_TRUE);
break;
default:
if (report_err) _error_handle(src, dst, errno);
@@ -461,97 +502,3 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
status_pos(1, src);
return res;
}
-
-int
-main(int argc, char **argv)
-{ // mv [src] [dst]
- const char *src, *dst, *fname, *home_dir;
- Eina_Strbuf *buf = NULL;
-
- if (argc < 3) return -1;
- src = ""
- dst = argv[2];
- eina_init();
- eet_init();
- ecore_init();
- efreet_init();
-
- fprintf(stderr, "MV: [%s] -> [%s]\n", src, dst);
- fflush(stderr);
-
- config_dir = getenv("E_HOME_DIR");
- home_dir = getenv("HOME");
- if (!home_dir) return 77; // no $HOME? definitely an error!
- if (!config_dir)
- {
- char sbuf[PATH_MAX];
-
- snprintf(sbuf, sizeof(sbuf), "%s/.e/e", home_dir);
- config_dir = eina_stringshare_add(sbuf);
- }
- meta_init(config_dir);
-
- // src = ""
- // dst = DDIR/
- //
- // mv SDIR/SFILE DDIR/SFILE
- // if errno == EXDEV
- // cp SDIR/SFILE DDIR/SFILE
- // rm SDIR/SFILE
- // else if errno == 0
- // if exists SDIR/.efm/SFILE.efm
- // mkdir DDIR/.efm
- // mv SDIR/.efm/SFILE.efm DDIR/.efm/SFILE.efm
-
- fname = ecore_file_file_get(src);
- if (!fname) goto err;
- buf = eina_strbuf_new();
- if (!buf) goto err;
- eina_strbuf_append(buf, dst);
- eina_strbuf_append(buf, "/");
- eina_strbuf_append(buf, fname);
- status_begin();
- if (fs_mv(src, eina_strbuf_string_get(buf), EINA_TRUE))
- {
- Eina_Bool src_can_write, dst_can_write;
- const char *dstfile;
- char *src_meta, *dst_meta;
-
- dstfile = eina_strbuf_string_get(buf);
-
- src_can_write = meta_path_can_write(src);
- dst_can_write = meta_path_can_write(eina_strbuf_string_get(buf));
-
- if (src_can_write) src_meta = meta_path_find(src, "meta.efm");
- else src_meta = meta_path_user_find(src, "meta.efm");
- if (dst_can_write) dst_meta = meta_path_find(dstfile, "meta.efm");
- else dst_meta = meta_path_user_find(dstfile, "meta.efm");
- if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
- fs_mv(src_meta, dst_meta, EINA_FALSE);
- free(src_meta);
- free(dst_meta);
- if (src_can_write) src_meta = meta_path_find(src, "thumb.efm");
- else src_meta = meta_path_user_find(src, "thumb.efm");
- if (dst_can_write) dst_meta = meta_path_find(dstfile, "thumb.efm");
- else dst_meta = meta_path_user_find(dstfile, "thumb.efm");
- if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
- fs_mv(src_meta, dst_meta, EINA_FALSE);
- free(src_meta);
- free(dst_meta);
- }
- else
- {
- status_end();
- }
-err:
- if (buf) eina_strbuf_free(buf);
- status_end();
-
- meta_shutdown();
-
- efreet_shutdown();
- ecore_shutdown();
- eet_shutdown();
- eina_shutdown();
- return 0;
-}
\ No newline at end of file
diff --git a/src/backends/default/fs.h b/src/backends/default/fs.h
new file mode 100644
index 0000000..cb50630
--- /dev/null
+++ b/src/backends/default/fs.h
@@ -0,0 +1,10 @@
+#ifndef FS_H
+#define FS_H
+#include <Eina.h>
+
+Eina_Bool fs_scan(const char *src);
+Eina_Bool fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err,
+ Eina_Bool cp, Eina_Bool rm);
+Eina_Bool fs_mv(const char *src, const char *dst, Eina_Bool report_err);
+
+#endif
\ No newline at end of file
diff --git a/src/backends/default/meson.build b/src/backends/default/meson.build
index 4aba107..c464309 100644
--- a/src/backends/default/meson.build
+++ b/src/backends/default/meson.build
@@ -36,6 +36,7 @@ executable('thumb', [
install_dir: dir)
executable('mv', [
'../../shared/sha.c',
+ 'fs.c',
'mv.c',
'meta.c',
'status.c'
diff --git a/src/backends/default/mv.c b/src/backends/default/mv.c
index 740357e..08004a3 100644
--- a/src/backends/default/mv.c
+++ b/src/backends/default/mv.c
@@ -1,8 +1,3 @@
-// for copy_file_range()
-#include <asm-generic/errno-base.h>
-#define _GNU_SOURCE
-#define _FILE_OFFSET_BITS 64
-
#include <Eina.h>
#include <Ecore.h>
#include <Ecore_File.h>
@@ -10,8 +5,6 @@
#include <Efreet_Mime.h>
#include <Eet.h>
-#include <asm-generic/errno.h>
-#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
@@ -20,448 +13,10 @@
#include "meta.h"
#include "status.h"
+#include "fs.h"
static const char *config_dir = NULL;
-// generic error handler. special case handling all errnos for everything is
-// pretty insane - so handle non-errors in switches and otherwise pass to
-// this tio handle the reast in a generic way.
-static void
-_error_handle(const char *src, const char *dst, int errno_in)
-{
- switch (errno_in)
- {
- case EACCES:
- status_error(src, dst, "Move - Access denied");
- return;
- case EFAULT:
- status_error(src, dst, "Move - Memory Fault");
- return;
- case ELOOP:
- status_error(src, dst, "Move - Too many symlinks");
- return;
- case ENAMETOOLONG:
- status_error(src, dst, "Move - Name too long");
- return;
- case ENOMEM:
- status_error(src, dst, "Move - Out of memory");
- return;
- case ENOTDIR:
- status_error(src, dst, "Move - Path component is not a directory");
- return;
- case EOVERFLOW:
- status_error(src, dst, "Move - Overflow");
- return;
- case EDQUOT:
- status_error(src, dst, "Move - Over quota");
- return;
- case EINVAL:
- status_error(src, dst, "Move - Inmvalid value");
- return;
- case EMLINK:
- status_error(src, dst, "Move - Too many source links");
- return;
- case ENOENT:
- status_error(src, dst, "Move - File does not exist");
- return;
- case ENOSPC:
- status_error(src, dst, "Move - Disk full");
- return;
- case EPERM:
- status_error(src, dst, "Move - Permission denied");
- return;
- case EROFS:
- status_error(src, dst, "Move - Read only filesystem");
- return;
- case EBADF:
- status_error(src, dst, "Move - Bad file descriptor");
- return;
- case EIO:
- status_error(src, dst, "Move - I/O error");
- return;
- case EISDIR:
- status_error(src, dst, "Move - Destination is dir");
- return;
- case EFBIG:
- status_error(src, dst, "Move - File too big");
- return;
- case ETXTBSY:
- status_error(src, dst, "Move - Text file busy");
- return;
- case EBUSY:
- status_error(src, dst, "Move - File busy");
- return;
- case ENOTEMPTY:
- status_error(src, dst, "Move - Destination not empty");
- return;
- case EEXIST:
- status_error(src, dst, "Move - File exists");
- return;
- default: // WAT? we should not get here - we handled everything...
- status_error(src, dst, "Move - Unknown error");
- break;
- }
-}
-
-// this scans a tree to build a potential operation progress count. it may
-// not be 100% right as the fs can change while the scan happens and after
-// so any move that devolves into a cp + rm isn't going to be atomic and
-// handle a changing fs while it works anyway
-static Eina_Bool
-fs_scan(const char *src)
-{
- Eina_Bool res = EINA_TRUE;
- Eina_Iterator *it;
- const char *s;
- struct stat st;
-
- if (strlen(src) < 1) return EINA_FALSE;
-
- if (lstat(src, &st) != 0)
- {
- switch (errno)
- {
- case ENOENT: // ignore this error - file removed during scan ?
- return EINA_TRUE;
- default:
- _error_handle(src, NULL, errno);
- return EINA_FALSE;
- }
- }
- if (S_ISDIR(st.st_mode))
- { // it's a dir - scan this recursively
- it = eina_file_ls(src);
- if (it)
- {
- EINA_ITERATOR_FOREACH(it, s)
- {
- if (res)
- {
- if (!fs_scan(s)) res = EINA_FALSE;
- }
- eina_stringshare_del(s);
- }
- eina_iterator_free(it);
- }
- }
- else
- {
- // the file itself count as 1 progress item - useful if it's a symlink
- // or a char or block device etc.
- status_count(1, ecore_file_file_get(src));
- // in addition each byte in the file count as a progress item too
- if (st.st_size > 0)
- status_count(st.st_size, ecore_file_file_get(src));
- }
- return res;
-}
-
-static Eina_Bool
-fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
-{ // cp_rm /path/to/src/filename /path/to/dst/filename
- // XXX: ecore_file_mv() ? <- look at it
- // XXX: utime()/utimes() -> utimensat()
- //
- // if src is dir
- // fs_mkdir(dst)
- // for all files in src
- // fs_cp_rm(src/file, dst/file, report_err)
- // fs_utimes(src, dst)
- // fs_chmod(src, dst)
- // fs_chown(src, dst)
- // fs_utimes(src, dst)
- // fs_chmod(src, dst)
- // fs_chown(src, dst)
- // fs_rmdir(src)
- // else
- // if (src is file)
- // fs_cp(src, dst, report_err)
- // fs_cp_xattr(src, dst)
- // else if (src is symlink)
- // fs_ln(src, dst)
- // else if (src is fifo)
- // fs_mkfifo(dst)
- // else if (src is socket)
- // fs_touch(dst)
- // else if (src is chrdev)
- // fs_chrdevdup(src, dst)
- // else if (src is blkdev)
- // fs_blkdevdup(src, dst)
- // fs_utimes(src, dst)
- // fs_chmod(src, dst)
- // fs_chown(src, dst)
- // fs_rm(src)
- // fs_cp(src_meta, dst_meta)
- // fs_utimes(src_meta, dst_meta)
- // fs_chmod(src_meta, dst_meta)
- // fs_chown(src_meta, dst_meta)
- // fs_rm(src_meta)
- Eina_Bool res = EINA_TRUE;
- Eina_Iterator *it;
- const char *s;
- struct stat st;
- mode_t old_umask;
- struct timeval times[2];
-
- if (strlen(src) < 1) return EINA_FALSE;
-
- // first count how much work needs doing
- if (!fs_scan(src)) return EINA_FALSE;
-
- fprintf(stderr, "cp_rm [%s] -> [%s]\n", src, dst);
- fflush(stderr);
- if (lstat(src, &st) != 0)
- {
- switch (errno)
- {
- case ENOENT: // ignore this error - file removed during scan ?
- status_pos(1, "Move - File vanished");
- break;
- default:
- _error_handle(src, dst, errno);
- return EINA_FALSE;
- }
- }
- old_umask = umask(0);
- if (S_ISDIR(st.st_mode))
- { // it's a dir - scan this recursively
- if (mkdir(dst, st.st_mode) != 0)
- {
- switch (errno)
- {
- case EEXIST: // ignore - mv would mv over this anyway
- break;
- default: // WAT
- _error_handle(NULL, dst, errno);
- res = EINA_FALSE;
- goto err;
- }
- }
- it = eina_file_ls(src);
- if (it)
- {
- EINA_ITERATOR_FOREACH(it, s)
- {
- Eina_Strbuf *buf = eina_strbuf_new();
- const char *fs = ecore_file_file_get(s);
-
- if (buf)
- {
- if ((res) && (fs))
- {
- eina_strbuf_append(buf, dst);
- eina_strbuf_append(buf, "/");
- eina_strbuf_append(buf, fs);
- if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err))
- res = EINA_FALSE;
- }
- eina_strbuf_free(buf);
- }
- eina_stringshare_del(s);
- }
- eina_iterator_free(it);
- }
- if (res) rmdir(src);
- }
- else if (S_ISLNK(st.st_mode))
- {
- char link[PATH_MAX];
- ssize_t lnsz;
-
- lnsz = readlink(src, link, sizeof(link));
- if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
- {
- if (symlink(link, dst) < 0)
- { // XXX: soft error? e.g. mv on FAT fs?
- status_pos(1, "Move - Error creating symlink");
- }
- }
- else if (lnsz < 0)
- { // XXX: handle read link err
- switch (errno)
- {
- case ENOENT: // ignore this error - file removed during scan ?
- status_pos(1, "Move - File vanished");
- break;
- default:
- _error_handle(src, dst, errno);
- return EINA_FALSE;
- }
- }
- else // 0 sized symlink ... WAT?
- {
- }
- }
- else if (S_ISFIFO(st.st_mode))
- {
- if (mkfifo(dst, st.st_mode) < 0)
- { // XXX: soft error? ignore?
- }
- }
- else if (S_ISSOCK(st.st_mode))
- {
- // we can't just make sockets - so ignore but have this here to document
- }
- else if ((S_ISCHR(st.st_mode)) || (S_ISBLK(st.st_mode)))
- {
- if (mknod(dst, st.st_mode, st.st_dev) < 0)
- { // XXX: soft error? ignore?
- }
- }
- else
- {
- int fd_in, fd_ou;
- void *old_copy_buf = NULL;
-
- fd_in = open(src, O_RDONLY);
- fd_ou = open(dst, O_WRONLY | O_CREAT, st.st_mode);
- if ((fd_in >= 0) && (fd_ou >= 0))
- {
- ssize_t size = 1 * 1024 * 1024; // 1mb default
- ssize_t ret, ret2;
- off_t off_in = 0, off_ou = 0;
- Eina_Bool old_copy = EINA_FALSE;
-
- for (;;)
- {
- if (old_copy)
- {
- if (!old_copy_buf)
- {
- size = 256 * 1024; // drop to 256k buffer
- old_copy_buf = malloc(size);
- if (!old_copy_buf)
- {
- res = EINA_FALSE;
- goto err_copy;
- }
- }
-again_read:
- ret = read(fd_in, old_copy_buf, size);
- if (ret < 0)
- {
- switch (errno)
- {
- case EAGAIN:
- case EINTR:
- goto again_read;
- default:
- _error_handle(src, NULL, errno);
- res = EINA_FALSE;
- goto err_copy;
- }
- }
- else
- {
- off_in += ret;
-again_write:
- ret2 = write(fd_ou, old_copy_buf, ret);
- if (ret2 < 0)
- {
- switch (errno)
- {
- case EAGAIN:
- case EINTR:
- goto again_write;
- default:
- _error_handle(NULL, dst, errno);
- res = EINA_FALSE;
- goto err_copy;
- }
- }
- else if (ret2 == ret)
- {
- off_ou += ret;
- if (ret < size) break; // end of file
- }
- }
- }
- else
- {
- ret = copy_file_range(fd_in, &off_in, fd_ou, &off_ou, size, 0);
- if (ret < 0)
- {
- switch (errno)
- {
- case EOPNOTSUPP:
- case EXDEV:
- old_copy = EINA_TRUE;
- break;
- case EBADF:
- default: // WAT
- _error_handle(src, dst, errno);
- res = EINA_FALSE;
- goto err_copy;
- }
- }
- else if (ret < size) break; // end of file
- }
- }
- }
-err_copy:
- if (old_copy_buf) free(old_copy_buf);
- if (fd_in >= 0) close(fd_in);
- if (fd_ou >= 0) close(fd_ou);
- if (res) unlink(src);
- }
- chown(dst, st.st_uid, st.st_gid);
-#ifdef STAT_NSEC
-#ifdef st_mtime
-#define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atim.tv_nsec)
-#define STAT_NSEC_MTIME(st) (unsigned long long)((st)->st_mtim.tv_nsec)
-#define STAT_NSEC_CTIME(st) (unsigned long long)((st)->st_ctim.tv_nsec)
-#else
-#define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atimensec)
-#define STAT_NSEC_MTIME(st) (unsigned long long)((st)->st_mtimensec)
-#define STAT_NSEC_CTIME(st) (unsigned long long)((st)->st_ctimensec)
-#endif
-#else
-#define STAT_NSEC_ATIME(st) (unsigned long long)(0)
-#define STAT_NSEC_MTIME(st) (unsigned long long)(0)
-#define STAT_NSEC_CTIME(st) (unsigned long long)(0)
-#endif
- times[0].tv_sec = st.st_atime;
- times[0].tv_usec = STAT_NSEC_ATIME(st) * 1000;
- times[1].tv_sec = st.st_mtime;
- times[1].tv_usec = STAT_NSEC_MTIME(st) * 1000;
- utimes(dst, times);
-err:
- umask(old_umask);
- if (!res)
- {
- fprintf(stderr, "MV: ERROR!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- fflush(stderr);
- }
- return res;
-}
-
-static Eina_Bool
-fs_mv(const char *src, const char *dst, Eina_Bool report_err)
-{ // mv /path/to/src/filename /path/to/dst/filename
- Eina_Bool res = EINA_TRUE;
- int ret;
-
- status_op("mv");
- status_count(1, src);
- ret = rename(src, dst);
- if (ret == 0) return res;
- else
- {
- switch (errno)
- {
- case EXDEV: // revert to cp + rm
- return fs_cp_rm(src, dst, report_err);
- break;
- default:
- if (report_err) _error_handle(src, dst, errno);
- res = EINA_FALSE;
- break;
- }
- }
- status_pos(1, src);
- return res;
-}
-
int
main(int argc, char **argv)
{ // mv [src] [dst]
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.