1071
1071
/* "sufficient to read at least one event." - inotify(7) */
1072
1072
const size_t ievent_size = (sizeof(struct inotify_event)
1073
1073
+ NAME_MAX + 1);
1074
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
1075
struct inotify_event *ievent = ((struct inotify_event *)
1075
struct inotify_event event;
1076
char name_buffer[NAME_MAX + 1];
1078
struct inotify_event *const ievent = &ievent_buffer.event;
1078
1080
const ssize_t read_length = read(fd, ievent, ievent_size);
1079
1081
if(read_length == 0){ /* EOF */
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);
3673
3747
void test_add_inotify_dir_watch_IN_DELETE(__attribute__((unused))
3674
3748
test_fixture *fixture,
3675
3749
__attribute__((unused))
3929
4003
const size_t ievent_max_size = (sizeof(struct inotify_event)
3930
4004
+ NAME_MAX + 1);
3931
4005
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
3932
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
3933
struct inotify_event *ievent = ((struct inotify_event *)
4007
struct inotify_event event;
4008
char name_buffer[NAME_MAX + 1];
4010
struct inotify_event *const ievent = &ievent_buffer.event;
3936
4012
const char dummy_file_name[] = "ask.dummy_file_name";
3937
4013
ievent->mask = IN_CLOSE_WRITE;
3939
4015
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
3940
4016
const size_t ievent_size = (sizeof(struct inotify_event)
3941
4017
+ sizeof(dummy_file_name));
3942
g_assert_cmpint(write(pipefds[1], ievent_buffer, ievent_size),
4018
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
3943
4019
==, ievent_size);
3944
4020
g_assert_cmpint(close(pipefds[1]), ==, 0);
4022
4098
const size_t ievent_max_size = (sizeof(struct inotify_event)
4023
4099
+ NAME_MAX + 1);
4024
4100
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4025
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
4026
struct inotify_event *ievent = ((struct inotify_event *)
4102
struct inotify_event event;
4103
char name_buffer[NAME_MAX + 1];
4105
struct inotify_event *const ievent = &ievent_buffer.event;
4029
4107
const char dummy_file_name[] = "ask.dummy_file_name";
4030
4108
ievent->mask = IN_MOVED_TO;
4032
4110
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4033
4111
const size_t ievent_size = (sizeof(struct inotify_event)
4034
4112
+ sizeof(dummy_file_name));
4035
g_assert_cmpint(write(pipefds[1], ievent_buffer, ievent_size),
4113
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4036
4114
==, ievent_size);
4037
4115
g_assert_cmpint(close(pipefds[1]), ==, 0);
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,
4101
4264
static void test_read_inotify_event_IN_DELETE(__attribute__((unused))
4102
4265
test_fixture *fixture,
4103
4266
__attribute__((unused))
4117
4280
const size_t ievent_max_size = (sizeof(struct inotify_event)
4118
4281
+ NAME_MAX + 1);
4119
4282
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4120
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
4121
struct inotify_event *ievent = ((struct inotify_event *)
4284
struct inotify_event event;
4285
char name_buffer[NAME_MAX + 1];
4287
struct inotify_event *const ievent = &ievent_buffer.event;
4124
4289
const char dummy_file_name[] = "ask.dummy_file_name";
4125
4290
ievent->mask = IN_DELETE;
4127
4292
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4128
4293
const size_t ievent_size = (sizeof(struct inotify_event)
4129
4294
+ sizeof(dummy_file_name));
4130
g_assert_cmpint(write(pipefds[1], ievent_buffer, ievent_size),
4295
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4131
4296
==, ievent_size);
4132
4297
g_assert_cmpint(close(pipefds[1]), ==, 0);
4199
4364
const size_t ievent_max_size = (sizeof(struct inotify_event)
4200
4365
+ NAME_MAX + 1);
4201
4366
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4202
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
4203
struct inotify_event *ievent = ((struct inotify_event *)
4368
struct inotify_event event;
4369
char name_buffer[NAME_MAX + 1];
4371
struct inotify_event *const ievent = &ievent_buffer.event;
4206
4373
const char dummy_file_name[] = "ignored.dummy_file_name";
4207
4374
ievent->mask = IN_CLOSE_WRITE;
4209
4376
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4210
4377
const size_t ievent_size = (sizeof(struct inotify_event)
4211
4378
+ sizeof(dummy_file_name));
4212
g_assert_cmpint(write(pipefds[1], ievent_buffer, ievent_size),
4379
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4213
4380
==, ievent_size);
4214
4381
g_assert_cmpint(close(pipefds[1]), ==, 0);
4273
4440
const size_t ievent_max_size = (sizeof(struct inotify_event)
4274
4441
+ NAME_MAX + 1);
4275
4442
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4276
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
4277
struct inotify_event *ievent = ((struct inotify_event *)
4444
struct inotify_event event;
4445
char name_buffer[NAME_MAX + 1];
4447
struct inotify_event *const ievent = &ievent_buffer.event;
4280
4449
const char dummy_file_name[] = "ignored.dummy_file_name";
4281
4450
ievent->mask = IN_MOVED_TO;
4283
4452
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4284
4453
const size_t ievent_size = (sizeof(struct inotify_event)
4285
4454
+ sizeof(dummy_file_name));
4286
g_assert_cmpint(write(pipefds[1], ievent_buffer, ievent_size),
4455
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4287
4456
==, ievent_size);
4288
4457
g_assert_cmpint(close(pipefds[1]), ==, 0);
4330
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));
4334
4588
void test_read_inotify_event_IN_DELETE_badname(__attribute__((unused))
4335
4589
test_fixture *fixture,
4350
4604
const size_t ievent_max_size = (sizeof(struct inotify_event)
4351
4605
+ NAME_MAX + 1);
4352
4606
g_assert_cmpint(ievent_max_size, <=, PIPE_BUF);
4353
char ievent_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
4354
struct inotify_event *ievent = ((struct inotify_event *)
4608
struct inotify_event event;
4609
char name_buffer[NAME_MAX + 1];
4611
struct inotify_event *const ievent = &ievent_buffer.event;
4357
4613
const char dummy_file_name[] = "ignored.dummy_file_name";
4358
4614
ievent->mask = IN_DELETE;
4360
4616
memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name));
4361
4617
const size_t ievent_size = (sizeof(struct inotify_event)
4362
4618
+ sizeof(dummy_file_name));
4363
g_assert_cmpint(write(pipefds[1], ievent_buffer, ievent_size),
4619
g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size),
4364
4620
==, ievent_size);
4365
4621
g_assert_cmpint(close(pipefds[1]), ==, 0);
7579
7835
test_add_inotify_dir_watch_IN_CLOSE_WRITE);
7580
7836
test_add_st("/task-creators/add_inotify_dir_watch/IN_MOVED_TO",
7581
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);
7582
7840
test_add_st("/task-creators/add_inotify_dir_watch/IN_DELETE",
7583
7841
test_add_inotify_dir_watch_IN_DELETE);
7584
7842
test_add_st("/task/read_inotify_event/readerror",
7593
7851
test_read_inotify_event_IN_CLOSE_WRITE);
7594
7852
test_add_st("/task/read_inotify_event/IN_MOVED_TO",
7595
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);
7596
7856
test_add_st("/task/read_inotify_event/IN_DELETE",
7597
7857
test_read_inotify_event_IN_DELETE);
7598
7858
test_add_st("/task/read_inotify_event/IN_CLOSE_WRITE/badname",
7599
7859
test_read_inotify_event_IN_CLOSE_WRITE_badname);
7600
7860
test_add_st("/task/read_inotify_event/IN_MOVED_TO/badname",
7601
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);
7602
7864
test_add_st("/task/read_inotify_event/IN_DELETE/badname",
7603
7865
test_read_inotify_event_IN_DELETE_badname);
7604
7866
test_add_st("/task/open_and_parse_question/ENOENT",