flock.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "fspr_arch_file_io.h"
  17. #if APR_HAVE_FCNTL_H
  18. #include <fcntl.h>
  19. #endif
  20. #ifdef HAVE_SYS_FILE_H
  21. #include <sys/file.h>
  22. #endif
  23. APR_DECLARE(fspr_status_t) fspr_file_lock(fspr_file_t *thefile, int type)
  24. {
  25. int rc;
  26. #if defined(HAVE_FCNTL_H)
  27. {
  28. struct flock l = { 0 };
  29. int fc;
  30. l.l_whence = SEEK_SET; /* lock from current point */
  31. l.l_start = 0; /* begin lock at this offset */
  32. l.l_len = 0; /* lock to end of file */
  33. if ((type & APR_FLOCK_TYPEMASK) == APR_FLOCK_SHARED)
  34. l.l_type = F_RDLCK;
  35. else
  36. l.l_type = F_WRLCK;
  37. fc = (type & APR_FLOCK_NONBLOCK) ? F_SETLK : F_SETLKW;
  38. /* keep trying if fcntl() gets interrupted (by a signal) */
  39. while ((rc = fcntl(thefile->filedes, fc, &l)) < 0 && errno == EINTR)
  40. continue;
  41. if (rc == -1) {
  42. /* on some Unix boxes (e.g., Tru64), we get EACCES instead
  43. * of EAGAIN; we don't want APR_STATUS_IS_EAGAIN() matching EACCES
  44. * since that breaks other things, so fix up the retcode here
  45. */
  46. if (errno == EACCES) {
  47. return EAGAIN;
  48. }
  49. return errno;
  50. }
  51. }
  52. #elif defined(HAVE_SYS_FILE_H)
  53. {
  54. int ltype;
  55. if ((type & APR_FLOCK_TYPEMASK) == APR_FLOCK_SHARED)
  56. ltype = LOCK_SH;
  57. else
  58. ltype = LOCK_EX;
  59. if ((type & APR_FLOCK_NONBLOCK) != 0)
  60. ltype |= LOCK_NB;
  61. /* keep trying if flock() gets interrupted (by a signal) */
  62. while ((rc = flock(thefile->filedes, ltype)) < 0 && errno == EINTR)
  63. continue;
  64. if (rc == -1)
  65. return errno;
  66. }
  67. #else
  68. #error No file locking mechanism is available.
  69. #endif
  70. return APR_SUCCESS;
  71. }
  72. APR_DECLARE(fspr_status_t) fspr_file_unlock(fspr_file_t *thefile)
  73. {
  74. int rc;
  75. #if defined(HAVE_FCNTL_H)
  76. {
  77. struct flock l = { 0 };
  78. l.l_whence = SEEK_SET; /* lock from current point */
  79. l.l_start = 0; /* begin lock at this offset */
  80. l.l_len = 0; /* lock to end of file */
  81. l.l_type = F_UNLCK;
  82. /* keep trying if fcntl() gets interrupted (by a signal) */
  83. while ((rc = fcntl(thefile->filedes, F_SETLKW, &l)) < 0
  84. && errno == EINTR)
  85. continue;
  86. if (rc == -1)
  87. return errno;
  88. }
  89. #elif defined(HAVE_SYS_FILE_H)
  90. {
  91. /* keep trying if flock() gets interrupted (by a signal) */
  92. while ((rc = flock(thefile->filedes, LOCK_UN)) < 0 && errno == EINTR)
  93. continue;
  94. if (rc == -1)
  95. return errno;
  96. }
  97. #else
  98. #error No file locking mechanism is available.
  99. #endif
  100. return APR_SUCCESS;
  101. }