Skip to content

Commit d4f159f

Browse files
committed
Determine behaviour of EVFILT_WRITE for regular files on FreeBSD
1 parent 1372cfd commit d4f159f

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed

test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ set(LIBKQUEUE_TEST_SOURCES
2525
test.c
2626
timer.c
2727
user.c
28-
vnode.c)
28+
vnode.c
29+
write.c)
2930
if(UNIX)
3031
list(APPEND LIBKQUEUE_TEST_SOURCES
3132
proc.c

test/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ void test_kqueue(struct test_context *);
112112
void test_evfilt_read(struct test_context *);
113113
void test_evfilt_signal(struct test_context *);
114114
void test_evfilt_vnode(struct test_context *);
115+
void test_evfilt_write(struct test_context *);
115116
void test_evfilt_timer(struct test_context *);
116117
void test_evfilt_proc(struct test_context *);
117118
#ifdef EVFILT_USER

test/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ main(int argc, char **argv)
169169
.ut_func = test_evfilt_vnode,
170170
.ut_end = INT_MAX },
171171
#endif
172+
{ .ut_name = "write",
173+
.ut_enabled = 1,
174+
.ut_func = test_evfilt_write,
175+
.ut_end = INT_MAX },
172176
#ifdef EVFILT_USER
173177
{ .ut_name = "user",
174178
.ut_enabled = 1,

test/write.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2024 Arran Cudbard-Bell <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*/
16+
17+
#include "common.h"
18+
19+
20+
/** Test if we can setup an event to write to a regular file
21+
*
22+
* Setting up a write event on a regular file doesn't make much sense
23+
* but it is allowed by kqueue, so check we exhibit similar behaviour.
24+
*/
25+
void
26+
test_kevent_write_regular_file(struct test_context *ctx)
27+
{
28+
struct kevent kev, ret[1];
29+
int fd;
30+
31+
fd = open(ctx->testfile, O_CREAT | O_WRONLY);
32+
if (fd < 0)
33+
abort();
34+
35+
EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, &fd);
36+
kevent_rv_cmp(0, kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL));
37+
kevent_get(ret, NUM_ELEMENTS(ret), ctx->kqfd, 1);
38+
39+
/* File should appear immediately writable */
40+
kevent_get(NULL, 0, ctx->kqfd, 1);
41+
kevent_cmp(&kev, ret);
42+
if (write(fd, "test", 4) != 4) {
43+
printf("failed writing to set file: %s", strerror(errno));
44+
abort();
45+
}
46+
47+
/* ...should still be writable */
48+
kevent_get(NULL, 0, ctx->kqfd, 1);
49+
kevent_cmp(&kev, ret);
50+
51+
kev.flags = EV_DELETE;
52+
kevent_rv_cmp(0, kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL));
53+
54+
close(fd);
55+
unlink(ctx->testfile);
56+
}
57+
58+
void
59+
test_evfilt_write(struct test_context *ctx)
60+
{
61+
char *tmpdir = getenv("TMPDIR");
62+
if (tmpdir == NULL)
63+
#ifdef __ANDROID__
64+
tmpdir = "/data/local/tmp";
65+
#else
66+
tmpdir = "/tmp";
67+
#endif
68+
69+
snprintf(ctx->testfile, sizeof(ctx->testfile), "%s/kqueue-test%d.tmp",
70+
tmpdir, testing_make_uid());
71+
72+
test(kevent_write_regular_file, ctx);
73+
}

0 commit comments

Comments
 (0)