misc_file.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * misc.c -- handles:
  3. * copyfile() movefile()
  4. *
  5. */
  6. #include "main.h"
  7. #include <sys/stat.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include "stat.h"
  11. /* Copy a file from one place to another (possibly erasing old copy).
  12. *
  13. * returns: 0 if OK
  14. * 1 if can't open original file
  15. * 2 if can't open new file
  16. * 3 if original file isn't normal
  17. * 4 if ran out of disk space
  18. */
  19. int copyfile(char *oldpath, char *newpath)
  20. {
  21. int fi, fo, x;
  22. char buf[512];
  23. struct stat st;
  24. #ifndef CYGWIN_HACKS
  25. fi = open(oldpath, O_RDONLY, 0);
  26. #else
  27. fi = open(oldpath, O_RDONLY | O_BINARY, 0);
  28. #endif
  29. if (fi < 0)
  30. return 1;
  31. fstat(fi, &st);
  32. if (!(st.st_mode & S_IFREG))
  33. return 3;
  34. fo = creat(newpath, (int) (st.st_mode & 0600));
  35. if (fo < 0) {
  36. close(fi);
  37. return 2;
  38. }
  39. for (x = 1; x > 0;) {
  40. x = read(fi, buf, 512);
  41. if (x > 0) {
  42. if (write(fo, buf, x) < x) { /* Couldn't write */
  43. close(fo);
  44. close(fi);
  45. unlink(newpath);
  46. return 4;
  47. }
  48. }
  49. }
  50. #ifdef HAVE_FSYNC
  51. fsync(fo);
  52. #endif /* HAVE_FSYNC */
  53. close(fo);
  54. close(fi);
  55. return 0;
  56. }
  57. int movefile(char *oldpath, char *newpath)
  58. {
  59. int ret;
  60. #ifdef HAVE_RENAME
  61. /* Try to use rename first */
  62. if (!rename(oldpath, newpath))
  63. return 0;
  64. #endif /* HAVE_RENAME */
  65. /* If that fails, fall back to just copying and then
  66. * deleting the file.
  67. */
  68. ret = copyfile(oldpath, newpath);
  69. if (!ret)
  70. unlink(oldpath);
  71. return ret;
  72. }