THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
1.3KB

  1. #include "cache.h"
  2. int copy_fd(int ifd, int ofd)
  3. {
  4. while (1) {
  5. char buffer[8192];
  6. ssize_t len = xread(ifd, buffer, sizeof(buffer));
  7. if (!len)
  8. break;
  9. if (len < 0)
  10. return COPY_READ_ERROR;
  11. if (write_in_full(ofd, buffer, len) < 0)
  12. return COPY_WRITE_ERROR;
  13. }
  14. return 0;
  15. }
  16. static int copy_times(const char *dst, const char *src)
  17. {
  18. struct stat st;
  19. struct utimbuf times;
  20. if (stat(src, &st) < 0)
  21. return -1;
  22. times.actime = st.st_atime;
  23. times.modtime = st.st_mtime;
  24. if (utime(dst, &times) < 0)
  25. return -1;
  26. return 0;
  27. }
  28. int copy_file(const char *dst, const char *src, int mode)
  29. {
  30. int fdi, fdo, status;
  31. mode = (mode & 0111) ? 0777 : 0666;
  32. if ((fdi = open(src, O_RDONLY)) < 0)
  33. return fdi;
  34. if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) {
  35. close(fdi);
  36. return fdo;
  37. }
  38. status = copy_fd(fdi, fdo);
  39. switch (status) {
  40. case COPY_READ_ERROR:
  41. error_errno("copy-fd: read returned");
  42. break;
  43. case COPY_WRITE_ERROR:
  44. error_errno("copy-fd: write returned");
  45. break;
  46. }
  47. close(fdi);
  48. if (close(fdo) != 0)
  49. return error_errno("%s: close error", dst);
  50. if (!status && adjust_shared_perm(dst))
  51. return -1;
  52. return status;
  53. }
  54. int copy_file_with_time(const char *dst, const char *src, int mode)
  55. {
  56. int status = copy_file(dst, src, mode);
  57. if (!status)
  58. return copy_times(dst, src);
  59. return status;
  60. }