Util.vala 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. using Invercargill;
  2. namespace Binman {
  3. public static void posix_to_error(int result) throws Error {
  4. if(result == 0) {
  5. return;
  6. }
  7. throw new Error(GLib.Quark.from_string("posix"), errno, Posix.strerror(errno));
  8. }
  9. public static void reflink_copy(string src, string dest) throws Error {
  10. int pid = Posix.fork();
  11. if (pid == 0) {
  12. posix_to_error(Posix.execv("/bin/cp", new string[] {"--reflink=always", src, dest}));
  13. Posix.exit(Posix.ENOENT);
  14. }
  15. int status;
  16. Posix.waitpid(pid, out status, 0);
  17. posix_to_error(status);
  18. }
  19. public static BinaryData calculate_file_checksum(string path, FileProgressCallback? progress_callback = null) throws Error {
  20. var stream = File.new_for_path(path).read();
  21. var checksum = new Checksum(ChecksumType.SHA512);
  22. const int increment = 1024 * 1024 * 128;
  23. uint64 read = 0;
  24. var file_size = stream.query_info("*").get_size();
  25. var to_read = file_size;
  26. while(read < to_read) {
  27. var data = new uint8[uint64.min(increment, to_read - read)];
  28. data.length = (int)stream.read(data);
  29. checksum.update(data, data.length);
  30. read += data.length;
  31. if(progress_callback != null) {
  32. progress_callback((int64)read, file_size);
  33. }
  34. }
  35. var checksum_bytes = new uint8[ChecksumType.SHA512.get_length()];
  36. size_t size = checksum_bytes.length;
  37. checksum.get_digest(checksum_bytes, ref size);
  38. return new Invercargill.BinaryData.from_byte_array(checksum_bytes);
  39. }
  40. }