3675
void test_add_inotify_dir_watch_IN_MOVED_FROM(__attribute__((unused))
3676
test_fixture *fixture,
3677
__attribute__((unused))
3680
__attribute__((cleanup(cleanup_close)))
3681
const int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
3682
g_assert_cmpint(epoll_fd, >=, 0);
3683
__attribute__((cleanup(cleanup_queue)))
3684
task_queue *queue = create_queue();
3685
g_assert_nonnull(queue);
3686
__attribute__((cleanup(string_set_clear)))
3687
string_set cancelled_filenames = {};
3688
const mono_microsecs current_time = 0;
3690
bool quit_now = false;
3691
buffer password = {};
3692
bool mandos_client_exited = false;
3693
bool password_is_read = false;
3695
__attribute__((cleanup(cleanup_string)))
3696
char *tempdir = make_temporary_directory();
3697
g_assert_nonnull(tempdir);
3699
__attribute__((cleanup(cleanup_string)))
3700
char *tempfilename = make_temporary_file_in_directory(tempdir);
3701
g_assert_nonnull(tempfilename);
3703
__attribute__((cleanup(cleanup_string)))
3704
char *targetdir = make_temporary_directory();
3705
g_assert_nonnull(targetdir);
3707
__attribute__((cleanup(cleanup_string)))
3708
char *targetfilename = NULL;
3709
g_assert_cmpint(asprintf(&targetfilename, "%s/%s", targetdir,
3710
basename(tempfilename)), >, 0);
3711
g_assert_nonnull(targetfilename);
3713
g_assert_true(add_inotify_dir_watch(queue, epoll_fd, &quit_now,
3715
&cancelled_filenames,
3717
&mandos_client_exited,
3718
&password_is_read));
3720
g_assert_cmpint(rename(tempfilename, targetfilename), ==, 0);
3722
const task_context *const added_read_task
3723
= find_matching_task(queue,
3724
(task_context){ .func=read_inotify_event });
3725
g_assert_nonnull(added_read_task);
3727
/* "sufficient to read at least one event." - inotify(7) */
3728
const size_t ievent_size = (sizeof(struct inotify_event)
3730
struct inotify_event *ievent = malloc(ievent_size);
3731
g_assert_nonnull(ievent);
3733
ssize_t read_size = read(added_read_task->fd, ievent, ievent_size);
3735
g_assert_cmpint((int)read_size, >, 0);
3736
g_assert_true(ievent->mask & IN_MOVED_FROM);
3737
g_assert_cmpstr(ievent->name, ==, basename(tempfilename));
3741
g_assert_cmpint(unlink(targetfilename), ==, 0);
3742
g_assert_cmpint(rmdir(targetdir), ==, 0);
3743
g_assert_cmpint(rmdir(tempdir), ==, 0);
3675
3747
void test_add_inotify_dir_watch_IN_DELETE(__attribute__((unused))
3676
3748
test_fixture *fixture,
3677
3749
__attribute__((unused))
4180
void test_read_inotify_event_IN_MOVED_FROM(__attribute__((unused))
4181
test_fixture *fixture,
4182
__attribute__((unused))
4183
gconstpointer user_data){
4184
__attribute__((cleanup(cleanup_close)))
4185
const int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
4186
g_assert_cmpint(epoll_fd, >=, 0);
4187
__attribute__((cleanup(string_set_clear)))
4188
string_set cancelled_filenames = {};
4189
const mono_microsecs current_time = 0;
4192
g_assert_cmpint(pipe2(pipefds, O_CLOEXEC | O_NONBLOCK), ==, 0);
4194
/* "sufficient to read at least one event." - inotify(7) */
4195
const size_t ievent_max_size = (sizeof(struct inotify_event)
4197
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4199
struct inotify_event event;
4200
char name_buffer[NAME_MAX + 1];
4202
struct inotify_event *const ievent = &ievent_buffer.event;
4204
const char dummy_file_name[] = "ask.dummy_file_name";
4205
ievent->mask = IN_MOVED_FROM;
4206
ievent->len = sizeof(dummy_file_name);
4207
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4208
const size_t ievent_size = (sizeof(struct inotify_event)
4209
+ sizeof(dummy_file_name));
4210
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4212
g_assert_cmpint(close(pipefds[1]), ==, 0);
4214
bool quit_now = false;
4215
buffer password = {};
4216
bool mandos_client_exited = false;
4217
bool password_is_read = false;
4218
__attribute__((cleanup(cleanup_queue)))
4219
task_queue *queue = create_queue();
4220
g_assert_nonnull(queue);
4222
task_context task = {
4223
.func=read_inotify_event,
4226
.quit_now=&quit_now,
4227
.password=&password,
4228
.filename=strdup("/nonexistent"),
4229
.cancelled_filenames=&cancelled_filenames,
4230
.current_time=¤t_time,
4231
.mandos_client_exited=&mandos_client_exited,
4232
.password_is_read=&password_is_read,
4234
task.func(task, queue);
4235
g_assert_false(quit_now);
4236
g_assert_true(queue->next_run == 0);
4237
g_assert_cmpuint((unsigned int)queue->length, ==, 1);
4239
g_assert_nonnull(find_matching_task(queue, (task_context){
4240
.func=read_inotify_event,
4243
.quit_now=&quit_now,
4244
.password=&password,
4245
.filename=task.filename,
4246
.cancelled_filenames=&cancelled_filenames,
4247
.current_time=¤t_time,
4248
.mandos_client_exited=&mandos_client_exited,
4249
.password_is_read=&password_is_read,
4252
g_assert_true(epoll_set_contains(epoll_fd, pipefds[0],
4253
EPOLLIN | EPOLLRDHUP));
4255
__attribute__((cleanup(cleanup_string)))
4256
char *filename = NULL;
4257
g_assert_cmpint(asprintf(&filename, "%s/%s", task.filename,
4258
dummy_file_name), >, 0);
4259
g_assert_nonnull(filename);
4260
g_assert_true(string_set_contains(*task.cancelled_filenames,
4107
4264
static void test_read_inotify_event_IN_DELETE(__attribute__((unused))
4108
4265
test_fixture *fixture,
4109
4266
__attribute__((unused))
4342
4499
EPOLLIN | EPOLLRDHUP));
4503
test_read_inotify_event_IN_MOVED_FROM_badname(__attribute__((unused))
4504
test_fixture *fixture,
4505
__attribute__((unused))
4508
__attribute__((cleanup(cleanup_close)))
4509
const int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
4510
g_assert_cmpint(epoll_fd, >=, 0);
4511
__attribute__((cleanup(string_set_clear)))
4512
string_set cancelled_filenames = {};
4513
const mono_microsecs current_time = 0;
4516
g_assert_cmpint(pipe2(pipefds, O_CLOEXEC | O_NONBLOCK), ==, 0);
4518
/* "sufficient to read at least one event." - inotify(7) */
4519
const size_t ievent_max_size = (sizeof(struct inotify_event)
4521
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4523
struct inotify_event event;
4524
char name_buffer[NAME_MAX + 1];
4526
struct inotify_event *const ievent = &ievent_buffer.event;
4528
const char dummy_file_name[] = "ignored.dummy_file_name";
4529
ievent->mask = IN_MOVED_FROM;
4530
ievent->len = sizeof(dummy_file_name);
4531
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4532
const size_t ievent_size = (sizeof(struct inotify_event)
4533
+ sizeof(dummy_file_name));
4534
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4536
g_assert_cmpint(close(pipefds[1]), ==, 0);
4538
bool quit_now = false;
4539
buffer password = {};
4540
bool mandos_client_exited = false;
4541
bool password_is_read = false;
4542
__attribute__((cleanup(cleanup_queue)))
4543
task_queue *queue = create_queue();
4544
g_assert_nonnull(queue);
4546
task_context task = {
4547
.func=read_inotify_event,
4550
.quit_now=&quit_now,
4551
.password=&password,
4552
.filename=strdup("/nonexistent"),
4553
.cancelled_filenames=&cancelled_filenames,
4554
.current_time=¤t_time,
4555
.mandos_client_exited=&mandos_client_exited,
4556
.password_is_read=&password_is_read,
4558
task.func(task, queue);
4559
g_assert_false(quit_now);
4560
g_assert_true(queue->next_run == 0);
4561
g_assert_cmpuint((unsigned int)queue->length, ==, 1);
4563
g_assert_nonnull(find_matching_task(queue, (task_context){
4564
.func=read_inotify_event,
4567
.quit_now=&quit_now,
4568
.password=&password,
4569
.filename=task.filename,
4570
.cancelled_filenames=&cancelled_filenames,
4571
.current_time=¤t_time,
4572
.mandos_client_exited=&mandos_client_exited,
4573
.password_is_read=&password_is_read,
4576
g_assert_true(epoll_set_contains(epoll_fd, pipefds[0],
4577
EPOLLIN | EPOLLRDHUP));
4579
__attribute__((cleanup(cleanup_string)))
4580
char *filename = NULL;
4581
g_assert_cmpint(asprintf(&filename, "%s/%s", task.filename,
4582
dummy_file_name), >, 0);
4583
g_assert_nonnull(filename);
4584
g_assert_false(string_set_contains(cancelled_filenames, filename));
4346
4588
void test_read_inotify_event_IN_DELETE_badname(__attribute__((unused))
4347
4589
test_fixture *fixture,
7593
7835
test_add_inotify_dir_watch_IN_CLOSE_WRITE);
7594
7836
test_add_st("/task-creators/add_inotify_dir_watch/IN_MOVED_TO",
7595
7837
test_add_inotify_dir_watch_IN_MOVED_TO);
7838
test_add_st("/task-creators/add_inotify_dir_watch/IN_MOVED_FROM",
7839
test_add_inotify_dir_watch_IN_MOVED_FROM);
7596
7840
test_add_st("/task-creators/add_inotify_dir_watch/IN_DELETE",
7597
7841
test_add_inotify_dir_watch_IN_DELETE);
7598
7842
test_add_st("/task/read_inotify_event/readerror",
7607
7851
test_read_inotify_event_IN_CLOSE_WRITE);
7608
7852
test_add_st("/task/read_inotify_event/IN_MOVED_TO",
7609
7853
test_read_inotify_event_IN_MOVED_TO);
7854
test_add_st("/task/read_inotify_event/IN_MOVED_FROM",
7855
test_read_inotify_event_IN_MOVED_FROM);
7610
7856
test_add_st("/task/read_inotify_event/IN_DELETE",
7611
7857
test_read_inotify_event_IN_DELETE);
7612
7858
test_add_st("/task/read_inotify_event/IN_CLOSE_WRITE/badname",
7613
7859
test_read_inotify_event_IN_CLOSE_WRITE_badname);
7614
7860
test_add_st("/task/read_inotify_event/IN_MOVED_TO/badname",
7615
7861
test_read_inotify_event_IN_MOVED_TO_badname);
7862
test_add_st("/task/read_inotify_event/IN_MOVED_FROM/badname",
7863
test_read_inotify_event_IN_MOVED_FROM_badname);
7616
7864
test_add_st("/task/read_inotify_event/IN_DELETE/badname",
7617
7865
test_read_inotify_event_IN_DELETE_badname);
7618
7866
test_add_st("/task/open_and_parse_question/ENOENT",