Line data Source code
1 : #include "../common/tdb_private.h"
2 : #include "../common/io.c"
3 : #include "../common/tdb.c"
4 : #include "../common/lock.c"
5 : #include "../common/freelist.c"
6 : #include "../common/traverse.c"
7 : #include "../common/transaction.c"
8 : #include "../common/error.c"
9 : #include "../common/open.c"
10 : #include "../common/check.c"
11 : #include "../common/hash.c"
12 : #include "../common/mutex.c"
13 : #include "tap-interface.h"
14 : #include <stdlib.h>
15 : #include <sys/types.h>
16 : #include <sys/wait.h>
17 : #include <poll.h>
18 : #include <stdarg.h>
19 :
20 : static TDB_DATA key, data;
21 :
22 4 : static void log_void(struct tdb_context *tdb, enum tdb_debug_level level,
23 : const char *fmt, ...)
24 : {
25 4 : }
26 :
27 0 : static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level,
28 : const char *fmt, ...)
29 : {
30 : va_list ap;
31 0 : va_start(ap, fmt);
32 0 : vfprintf(stderr, fmt, ap);
33 0 : va_end(ap);
34 0 : }
35 :
36 1 : static int do_child(int fd)
37 : {
38 : struct tdb_context *tdb;
39 : unsigned int log_count;
40 1 : struct tdb_logging_context log_ctx = { log_fn, &log_count };
41 1 : struct tdb_logging_context nolog_ctx = { log_void, NULL };
42 : char c;
43 :
44 1 : read(fd, &c, 1);
45 :
46 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
47 : TDB_DEFAULT,
48 : O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL);
49 1 : ok((tdb == NULL) && (errno == EINVAL), "TDB_DEFAULT without "
50 : "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno);
51 :
52 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
53 : TDB_CLEAR_IF_FIRST,
54 : O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL);
55 1 : ok((tdb == NULL) && (errno == EINVAL), "TDB_CLEAR_IF_FIRST without "
56 : "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno);
57 :
58 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
59 : TDB_CLEAR_IF_FIRST |
60 : TDB_MUTEX_LOCKING |
61 : TDB_INTERNAL,
62 : O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL);
63 1 : ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with "
64 : "TDB_INTERNAL should fail with EINVAL - %d", errno);
65 :
66 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
67 : TDB_CLEAR_IF_FIRST |
68 : TDB_MUTEX_LOCKING |
69 : TDB_NOMMAP,
70 : O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL);
71 1 : ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with "
72 : "TDB_NOMMAP should fail with EINVAL - %d", errno);
73 :
74 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
75 : TDB_CLEAR_IF_FIRST |
76 : TDB_MUTEX_LOCKING,
77 : O_RDONLY, 0755, &nolog_ctx, NULL);
78 1 : ok((tdb != NULL), "TDB_MUTEX_LOCKING with "
79 : "O_RDONLY should work - %d", errno);
80 1 : tdb_close(tdb);
81 :
82 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
83 : TDB_CLEAR_IF_FIRST |
84 : TDB_MUTEX_LOCKING,
85 : O_RDWR|O_CREAT, 0755, &log_ctx, NULL);
86 1 : ok((tdb != NULL), "TDB_MUTEX_LOCKING with TDB_CLEAR_IF_FIRST"
87 : "TDB_NOMMAP should work - %d", errno);
88 :
89 1 : return 0;
90 : }
91 :
92 : /* The code should barf on TDBs created with rwlocks. */
93 1 : int main(int argc, char *argv[])
94 : {
95 : struct tdb_context *tdb;
96 : unsigned int log_count;
97 1 : struct tdb_logging_context log_ctx = { log_fn, &log_count };
98 1 : struct tdb_logging_context nolog_ctx = { log_void, NULL };
99 : int ret, status;
100 : pid_t child, wait_ret;
101 : int pipefd[2];
102 1 : char c = 0;
103 : bool runtime_support;
104 :
105 1 : runtime_support = tdb_runtime_check_for_robust_mutexes();
106 :
107 1 : ret = pipe(pipefd);
108 1 : ok1(ret == 0);
109 :
110 1 : key.dsize = strlen("hi");
111 1 : key.dptr = discard_const_p(uint8_t, "hi");
112 1 : data.dsize = strlen("world");
113 1 : data.dptr = discard_const_p(uint8_t, "world");
114 :
115 1 : if (!runtime_support) {
116 0 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
117 : TDB_CLEAR_IF_FIRST|
118 : TDB_MUTEX_LOCKING,
119 : O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL);
120 0 : ok((tdb == NULL) && (errno == ENOSYS), "TDB_MUTEX_LOCKING without "
121 : "runtime support should fail with ENOSYS - %d", errno);
122 :
123 0 : skip(1, "No robust mutex support");
124 0 : return exit_status();
125 : }
126 :
127 1 : child = fork();
128 2 : if (child == 0) {
129 1 : return do_child(pipefd[0]);
130 : }
131 :
132 1 : tdb = tdb_open_ex("mutex-openflags2.tdb", 0,
133 : TDB_CLEAR_IF_FIRST|
134 : TDB_MUTEX_LOCKING,
135 : O_RDWR|O_CREAT, 0755, &log_ctx, NULL);
136 1 : ok((tdb != NULL), "tdb_open_ex with mutexes should succeed");
137 :
138 1 : write(pipefd[1], &c, 1);
139 :
140 1 : wait_ret = wait(&status);
141 1 : ok((wait_ret == child) && (status == 0),
142 : "child should have exited correctly");
143 :
144 1 : diag("done");
145 1 : return exit_status();
146 : }
|