Skip to content

Commit

Permalink
Determine behaviour of EVFILT_WRITE for regular files on FreeBSD
Browse files Browse the repository at this point in the history
  • Loading branch information
arr2036 committed Mar 18, 2024
1 parent 1372cfd commit d4f159f
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
3 changes: 2 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ set(LIBKQUEUE_TEST_SOURCES
test.c
timer.c
user.c
vnode.c)
vnode.c
write.c)
if(UNIX)
list(APPEND LIBKQUEUE_TEST_SOURCES
proc.c
Expand Down
1 change: 1 addition & 0 deletions test/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ void test_kqueue(struct test_context *);
void test_evfilt_read(struct test_context *);
void test_evfilt_signal(struct test_context *);
void test_evfilt_vnode(struct test_context *);
void test_evfilt_write(struct test_context *);
void test_evfilt_timer(struct test_context *);
void test_evfilt_proc(struct test_context *);
#ifdef EVFILT_USER
Expand Down
4 changes: 4 additions & 0 deletions test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ main(int argc, char **argv)
.ut_func = test_evfilt_vnode,
.ut_end = INT_MAX },
#endif
{ .ut_name = "write",
.ut_enabled = 1,
.ut_func = test_evfilt_write,
.ut_end = INT_MAX },
#ifdef EVFILT_USER
{ .ut_name = "user",
.ut_enabled = 1,
Expand Down
73 changes: 73 additions & 0 deletions test/write.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 Arran Cudbard-Bell <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "common.h"


/** Test if we can setup an event to write to a regular file
*
* Setting up a write event on a regular file doesn't make much sense
* but it is allowed by kqueue, so check we exhibit similar behaviour.
*/
void
test_kevent_write_regular_file(struct test_context *ctx)
{
struct kevent kev, ret[1];
int fd;

fd = open(ctx->testfile, O_CREAT | O_WRONLY);
if (fd < 0)
abort();

EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, &fd);
kevent_rv_cmp(0, kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL));
kevent_get(ret, NUM_ELEMENTS(ret), ctx->kqfd, 1);

/* File should appear immediately writable */
kevent_get(NULL, 0, ctx->kqfd, 1);
kevent_cmp(&kev, ret);
if (write(fd, "test", 4) != 4) {
printf("failed writing to set file: %s", strerror(errno));
abort();
}

/* ...should still be writable */
kevent_get(NULL, 0, ctx->kqfd, 1);
kevent_cmp(&kev, ret);

kev.flags = EV_DELETE;
kevent_rv_cmp(0, kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL));

close(fd);
unlink(ctx->testfile);
}

void
test_evfilt_write(struct test_context *ctx)
{
char *tmpdir = getenv("TMPDIR");
if (tmpdir == NULL)
#ifdef __ANDROID__
tmpdir = "/data/local/tmp";
#else
tmpdir = "/tmp";
#endif

snprintf(ctx->testfile, sizeof(ctx->testfile), "%s/kqueue-test%d.tmp",
tmpdir, testing_make_uid());

test(kevent_write_regular_file, ctx);
}

0 comments on commit d4f159f

Please sign in to comment.