api-83-openhook.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "config.h"
  2. #include "../ntdb.h"
  3. #include "../private.h"
  4. #include "tap-interface.h"
  5. #include "external-agent.h"
  6. #include "logging.h"
  7. #include "helpapi-external-agent.h"
  8. #define KEY_STR "key"
  9. static enum NTDB_ERROR clear_if_first(int fd, void *arg)
  10. {
  11. /* We hold a lock offset 4 always, so we can tell if anyone is holding it.
  12. * (This is compatible with tdb's TDB_CLEAR_IF_FIRST flag). */
  13. struct flock fl;
  14. if (arg != clear_if_first)
  15. return NTDB_ERR_CORRUPT;
  16. fl.l_type = F_WRLCK;
  17. fl.l_whence = SEEK_SET;
  18. fl.l_start = 4;
  19. fl.l_len = 1;
  20. if (fcntl(fd, F_SETLK, &fl) == 0) {
  21. /* We must be first ones to open it! */
  22. diag("truncating file!");
  23. if (ftruncate(fd, 0) != 0) {
  24. return NTDB_ERR_IO;
  25. }
  26. }
  27. fl.l_type = F_RDLCK;
  28. if (fcntl(fd, F_SETLKW, &fl) != 0) {
  29. return NTDB_ERR_IO;
  30. }
  31. return NTDB_SUCCESS;
  32. }
  33. int main(int argc, char *argv[])
  34. {
  35. unsigned int i;
  36. struct ntdb_context *ntdb, *ntdb2;
  37. struct agent *agent;
  38. union ntdb_attribute cif;
  39. NTDB_DATA key = ntdb_mkdata(KEY_STR, strlen(KEY_STR));
  40. int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
  41. NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
  42. cif.openhook.base.attr = NTDB_ATTRIBUTE_OPENHOOK;
  43. cif.openhook.base.next = &tap_log_attr;
  44. cif.openhook.fn = clear_if_first;
  45. cif.openhook.data = clear_if_first;
  46. agent = prepare_external_agent();
  47. plan_tests(sizeof(flags) / sizeof(flags[0]) * 16);
  48. for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
  49. /* Create it */
  50. ntdb = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC,
  51. O_RDWR|O_CREAT|O_TRUNC, 0600, NULL);
  52. ok1(ntdb);
  53. ok1(ntdb_store(ntdb, key, key, NTDB_REPLACE) == 0);
  54. ntdb_close(ntdb);
  55. /* Now, open with CIF, should clear it. */
  56. ntdb = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC,
  57. O_RDWR, 0, &cif);
  58. ok1(ntdb);
  59. ok1(!ntdb_exists(ntdb, key));
  60. ok1(ntdb_store(ntdb, key, key, NTDB_REPLACE) == 0);
  61. /* Agent should not clear it, since it's still open. */
  62. ok1(external_agent_operation(agent, OPEN_WITH_HOOK,
  63. "run-83-openhook.ntdb") == SUCCESS);
  64. ok1(external_agent_operation(agent, FETCH, KEY_STR "=" KEY_STR)
  65. == SUCCESS);
  66. ok1(external_agent_operation(agent, CLOSE, "") == SUCCESS);
  67. /* Still exists for us too. */
  68. ok1(ntdb_exists(ntdb, key));
  69. /* Nested open should not erase db. */
  70. ntdb2 = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC,
  71. O_RDWR, 0, &cif);
  72. ok1(ntdb_exists(ntdb2, key));
  73. ok1(ntdb_exists(ntdb, key));
  74. ntdb_close(ntdb2);
  75. ok1(ntdb_exists(ntdb, key));
  76. /* Close it, now agent should clear it. */
  77. ntdb_close(ntdb);
  78. ok1(external_agent_operation(agent, OPEN_WITH_HOOK,
  79. "run-83-openhook.ntdb") == SUCCESS);
  80. ok1(external_agent_operation(agent, FETCH, KEY_STR "=" KEY_STR)
  81. == FAILED);
  82. ok1(external_agent_operation(agent, CLOSE, "") == SUCCESS);
  83. ok1(tap_log_messages == 0);
  84. }
  85. free_external_agent(agent);
  86. return exit_status();
  87. }