file.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * file.c - file handling functions
  4. *
  5. * Copyright © 1994, 1995 Ian Jackson <ian@chiark.greenend.org.uk>
  6. * Copyright © 2008 Guillem Jover <guillem@debian.org>
  7. *
  8. * This is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <assert.h>
  26. #include <errno.h>
  27. #include <fcntl.h>
  28. #include <unistd.h>
  29. #include <dpkg/dpkg.h>
  30. #include <dpkg/i18n.h>
  31. #include <dpkg/file.h>
  32. /**
  33. * Copy file ownership and permissions from one file to another.
  34. *
  35. * @param src The source filename.
  36. * @param dst The destination filename.
  37. */
  38. void
  39. file_copy_perms(const char *src, const char *dst)
  40. {
  41. struct stat stab;
  42. if (stat(src, &stab) == -1) {
  43. if (errno == ENOENT)
  44. return;
  45. ohshite(_("unable to stat source file '%.250s'"), src);
  46. }
  47. if (chown(dst, stab.st_uid, stab.st_gid) == -1)
  48. ohshite(_("unable to change ownership of target file '%.250s'"),
  49. dst);
  50. if (chmod(dst, (stab.st_mode & 07777)) == -1)
  51. ohshite(_("unable to set mode of target file '%.250s'"), dst);
  52. }
  53. static void
  54. file_lock_setup(struct flock *fl, short type)
  55. {
  56. fl->l_type = type;
  57. fl->l_whence = SEEK_SET;
  58. fl->l_start = 0;
  59. fl->l_len = 0;
  60. fl->l_pid = 0;
  61. }
  62. /**
  63. * Unlock a previously locked file.
  64. */
  65. void
  66. file_unlock(int lockfd, const char *lock_desc)
  67. {
  68. struct flock fl;
  69. assert(lockfd >= 0);
  70. file_lock_setup(&fl, F_UNLCK);
  71. if (fcntl(lockfd, F_SETLK, &fl) == -1)
  72. ohshite(_("unable to unlock %s"), lock_desc);
  73. }
  74. static void
  75. file_unlock_cleanup(int argc, void **argv)
  76. {
  77. int lockfd = *(int *)argv[0];
  78. const char *lock_desc = argv[1];
  79. file_unlock(lockfd, lock_desc);
  80. }
  81. /**
  82. * Check if a file has a lock acquired.
  83. *
  84. * @param lockfd The file descriptor for the lock.
  85. * @param filename The file name associated to the file descriptor.
  86. */
  87. bool
  88. file_is_locked(int lockfd, const char *filename)
  89. {
  90. struct flock fl;
  91. file_lock_setup(&fl, F_WRLCK);
  92. if (fcntl(lockfd, F_GETLK, &fl) == -1)
  93. ohshit(_("unable to check file '%s' lock status"), filename);
  94. if (fl.l_type == F_WRLCK && fl.l_pid != getpid())
  95. return true;
  96. else
  97. return false;
  98. }
  99. /**
  100. * Lock a file.
  101. *
  102. * @param lockfd The pointer to the lock file descriptor. It must be allocated
  103. * statically as its addresses is passed to a cleanup handler.
  104. * @param flags The lock flags specifiying what type of locking to perform.
  105. * @param filename The name of the file to lock.
  106. * @param desc The description of the file to lock.
  107. */
  108. void
  109. file_lock(int *lockfd, enum file_lock_flags flags, const char *filename,
  110. const char *desc)
  111. {
  112. struct flock fl;
  113. int lock_cmd;
  114. setcloexec(*lockfd, filename);
  115. file_lock_setup(&fl, F_WRLCK);
  116. if (flags == FILE_LOCK_WAIT)
  117. lock_cmd = F_SETLKW;
  118. else
  119. lock_cmd = F_SETLK;
  120. if (fcntl(*lockfd, lock_cmd, &fl) == -1) {
  121. if (errno == EACCES || errno == EAGAIN)
  122. ohshit(_("%s is locked by another process"), desc);
  123. else
  124. ohshite(_("unable to lock %s"), desc);
  125. }
  126. push_cleanup(file_unlock_cleanup, ~0, NULL, 0, 2, lockfd, desc);
  127. }