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 3519ab0f91340d741a033a9c51a86e5138e84d17
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Tue Apr 30 17:07:37 2024 +0100

    cleaner code - move file cp to own func etc.
---
 src/backends/default/fs.c | 292 ++++++++++++++++++++++++----------------------
 1 file changed, 153 insertions(+), 139 deletions(-)

diff --git a/src/backends/default/fs.c b/src/backends/default/fs.c
index 403704c..06f6216 100644
--- a/src/backends/default/fs.c
+++ b/src/backends/default/fs.c
@@ -15,22 +15,30 @@
 #include "status.h"
 #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
-// this tio handle the reast in a generic way.
-static void
-_error_handle(const char *src, const char *dst, const char *op, int errno_in)
+static Eina_Strbuf *
+error_strbuf_new(const char *op)
 {
   Eina_Strbuf *buf = eina_strbuf_new();
 
   if (!buf) abort();
   eina_strbuf_append(buf, op);
   eina_strbuf_append(buf, ": ");
-#define HNDL(_err, _str)                                 \
-  _err:                                                  \
-    eina_strbuf_append(buf, _str);                       \
-    status_error(src, dst, eina_strbuf_string_get(buf)); \
-    break
+  return buf;
+}
+
+// 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, const char *op, int errno_in)
+{
+  Eina_Strbuf *buf = error_strbuf_new(op);
+
+#define HNDL(_err, _str)                               \
+_err:                                                  \
+  eina_strbuf_append(buf, _str);                       \
+  status_error(src, dst, eina_strbuf_string_get(buf)); \
+  break
   switch (errno_in)
     {
       HNDL(case EACCES, "Access denied");
@@ -61,6 +69,120 @@ _error_handle(const char *src, const char *dst, const char *op, int errno_in)
   eina_strbuf_free(buf);
 }
 
+static void
+error_ok_pos(const char *src, const char *op, const char *str)
+{
+  Eina_Strbuf *buf = error_strbuf_new(op);
+
+  eina_strbuf_append(buf, str);
+  status_pos(1, eina_strbuf_string_get(buf));
+  eina_strbuf_free(buf);
+}
+
+static Eina_Bool
+fs_cp_file(const char *src, const char *dst, const char *op, struct stat src_st)
+{
+  // copy a normal file from src to dst - use optimized copy range if possible
+  // and fall abck to read + write into userspace buffer otherwise. use the
+  // struct stat mode passed in for created file. return true if fully
+  // successful or false otherwise
+  int   fd_in, fd_ou;
+  void *old_copy_buf = NULL;
+  Eina_Bool res = EINA_TRUE;
+
+  fd_in = open(src, O_RDONLY);
+  fd_ou = open(dst, O_WRONLY | O_CREAT, src_st.st_mode);
+  if ((fd_in >= 0) && (fd_ou >= 0))
+    {
+      ssize_t   size = 1 * 1024 * 1024; // 1mb default for copy range
+      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 for r+w
+                  old_copy_buf = malloc(size);
+                  if (!old_copy_buf)
+                    {
+                      res = EINA_FALSE;
+                      goto err;
+                    }
+                }
+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, op, errno);
+                      res = EINA_FALSE;
+                      goto err;
+                    }
+                }
+              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, op, errno);
+                          res = EINA_FALSE;
+                          goto err;
+                        }
+                    }
+                  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:
+                      // fall back to old read+write copy into userspace buf
+                      old_copy = EINA_TRUE;
+                      break;
+                    default:
+                      _error_handle(src, dst, op, errno);
+                      res = EINA_FALSE;
+                      goto err;
+                    }
+                }
+              else if (ret < size) break; // end of file
+            }
+        }
+    }
+  else res = EINA_FALSE;
+err:
+  if (old_copy_buf) free(old_copy_buf);
+  if (fd_in >= 0) close(fd_in);
+  if (fd_ou >= 0) close(fd_ou);
+  return res;
+}
+
 // 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
@@ -94,10 +216,7 @@ fs_scan(const char *src)
         {
           EINA_ITERATOR_FOREACH(it, s)
           {
-            if (res)
-              {
-                if (!fs_scan(s)) res = EINA_FALSE;
-              }
+            if ((res) && (!fs_scan(s))) res = EINA_FALSE;
             eina_stringshare_del(s);
           }
           eina_iterator_free(it);
@@ -125,9 +244,8 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
   mode_t         old_umask;
   struct timeval times[2];
   const char    *op = "";
-  Eina_Strbuf   *sbuf = NULL;
 
-  if (strlen(src) < 1) return EINA_FALSE;
+  if ((!src) || (!dst) || (strlen(src) < 1)) return EINA_FALSE;
 
   // first count how much work needs doing
   if (!fs_scan(src)) return EINA_FALSE;
@@ -142,11 +260,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
       switch (errno)
         {
         case ENOENT: // ignore this error - file removed during scan ?
-          eina_strbuf_reset(sbuf);
-          eina_strbuf_append(sbuf, op);
-          eina_strbuf_append(sbuf, ": ");
-          eina_strbuf_append(sbuf, "File vanished");
-          status_pos(1, eina_strbuf_string_get(sbuf));
+          error_ok_pos(src, op, "File vanished");
           goto err;
         default:
           _error_handle(src, dst, op, errno);
@@ -154,7 +268,6 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
           goto err;
         }
     }
-  sbuf = eina_strbuf_new();
   if (S_ISDIR(st.st_mode))
     { // it's a dir - scan this recursively
       if (cp)
@@ -165,7 +278,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
                 {
                 case EEXIST: // ignore - mv would mv over this anyway
                   break;
-                default: // WAT
+                default:
                   _error_handle(NULL, dst, op, errno);
                   res = EINA_FALSE;
                   goto err;
@@ -175,15 +288,18 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
       it = eina_file_ls(src);
       if (it)
         {
+          Eina_Strbuf *buf = eina_strbuf_new();
+
+          if (!buf) abort();
           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_reset(buf);
                     eina_strbuf_append(buf, dst);
                     eina_strbuf_append(buf, "/");
                     eina_strbuf_append(buf, fs);
@@ -191,11 +307,11 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
                                   report_err, cp, rm))
                       res = EINA_FALSE;
                   }
-                eina_strbuf_free(buf);
               }
             eina_stringshare_del(s);
           }
           eina_iterator_free(it);
+          eina_strbuf_free(buf);
         }
     }
   else if (S_ISLNK(st.st_mode))
@@ -210,11 +326,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
             {
               if (symlink(link, dst) < 0)
                 { // soft error? e.g. mv on FAT fs? report but move on
-                  eina_strbuf_reset(sbuf);
-                  eina_strbuf_append(sbuf, op);
-                  eina_strbuf_append(sbuf, ": ");
-                  eina_strbuf_append(sbuf, "Error creating symlink");
-                  status_pos(1, eina_strbuf_string_get(sbuf));
+                  error_ok_pos(dst, op, "Error creating symlink");
                 }
             }
           else if (lnsz < 0)
@@ -222,24 +334,16 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
               switch (errno)
                 {
                 case ENOENT: // ignore this error - file removed during scan ?
-                  eina_strbuf_reset(sbuf);
-                  eina_strbuf_append(sbuf, op);
-                  eina_strbuf_append(sbuf, ": ");
-                  eina_strbuf_append(sbuf, "File vanished");
-                  status_pos(1, eina_strbuf_string_get(sbuf));
+                  error_ok_pos(src, op, "File vanished");
                   break;
                 default:
                   _error_handle(src, dst, op, errno);
                   return EINA_FALSE;
                 }
             }
-          else // 0 sized symlink ... WAT?
-            {
-              eina_strbuf_reset(sbuf);
-              eina_strbuf_append(sbuf, op);
-              eina_strbuf_append(sbuf, ": ");
-              eina_strbuf_append(sbuf, "Zero sized symlink");
-              status_error(src, NULL, eina_strbuf_string_get(sbuf));
+          else
+            { // 0 sized symlink ... WAT?
+              error_ok_pos(src, op, "Zero sized symlink");
             }
         }
     }
@@ -255,8 +359,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
   else if (S_ISSOCK(st.st_mode))
     {
       if (cp)
-        {
-          // we can't just make sockets - so ignore but document here
+        { // we can't just make sockets - so ignore but document here
         }
     }
   else if ((S_ISCHR(st.st_mode)) || (S_ISBLK(st.st_mode)))
@@ -272,99 +375,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
     {
       if (cp)
         {
-          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, op, 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, op, 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, op, 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);
+          res = fs_cp_file(src, dst, op, st);
         }
     }
   if ((rm) && (res))
@@ -380,9 +391,12 @@ err_copy:
                 default:
                   _error_handle(src, NULL, op, errno);
                   res = EINA_FALSE;
-                  goto err;
+                  goto err_unlink;
                 }
             }
+        }
+      else
+        {
           if (unlink(src) != 0)
             {
               switch (errno)
@@ -399,6 +413,7 @@ err_copy:
     }
 err_unlink:
   chown(dst, st.st_uid, st.st_gid); // ignore err
+// duplicate mtime+atime from src down to msic/nsec if possible
 #ifdef STAT_NSEC
 #ifdef st_mtime
 #define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atim.tv_nsec)
@@ -421,7 +436,6 @@ err_unlink:
   utimes(dst, times); // ingore err
 err:
   umask(old_umask);
-  if (sbuf) eina_strbuf_free(sbuf);
   return res;
 }
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to