48
48
#include <error.h> /* error() */
49
49
#include <sysexits.h> /* EX_USAGE, EX_OSERR, EX_OSFILE */
50
50
#include <errno.h> /* errno, error_t, EACCES,
51
ENAMETOOLONG, ENOENT, ENOTDIR,
52
EEXIST, ECHILD, EPERM, ENOMEM,
53
EAGAIN, EINTR, ENOBUFS, EADDRINUSE,
51
ENAMETOOLONG, ENOENT, EEXIST,
52
ECHILD, EPERM, ENOMEM, EAGAIN,
53
EINTR, ENOBUFS, EADDRINUSE,
54
54
ECONNREFUSED, ECONNRESET,
55
55
ETOOMANYREFS, EMSGSIZE, EBADF,
83
83
#include <sys/mman.h> /* munlock(), mlock() */
84
84
#include <fcntl.h> /* O_CLOEXEC, O_NONBLOCK, fcntl(),
85
85
F_GETFD, F_GETFL, FD_CLOEXEC,
86
open(), O_WRONLY, O_NOCTTY,
87
O_RDONLY, O_NOFOLLOW */
86
open(), O_WRONLY, O_RDONLY */
88
87
#include <sys/wait.h> /* waitpid(), WNOHANG, WIFEXITED(),
90
89
#include <limits.h> /* PIPE_BUF, NAME_MAX, INT_MAX */
91
90
#include <sys/inotify.h> /* inotify_init1(), IN_NONBLOCK,
92
91
IN_CLOEXEC, inotify_add_watch(),
93
92
IN_CLOSE_WRITE, IN_MOVED_TO,
94
IN_MOVED_FROM, IN_DELETE,
95
IN_EXCL_UNLINK, IN_ONLYDIR,
96
struct inotify_event */
93
IN_DELETE, struct inotify_event */
97
94
#include <fnmatch.h> /* fnmatch(), FNM_FILE_NAME */
98
95
#include <stdio.h> /* asprintf(), FILE, fopen(),
99
96
getline(), sscanf(), feof(),
148
145
mono_microsecs next_run;
149
146
} __attribute__((designated_init)) task_queue;
151
/* "task_func" - A function type for task functions
148
/* "func_type" - A function type for task functions
153
150
I.e. functions for the code which runs when a task is run, all have
1024
1020
if(inotify_add_watch(fd, dir, IN_CLOSE_WRITE | IN_MOVED_TO
1025
| IN_MOVED_FROM| IN_DELETE | IN_EXCL_UNLINK
1021
| IN_MOVED_FROM| IN_DELETE | IN_EXCL_UNLINK)
1028
1023
error(0, errno, "Failed to create inotify watch on %s", dir);
2229
2224
__attribute__((cleanup(cleanup_close)))
2230
const int devnull_fd = open("/dev/null",
2231
O_WRONLY | O_CLOEXEC | O_NOCTTY);
2225
const int devnull_fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
2232
2226
g_assert_cmpint(devnull_fd, >=, 0);
2233
2227
__attribute__((cleanup(cleanup_close)))
2234
2228
const int real_stderr_fd = dup(STDERR_FILENO);
2259
2253
__attribute__((cleanup(cleanup_close)))
2260
2254
const int devnull_fd = open("/dev/null",
2261
O_WRONLY | O_CLOEXEC | O_NOCTTY);
2255
O_WRONLY | O_CLOEXEC);
2262
2256
g_assert_cmpint(devnull_fd, >=, 0);
2263
2257
__attribute__((cleanup(cleanup_close)))
2264
2258
const int real_stderr_fd = dup(STDERR_FILENO);
2910
2904
__attribute__((cleanup(cleanup_close)))
2911
2905
const int devnull_fd = open("/dev/null",
2912
O_WRONLY | O_CLOEXEC | O_NOCTTY);
2906
O_WRONLY | O_CLOEXEC);
2913
2907
g_assert_cmpint(devnull_fd, >=, 0);
2914
2908
__attribute__((cleanup(cleanup_close)))
2915
2909
const int real_stderr_fd = dup(STDERR_FILENO);
2981
2975
__attribute__((cleanup(cleanup_close)))
2982
2976
const int devnull_fd = open("/dev/null",
2983
O_WRONLY | O_CLOEXEC, O_NOCTTY);
2977
O_WRONLY | O_CLOEXEC);
2984
2978
g_assert_cmpint(devnull_fd, >=, 0);
2985
2979
__attribute__((cleanup(cleanup_close)))
2986
2980
const int real_stderr_fd = dup(STDERR_FILENO);
3024
3018
buffer password = {};
3026
3020
/* Reading /proc/self/mem from offset 0 will always give EIO */
3027
const int fd = open("/proc/self/mem",
3028
O_RDONLY | O_CLOEXEC | O_NOCTTY);
3021
const int fd = open("/proc/self/mem", O_RDONLY | O_CLOEXEC);
3030
3023
bool password_is_read = false;
3031
3024
bool quit_now = false;
3459
3452
g_assert_cmpuint((unsigned int)queue->length, ==, 0);
3462
static void test_add_inotify_dir_watch_nondir(__attribute__((unused))
3463
test_fixture *fixture,
3464
__attribute__((unused))
3467
__attribute__((cleanup(cleanup_close)))
3468
const int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
3469
g_assert_cmpint(epoll_fd, >=, 0);
3470
__attribute__((cleanup(cleanup_queue)))
3471
task_queue *queue = create_queue();
3472
g_assert_nonnull(queue);
3473
__attribute__((cleanup(string_set_clear)))
3474
string_set cancelled_filenames = {};
3475
const mono_microsecs current_time = 0;
3477
bool quit_now = false;
3478
buffer password = {};
3479
bool mandos_client_exited = false;
3480
bool password_is_read = false;
3482
const char not_a_directory[] = "/dev/tty";
3484
FILE *real_stderr = stderr;
3485
FILE *devnull = fopen("/dev/null", "we");
3486
g_assert_nonnull(devnull);
3488
g_assert_false(add_inotify_dir_watch(queue, epoll_fd, &quit_now,
3489
&password, not_a_directory,
3490
&cancelled_filenames,
3492
&mandos_client_exited,
3493
&password_is_read));
3494
stderr = real_stderr;
3495
g_assert_cmpint(fclose(devnull), ==, 0);
3497
g_assert_cmpuint((unsigned int)queue->length, ==, 0);
3500
3455
static void test_add_inotify_dir_watch_EAGAIN(__attribute__((unused))
3501
3456
test_fixture *fixture,
3502
3457
__attribute__((unused))
3939
3894
const mono_microsecs current_time = 0;
3941
3896
/* Reading /proc/self/mem from offset 0 will always result in EIO */
3942
const int fd = open("/proc/self/mem",
3943
O_RDONLY | O_CLOEXEC | O_NOCTTY);
3897
const int fd = open("/proc/self/mem", O_RDONLY | O_CLOEXEC);
3945
3899
bool quit_now = false;
3946
3900
__attribute__((cleanup(cleanup_queue)))
5631
5585
__attribute__((unused))
5632
5586
gconstpointer user_data){
5633
5587
__attribute__((cleanup(cleanup_close)))
5634
const int epoll_fd = open("/dev/null",
5635
O_WRONLY | O_CLOEXEC | O_NOCTTY);
5588
const int epoll_fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
5636
5589
__attribute__((cleanup(cleanup_string)))
5637
5590
char *const question_filename = strdup("/nonexistent/question");
5638
5591
g_assert_nonnull(question_filename);
6042
5995
__attribute__((unused))
6043
5996
gconstpointer user_data){
6044
5997
__attribute__((cleanup(cleanup_close)))
6045
const int epoll_fd = open("/dev/null",
6046
O_WRONLY | O_CLOEXEC | O_NOCTTY);
5998
const int epoll_fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
6047
5999
__attribute__((cleanup(cleanup_string)))
6048
6000
char *const question_filename = strdup("/nonexistent/question");
6049
6001
g_assert_nonnull(question_filename);
6312
6264
const char *const
6314
6266
__attribute__((cleanup(cleanup_close)))
6315
const int devnull_fd = open("/dev/null",
6316
O_WRONLY | O_CLOEXEC | O_NOCTTY);
6267
const int devnull_fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
6317
6268
g_assert_cmpint(devnull_fd, >=, 0);
6318
6269
__attribute__((cleanup(cleanup_close)))
6319
6270
const int real_stderr_fd = dup(STDERR_FILENO);
7954
7905
test_add_inotify_dir_watch);
7955
7906
test_add_st("/task-creators/add_inotify_dir_watch/fail",
7956
7907
test_add_inotify_dir_watch_fail);
7957
test_add_st("/task-creators/add_inotify_dir_watch/not-a-directory",
7958
test_add_inotify_dir_watch_nondir);
7959
7908
test_add_st("/task-creators/add_inotify_dir_watch/EAGAIN",
7960
7909
test_add_inotify_dir_watch_EAGAIN);
7961
7910
test_add_st("/task-creators/add_inotify_dir_watch/IN_CLOSE_WRITE",
8092
8041
g_option_context_set_help_enabled(context, FALSE);
8093
8042
g_option_context_set_ignore_unknown_options(context, TRUE);
8095
gboolean should_run_tests = FALSE;
8044
gboolean run_tests = FALSE;
8096
8045
GOptionEntry entries[] = {
8097
8046
{ "test", 0, 0, G_OPTION_ARG_NONE,
8098
&should_run_tests, "Run tests", NULL },
8047
&run_tests, "Run tests", NULL },
8101
8050
g_option_context_add_main_entries(context, entries, NULL);