diff options
Diffstat (limited to 'src/LibraryFiles.vala')
| -rw-r--r-- | src/LibraryFiles.vala | 66 | 
1 files changed, 65 insertions, 1 deletions
| diff --git a/src/LibraryFiles.vala b/src/LibraryFiles.vala index a49b77b..bbacb6c 100644 --- a/src/LibraryFiles.vala +++ b/src/LibraryFiles.vala @@ -6,6 +6,22 @@  namespace LibraryFiles { +static bool use_fallback_copy_func = false; + +public void select_copy_function() { +    var import_dir = AppDirs.get_import_dir(); + +    try { +        var info = import_dir.query_filesystem_info("filesystem::type", null); +        use_fallback_copy_func = info.get_attribute_as_string("filesystem::type") == "nfs"; +    } catch (Error error) { +        critical ("Failed to query fs type: %s", error.message); +        use_fallback_copy_func = true; +    } + +    info ("Using fallback copy: %s", use_fallback_copy_func.to_string()); +} +  // This method uses global::generate_unique_file_at in order to "claim" a file in the filesystem.  // Thus, when the method returns success a file may exist already, and should be overwritten.  // @@ -89,7 +105,11 @@ private File duplicate(File src, FileProgressCallback? progress_callback, bool b          LibraryMonitor.blacklist_file(dest, "LibraryFiles.duplicate");      try { -        src.copy(dest, FileCopyFlags.ALL_METADATA | FileCopyFlags.OVERWRITE, null, progress_callback); +        if (use_fallback_copy_func) { +            fallback_copy(src, dest, progress_callback); +        } else { +            src.copy(dest, FileCopyFlags.ALL_METADATA | FileCopyFlags.OVERWRITE, null, progress_callback); +        }          if (blacklist)              LibraryMonitor.unblacklist_file(dest);      } catch (Error err) { @@ -111,4 +131,48 @@ private File duplicate(File src, FileProgressCallback? progress_callback, bool b      return dest;  } + +public void fallback_copy(File? src, File? dst, FileProgressCallback? callback) throws Error { +    if (src == null || dst == null) { +        return; +    } + +    var f = FileStream.open(src.get_path(), "rb"); +    if (f != null) { +        f.seek(0, FileSeek.END); +        var size = f.tell(); +        f.seek(0, FileSeek.SET); +        debug ("Copying %s to %s, size is %ld", src.get_path(), dst.get_path(), size); + +        var g = FileStream.open(dst.get_path(), "wb"); +        if (g != null) { +            uint8 buffer[4096]; +            size_t written = 0; + +            while (!f.eof()) { +                var len = f.read(buffer); +                if (len > 0) { +                    var out_len = g.write(buffer[0:len]); +                    if (out_len < 0) { +                        critical("Failed to write to file %s: %m", dst.get_path()); +                        throw new IOError.FAILED("Failed to write to %s", dst.get_path()); +                    } +                    written += len; + +                    if (callback != null) +                        callback (written, size); +                } else if (len < 0) { +                    critical("Failed to read from file %s: %m", src.get_path()); +                    throw new IOError.FAILED("Failed to read from %s", src.get_path()); +                } +            } +        } else { +            critical ("Failed to open %s: %m", dst.get_path()); +            throw new IOError.FAILED("Failed to open %s", dst.get_path()); +        } +    } else { +        critical ("Failed to open %s: %m", src.get_path()); +        throw new IOError.FAILED("Failed to open %s", src.get_path()); +    } +}  } | 
