run-locking.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* Include the C files directly. */
  2. #include <ccan/failtest/failtest.c>
  3. #include <stdlib.h>
  4. #include <setjmp.h>
  5. #include <stdio.h>
  6. #include <stdarg.h>
  7. #include <assert.h>
  8. #include <ccan/tap/tap.h>
  9. #define SIZE 8
  10. /* We don't want to fork and fail; we're just testing lock recording. */
  11. static enum failtest_result dont_fail(struct tlist_calls *history)
  12. {
  13. return FAIL_DONT_FAIL;
  14. }
  15. static bool place_lock(int fd, char lockarr[], unsigned pos, unsigned size,
  16. int type)
  17. {
  18. struct flock fl;
  19. /* Update record keeping. */
  20. if (type == F_RDLCK)
  21. memset(lockarr+pos, 1, size);
  22. else if (type == F_WRLCK)
  23. memset(lockarr+pos, 2, size);
  24. else
  25. memset(lockarr+pos, 0, size);
  26. fl.l_whence = SEEK_SET;
  27. fl.l_type = type;
  28. fl.l_start = pos;
  29. fl.l_len = size;
  30. return failtest_fcntl(fd, "run-locking.c", 1, F_SETLK, &fl) == 0;
  31. }
  32. static char lock_lookup(int fd, unsigned pos)
  33. {
  34. char ret = 0;
  35. unsigned int i;
  36. struct lock_info *l;
  37. for (i = 0; i < lock_num; i++) {
  38. l = &locks[i];
  39. if (l->fd != fd)
  40. continue;
  41. if (pos >= l->start && pos <= l->end) {
  42. if (ret)
  43. ret = 3;
  44. else if (l->type == F_RDLCK)
  45. ret = 1;
  46. else
  47. ret = 2;
  48. }
  49. }
  50. return ret;
  51. }
  52. static bool test(int fd,
  53. unsigned p1, unsigned s1,
  54. unsigned p2, unsigned s2,
  55. unsigned p3, unsigned s3)
  56. {
  57. unsigned int i;
  58. char lockarr[SIZE];
  59. memset(lockarr, 0, sizeof(lockarr));
  60. if (!place_lock(fd, lockarr, p1, s1, F_WRLCK))
  61. return false;
  62. if (!place_lock(fd, lockarr, p2, s2, F_RDLCK))
  63. return false;
  64. if (!place_lock(fd, lockarr, p3, s3, F_UNLCK))
  65. return false;
  66. for (i = 0; i < SIZE; i++) {
  67. if (lock_lookup(fd, i) != lockarr[i])
  68. return false;
  69. }
  70. /* Reset lock info. */
  71. lock_num = 0;
  72. return true;
  73. }
  74. int main(void)
  75. {
  76. int fd;
  77. long flags;
  78. unsigned int isize;
  79. plan_tests(5835);
  80. failtest_init(0, NULL);
  81. failtest_hook = dont_fail;
  82. fd = open("run-locking-scratch", O_RDWR|O_CREAT, 0600);
  83. /* GETFL and SETFL wrappers should pass through. */
  84. flags = fcntl(fd, F_GETFL);
  85. ok1(failtest_fcntl(fd, "run-locking.c", 1, F_GETFL) == flags);
  86. flags |= O_NONBLOCK;
  87. ok1(failtest_fcntl(fd, "run-locking.c", 1, F_SETFL, flags) == 0);
  88. ok1(failtest_fcntl(fd, "run-locking.c", 1, F_GETFL) == flags);
  89. for (isize = 1; isize < 4; isize++) {
  90. unsigned int ipos;
  91. for (ipos = 0; ipos + isize < SIZE; ipos++) {
  92. unsigned int jsize;
  93. for (jsize = 1; jsize < 4; jsize++) {
  94. unsigned int jpos;
  95. for (jpos = 0; jpos + jsize < SIZE; jpos++) {
  96. unsigned int ksize;
  97. for (ksize = 1; ksize < 4; ksize++) {
  98. unsigned int kpos;
  99. for (kpos = 0;
  100. kpos + ksize < SIZE;
  101. kpos++) {
  102. ok1(test(fd,
  103. ipos, isize,
  104. jpos, jsize,
  105. kpos, ksize));
  106. }
  107. }
  108. }
  109. }
  110. }
  111. }
  112. return exit_status();
  113. }