4 Copyright (C) Amitay Isaacs 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
27 #include "common/logging.c"
28 #include "common/pkt_read.c"
29 #include "common/pkt_write.c"
30 #include "common/comm.c"
31 #include "common/pidfile.c"
32 #include "common/sock_daemon.c"
33 #include "common/sock_io.c"
35 struct dummy_wait_state {
38 static struct tevent_req *dummy_wait_send(TALLOC_CTX *mem_ctx,
39 struct tevent_context *ev,
42 struct tevent_req *req;
43 struct dummy_wait_state *state;
44 const char *sockpath = (const char *)private_data;
48 ret = stat(sockpath, &st);
50 assert(S_ISSOCK(st.st_mode));
52 req = tevent_req_create(mem_ctx, &state, struct dummy_wait_state);
58 return tevent_req_post(req, ev);
61 static bool dummy_wait_recv(struct tevent_req *req, int *perr)
66 static int test1_startup_fail(void *private_data)
71 static int test1_startup(void *private_data)
73 const char *sockpath = (const char *)private_data;
77 ret = stat(sockpath, &st);
83 struct test1_startup_state {
86 static struct tevent_req *test1_startup_send(TALLOC_CTX *mem_ctx,
87 struct tevent_context *ev,
90 struct tevent_req *req;
91 struct test1_startup_state *state;
93 req = tevent_req_create(mem_ctx, &state, struct test1_startup_state);
98 tevent_req_error(req, 2);
99 return tevent_req_post(req, ev);
102 static bool test1_startup_recv(struct tevent_req *req, int *perr)
104 if (tevent_req_is_unix_error(req, perr)) {
111 static struct tevent_req *dummy_read_send(TALLOC_CTX *mem_ctx,
112 struct tevent_context *ev,
113 struct sock_client_context *client,
114 uint8_t *buf, size_t buflen,
120 static bool dummy_read_recv(struct tevent_req *req, int *perr)
128 static struct sock_socket_funcs dummy_socket_funcs = {
129 .read_send = dummy_read_send,
130 .read_recv = dummy_read_recv,
136 * Check setup without actually running daemon
139 static void test1(TALLOC_CTX *mem_ctx, const char *pidfile,
140 const char *sockpath)
142 struct tevent_context *ev;
143 struct sock_daemon_context *sockd;
144 struct sock_daemon_funcs test1_funcs;
148 ev = tevent_context_init(mem_ctx);
151 test1_funcs = (struct sock_daemon_funcs){
152 .startup = test1_startup_fail,
155 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
156 &test1_funcs, NULL, &sockd);
158 assert(sockd != NULL);
160 ret = stat(pidfile, &st);
163 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
167 test1_funcs = (struct sock_daemon_funcs){
168 .startup_send = test1_startup_send,
169 .startup_recv = test1_startup_recv,
172 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
173 &test1_funcs, NULL, &sockd);
175 assert(sockd != NULL);
177 ret = stat(pidfile, &st);
180 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
184 test1_funcs = (struct sock_daemon_funcs){
185 .startup = test1_startup,
186 .wait_send = dummy_wait_send,
187 .wait_recv = dummy_wait_recv,
190 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
191 &test1_funcs, discard_const(sockpath), &sockd);
193 assert(sockd != NULL);
195 ret = sock_daemon_add_unix(sockd, sockpath, &dummy_socket_funcs, NULL);
198 ret = stat(sockpath, &st);
201 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
204 talloc_free(mem_ctx);
210 * Start daemon, check PID file, sock daemon functions, termination,
214 static int test2_startup(void *private_data)
216 int fd = *(int *)private_data;
220 nwritten = write(fd, &ret, sizeof(ret));
221 assert(nwritten == sizeof(ret));
225 static int test2_reconfigure(void *private_data)
227 static bool first_time = true;
228 int fd = *(int *)private_data;
232 nwritten = write(fd, &ret, sizeof(ret));
233 assert(nwritten == sizeof(ret));
243 struct test2_reconfigure_state {
247 static struct tevent_req *test2_reconfigure_send(TALLOC_CTX *mem_ctx,
248 struct tevent_context *ev,
251 struct tevent_req *req;
252 struct test2_reconfigure_state *state;
253 static bool first_time = true;
255 req = tevent_req_create(mem_ctx, &state,
256 struct test2_reconfigure_state);
261 state->fd = *(int *)private_data;
265 tevent_req_error(req, 2);
267 tevent_req_done(req);
270 return tevent_req_post(req, ev);
273 static bool test2_reconfigure_recv(struct tevent_req *req, int *perr)
275 struct test2_reconfigure_state *state = tevent_req_data(
276 req, struct test2_reconfigure_state);
280 nwritten = write(state->fd, &ret, sizeof(ret));
281 assert(nwritten == sizeof(ret));
283 if (tevent_req_is_unix_error(req, perr)) {
290 static void test2_shutdown(void *private_data)
292 int fd = *(int *)private_data;
296 nwritten = write(fd, &ret, sizeof(ret));
297 assert(nwritten == sizeof(ret));
300 struct test2_shutdown_state {
304 static struct tevent_req *test2_shutdown_send(TALLOC_CTX *mem_ctx,
305 struct tevent_context *ev,
308 struct tevent_req *req;
309 struct test2_shutdown_state *state;
311 req = tevent_req_create(mem_ctx, &state,
312 struct test2_shutdown_state);
317 state->fd = *(int *)private_data;
319 tevent_req_done(req);
320 return tevent_req_post(req, ev);
323 static void test2_shutdown_recv(struct tevent_req *req)
325 struct test2_shutdown_state *state = tevent_req_data(
326 req, struct test2_shutdown_state);
330 nwritten = write(state->fd, &ret, sizeof(ret));
331 assert(nwritten == sizeof(ret));
334 static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
335 const char *sockpath)
343 char pidstr[20] = { 0 };
352 struct tevent_context *ev;
353 struct sock_daemon_context *sockd;
354 struct sock_daemon_funcs test2_funcs = {
355 .startup = test2_startup,
356 .reconfigure = test2_reconfigure,
357 .shutdown = test2_shutdown,
362 ev = tevent_context_init(mem_ctx);
365 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
366 &test2_funcs, &fd[1], &sockd);
369 ret = sock_daemon_add_unix(sockd, sockpath,
370 &dummy_socket_funcs, NULL);
373 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
374 assert(ret == EINTR);
381 n = read(fd[0], &ret, sizeof(ret));
382 assert(n == sizeof(ret));
385 pidfile_fd = open(pidfile, O_RDONLY, 0644);
386 assert(pidfile_fd != -1);
387 ret = fstat(pidfile_fd, &st);
389 assert(S_ISREG(st.st_mode));
390 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
392 pid2 = (pid_t)atoi(pidstr);
396 ret = kill(pid, SIGHUP);
399 n = read(fd[0], &ret, sizeof(ret));
400 assert(n == sizeof(ret));
403 ret = kill(pid, SIGUSR1);
406 n = read(fd[0], &ret, sizeof(ret));
407 assert(n == sizeof(ret));
410 ret = kill(pid, SIGTERM);
413 n = read(fd[0], &ret, sizeof(ret));
414 assert(n == sizeof(ret));
417 pid2 = waitpid(pid, &ret, 0);
419 assert(WEXITSTATUS(ret) == 0);
423 ret = stat(pidfile, &st);
426 ret = stat(sockpath, &st);
436 struct tevent_context *ev;
437 struct sock_daemon_context *sockd;
438 struct sock_daemon_funcs test2_funcs = {
439 .startup = test2_startup,
440 .reconfigure_send = test2_reconfigure_send,
441 .reconfigure_recv = test2_reconfigure_recv,
442 .shutdown_send = test2_shutdown_send,
443 .shutdown_recv = test2_shutdown_recv,
448 ev = tevent_context_init(mem_ctx);
451 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
452 &test2_funcs, &fd[1], &sockd);
455 ret = sock_daemon_add_unix(sockd, sockpath,
456 &dummy_socket_funcs, NULL);
459 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
460 assert(ret == EINTR);
467 n = read(fd[0], &ret, sizeof(ret));
468 assert(n == sizeof(ret));
471 ret = kill(pid, SIGUSR1);
474 n = read(fd[0], &ret, sizeof(ret));
475 assert(n == sizeof(ret));
478 ret = kill(pid, SIGHUP);
481 n = read(fd[0], &ret, sizeof(ret));
482 assert(n == sizeof(ret));
485 ret = kill(pid, SIGTERM);
488 n = read(fd[0], &ret, sizeof(ret));
489 assert(n == sizeof(ret));
492 pid2 = waitpid(pid, &ret, 0);
494 assert(WEXITSTATUS(ret) == 0);
502 * Start daemon, test watching of (parent) PID
505 static void test3(TALLOC_CTX *mem_ctx, const char *pidfile,
506 const char *sockpath)
509 pid_t pid_watch, pid, pid2;
513 assert(pid_watch != -1);
515 if (pid_watch == 0) {
524 struct tevent_context *ev;
525 struct sock_daemon_context *sockd;
527 ev = tevent_context_init(mem_ctx);
530 ret = sock_daemon_setup(mem_ctx, "test3", "file:", "NOTICE",
534 ret = sock_daemon_add_unix(sockd, sockpath,
535 &dummy_socket_funcs, NULL);
538 ret = sock_daemon_run(ev, sockd, NULL, false, false, pid_watch);
539 assert(ret == ESRCH);
544 pid2 = waitpid(pid_watch, &ret, 0);
545 assert(pid2 == pid_watch);
546 assert(WEXITSTATUS(ret) == 0);
548 pid2 = waitpid(pid, &ret, 0);
550 assert(WEXITSTATUS(ret) == 0);
552 ret = stat(pidfile, &st);
555 ret = stat(sockpath, &st);
562 * Start daemon, test termination via wait_send function
565 struct test4_wait_state {
568 static void test4_wait_done(struct tevent_req *subreq);
570 static struct tevent_req *test4_wait_send(TALLOC_CTX *mem_ctx,
571 struct tevent_context *ev,
574 struct tevent_req *req, *subreq;
575 struct test4_wait_state *state;
577 req = tevent_req_create(mem_ctx, &state, struct test4_wait_state);
582 subreq = tevent_wakeup_send(state, ev,
583 tevent_timeval_current_ofs(10,0));
584 if (tevent_req_nomem(subreq, req)) {
585 return tevent_req_post(req, ev);
587 tevent_req_set_callback(subreq, test4_wait_done, req);
592 static void test4_wait_done(struct tevent_req *subreq)
594 struct tevent_req *req = tevent_req_callback_data(
595 subreq, struct tevent_req);
598 status = tevent_wakeup_recv(subreq);
602 tevent_req_error(req, EIO);
604 tevent_req_done(req);
608 static bool test4_wait_recv(struct tevent_req *req, int *perr)
612 if (tevent_req_is_unix_error(req, &ret)) {
622 static struct sock_daemon_funcs test4_funcs = {
623 .wait_send = test4_wait_send,
624 .wait_recv = test4_wait_recv,
627 static void test4(TALLOC_CTX *mem_ctx, const char *pidfile,
628 const char *sockpath)
638 struct tevent_context *ev;
639 struct sock_daemon_context *sockd;
641 ev = tevent_context_init(mem_ctx);
644 ret = sock_daemon_setup(mem_ctx, "test4", "file:", "NOTICE",
645 &test4_funcs, NULL, &sockd);
648 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
654 pid2 = waitpid(pid, &ret, 0);
656 assert(WEXITSTATUS(ret) == 0);
658 ret = stat(pidfile, &st);
661 ret = stat(sockpath, &st);
668 * Start daemon, multiple client connects, requests, disconnects
671 #define TEST5_MAX_CLIENTS 10
678 struct test5_client_state {
684 static void test5_client_callback(uint8_t *buf, size_t buflen,
687 struct test5_client_state *state =
688 (struct test5_client_state *)private_data;
689 struct test5_pkt *pkt;
698 assert(buflen == sizeof(struct test5_pkt));
699 pkt = (struct test5_pkt *)buf;
700 assert(pkt->len == sizeof(struct test5_pkt));
705 assert(state->fd != -1);
707 n = write(state->fd, (void *)&ret, sizeof(int));
708 assert(n == sizeof(int));
713 static int test5_client(const char *sockpath, int id)
727 struct tevent_context *ev;
728 struct test5_client_state state;
729 struct sock_queue *queue;
730 struct test5_pkt pkt;
735 ev = tevent_context_init(NULL);
738 conn = sock_connect(sockpath);
745 queue = sock_queue_setup(ev, ev, conn,
746 test5_client_callback, &state);
747 assert(queue != NULL);
752 ret = sock_queue_write(queue, (uint8_t *)&pkt,
753 sizeof(struct test5_pkt));
756 while (! state.done) {
757 tevent_loop_once(ev);
770 n = read(fd[0], &ret, sizeof(ret));
772 fprintf(stderr, "client id %d read 0 bytes\n", id);
774 assert(n == 0 || n == sizeof(ret));
781 struct test5_server_state {
785 static bool test5_connect(struct sock_client_context *client,
788 struct test5_server_state *state =
789 (struct test5_server_state *)private_data;
791 if (state->num_clients == TEST5_MAX_CLIENTS) {
795 state->num_clients += 1;
796 assert(state->num_clients <= TEST5_MAX_CLIENTS);
800 static void test5_disconnect(struct sock_client_context *client,
803 struct test5_server_state *state =
804 (struct test5_server_state *)private_data;
806 state->num_clients -= 1;
807 assert(state->num_clients >= 0);
810 struct test5_read_state {
811 struct test5_pkt reply;
814 static void test5_read_done(struct tevent_req *subreq);
816 static struct tevent_req *test5_read_send(TALLOC_CTX *mem_ctx,
817 struct tevent_context *ev,
818 struct sock_client_context *client,
819 uint8_t *buf, size_t buflen,
822 struct test5_server_state *server_state =
823 (struct test5_server_state *)private_data;
824 struct tevent_req *req, *subreq;
825 struct test5_read_state *state;
826 struct test5_pkt *pkt;
828 req = tevent_req_create(mem_ctx, &state, struct test5_read_state);
831 assert(buflen == sizeof(struct test5_pkt));
833 pkt = (struct test5_pkt *)buf;
834 assert(pkt->data == 0xbaba);
836 state->reply.len = sizeof(struct test5_pkt);
837 state->reply.data = server_state->num_clients;
839 subreq = sock_socket_write_send(state, ev, client,
840 (uint8_t *)&state->reply,
842 assert(subreq != NULL);
844 tevent_req_set_callback(subreq, test5_read_done, req);
849 static void test5_read_done(struct tevent_req *subreq)
851 struct tevent_req *req = tevent_req_callback_data(
852 subreq, struct tevent_req);
856 status = sock_socket_write_recv(subreq, &ret);
859 tevent_req_error(req, ret);
863 tevent_req_done(req);
866 static bool test5_read_recv(struct tevent_req *req, int *perr)
870 if (tevent_req_is_unix_error(req, &ret)) {
880 static struct sock_socket_funcs test5_client_funcs = {
881 .connect = test5_connect,
882 .disconnect = test5_disconnect,
883 .read_send = test5_read_send,
884 .read_recv = test5_read_recv,
887 struct test5_wait_state {
890 static struct tevent_req *test5_wait_send(TALLOC_CTX *mem_ctx,
891 struct tevent_context *ev,
894 struct tevent_req *req;
895 struct test5_wait_state *state;
896 int fd = *(int *)private_data;
900 nwritten = write(fd, &ret, sizeof(ret));
901 assert(nwritten == sizeof(ret));
904 req = tevent_req_create(mem_ctx, &state, struct test5_wait_state);
912 static bool test5_wait_recv(struct tevent_req *req, int *perr)
917 static struct sock_daemon_funcs test5_funcs = {
918 .wait_send = test5_wait_send,
919 .wait_recv = test5_wait_recv,
922 static void test5(TALLOC_CTX *mem_ctx, const char *pidfile,
923 const char *sockpath)
925 pid_t pid_server, pid;
935 assert(pid_server != -1);
937 if (pid_server == 0) {
938 struct tevent_context *ev;
939 struct sock_daemon_context *sockd;
940 struct test5_server_state state;
944 ev = tevent_context_init(mem_ctx);
947 ret = sock_daemon_setup(mem_ctx, "test5", "file:", "NOTICE",
948 &test5_funcs, &fd[1], &sockd);
951 state.num_clients = 0;
953 ret = sock_daemon_add_unix(sockd, sockpath,
954 &test5_client_funcs, &state);
957 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
958 assert(ret == EINTR);
965 n = read(fd[0], &ret, sizeof(ret));
966 assert(n == sizeof(ret));
971 for (i=0; i<100; i++) {
972 ret = test5_client(sockpath, i);
973 if (i < TEST5_MAX_CLIENTS) {
980 for (i=0; i<100; i++) {
985 ret = kill(pid_server, SIGTERM);
992 * Start daemon, test client connects, requests, replies, disconnects
1000 struct test6_client_state {
1004 static void test6_client_callback(uint8_t *buf, size_t buflen,
1007 struct test6_client_state *state =
1008 (struct test6_client_state *)private_data;
1009 struct test6_pkt *pkt;
1011 assert(buflen == sizeof(struct test6_pkt));
1012 pkt = (struct test6_pkt *)buf;
1013 assert(pkt->len == sizeof(struct test6_pkt));
1014 assert(pkt->data == 0xffeeddcc);
1019 static void test6_client(const char *sockpath)
1021 struct tevent_context *ev;
1022 struct test6_client_state state;
1023 struct sock_queue *queue;
1024 struct test6_pkt pkt;
1027 ev = tevent_context_init(NULL);
1030 conn = sock_connect(sockpath);
1035 queue = sock_queue_setup(ev, ev, conn,
1036 test6_client_callback, &state);
1037 assert(queue != NULL);
1040 pkt.data = 0xaabbccdd;
1042 ret = sock_queue_write(queue, (uint8_t *)&pkt,
1043 sizeof(struct test6_pkt));
1046 while (! state.done) {
1047 tevent_loop_once(ev);
1053 struct test6_server_state {
1054 struct sock_daemon_context *sockd;
1058 struct test6_read_state {
1059 struct test6_server_state *server_state;
1060 struct test6_pkt reply;
1063 static void test6_read_done(struct tevent_req *subreq);
1065 static struct tevent_req *test6_read_send(TALLOC_CTX *mem_ctx,
1066 struct tevent_context *ev,
1067 struct sock_client_context *client,
1068 uint8_t *buf, size_t buflen,
1071 struct test6_server_state *server_state =
1072 (struct test6_server_state *)private_data;
1073 struct tevent_req *req, *subreq;
1074 struct test6_read_state *state;
1075 struct test6_pkt *pkt;
1077 req = tevent_req_create(mem_ctx, &state, struct test6_read_state);
1078 assert(req != NULL);
1080 state->server_state = server_state;
1082 assert(buflen == sizeof(struct test6_pkt));
1084 pkt = (struct test6_pkt *)buf;
1085 assert(pkt->data == 0xaabbccdd);
1087 state->reply.len = sizeof(struct test6_pkt);
1088 state->reply.data = 0xffeeddcc;
1090 subreq = sock_socket_write_send(state, ev, client,
1091 (uint8_t *)&state->reply,
1093 assert(subreq != NULL);
1095 tevent_req_set_callback(subreq, test6_read_done, req);
1100 static void test6_read_done(struct tevent_req *subreq)
1102 struct tevent_req *req = tevent_req_callback_data(
1103 subreq, struct tevent_req);
1104 struct test6_read_state *state = tevent_req_data(
1105 req, struct test6_read_state);
1109 status = sock_socket_write_recv(subreq, &ret);
1110 TALLOC_FREE(subreq);
1112 tevent_req_error(req, ret);
1116 state->server_state->done = 1;
1117 tevent_req_done(req);
1120 static bool test6_read_recv(struct tevent_req *req, int *perr)
1124 if (tevent_req_is_unix_error(req, &ret)) {
1134 static struct sock_socket_funcs test6_client_funcs = {
1135 .read_send = test6_read_send,
1136 .read_recv = test6_read_recv,
1139 struct test6_wait_state {
1140 struct test6_server_state *server_state;
1143 static void test6_wait_done(struct tevent_req *subreq);
1145 static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx,
1146 struct tevent_context *ev,
1149 struct test6_server_state *server_state =
1150 (struct test6_server_state *)private_data;
1151 struct tevent_req *req, *subreq;
1152 struct test6_wait_state *state;
1156 nwritten = write(server_state->fd, &ret, sizeof(ret));
1157 assert(nwritten == sizeof(ret));
1158 close(server_state->fd);
1159 server_state->fd = -1;
1161 req = tevent_req_create(mem_ctx, &state, struct test6_wait_state);
1166 state->server_state = (struct test6_server_state *)private_data;
1168 subreq = tevent_wakeup_send(state, ev,
1169 tevent_timeval_current_ofs(10,0));
1170 if (tevent_req_nomem(subreq, req)) {
1171 return tevent_req_post(req, ev);
1173 tevent_req_set_callback(subreq, test6_wait_done, req);
1178 static void test6_wait_done(struct tevent_req *subreq)
1180 struct tevent_req *req = tevent_req_callback_data(
1181 subreq, struct tevent_req);
1182 struct test6_wait_state *state = tevent_req_data(
1183 req, struct test6_wait_state);
1186 status = tevent_wakeup_recv(subreq);
1187 TALLOC_FREE(subreq);
1189 tevent_req_error(req, EIO);
1193 if (state->server_state->done == 0) {
1194 tevent_req_error(req, EIO);
1198 tevent_req_done(req);
1201 static bool test6_wait_recv(struct tevent_req *req, int *perr)
1205 if (tevent_req_is_unix_error(req, &ret)) {
1215 static struct sock_daemon_funcs test6_funcs = {
1216 .wait_send = test6_wait_send,
1217 .wait_recv = test6_wait_recv,
1220 static void test6(TALLOC_CTX *mem_ctx, const char *pidfile,
1221 const char *sockpath)
1223 pid_t pid_server, pid;
1232 pid_server = fork();
1233 assert(pid_server != -1);
1235 if (pid_server == 0) {
1236 struct tevent_context *ev;
1237 struct sock_daemon_context *sockd;
1238 struct test6_server_state server_state = { 0 };
1242 ev = tevent_context_init(mem_ctx);
1245 server_state.fd = fd[1];
1247 ret = sock_daemon_setup(mem_ctx, "test6", "file:", "NOTICE",
1248 &test6_funcs, &server_state,
1252 server_state.sockd = sockd;
1253 server_state.done = 0;
1255 ret = sock_daemon_add_unix(sockd, sockpath,
1256 &test6_client_funcs, &server_state);
1259 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
1267 n = read(fd[0], &ret, sizeof(ret));
1268 assert(n == sizeof(ret));
1273 test6_client(sockpath);
1282 * Start daemon twice, confirm PID file contention
1285 static void test7(TALLOC_CTX *mem_ctx, const char *pidfile,
1286 const char *sockpath)
1288 struct sock_daemon_funcs test7_funcs;
1293 struct tevent_context *ev;
1294 struct sock_daemon_context *sockd;
1297 /* Reuse test2 funcs for the startup synchronisation */
1298 test7_funcs = (struct sock_daemon_funcs) {
1299 .startup = test2_startup,
1300 .reconfigure = test2_reconfigure,
1301 .shutdown = test2_shutdown,
1313 ev = tevent_context_init(mem_ctx);
1316 ret = sock_daemon_setup(mem_ctx, "test7", "file:", "NOTICE",
1317 &test7_funcs, &fd[1], &sockd);
1320 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1321 assert(ret == EINTR);
1328 n = read(fd[0], &ret, sizeof(ret));
1329 assert(n == sizeof(ret));
1332 ret = stat(pidfile, &st);
1334 assert(S_ISREG(st.st_mode));
1336 ev = tevent_context_init(mem_ctx);
1339 ret = sock_daemon_setup(mem_ctx, "test7-parent", "file:", "NOTICE",
1340 &test7_funcs, &fd[1], &sockd);
1343 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1344 assert(ret == EEXIST);
1346 ret = kill(pid, SIGTERM);
1349 n = read(fd[0], &ret, sizeof(ret));
1350 assert(n == sizeof(ret));
1353 pid2 = waitpid(pid, &ret, 0);
1354 assert(pid2 == pid);
1355 assert(WEXITSTATUS(ret) == 0);
1363 * Start daemon, confirm that create_session argument works as expected
1366 static void test8(TALLOC_CTX *mem_ctx, const char *pidfile,
1367 const char *sockpath)
1370 pid_t pid, pid2, sid;
1372 struct tevent_context *ev;
1373 struct sock_daemon_context *sockd;
1383 /* Reuse test2 funcs for the startup synchronisation */
1384 struct sock_daemon_funcs test8_funcs = {
1385 .startup = test2_startup,
1390 ev = tevent_context_init(mem_ctx);
1393 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1394 &test8_funcs, &fd[1], &sockd);
1397 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1398 assert(ret == EINTR);
1405 n = read(fd[0], &ret, sizeof(ret));
1406 assert(n == sizeof(ret));
1409 /* create_session false above, so pid != sid */
1413 ret = kill(pid, SIGTERM);
1416 pid2 = waitpid(pid, &ret, 0);
1417 assert(pid2 == pid);
1418 assert(WEXITSTATUS(ret) == 0);
1429 /* Reuse test2 funcs for the startup synchronisation */
1430 struct sock_daemon_funcs test8_funcs = {
1431 .startup = test2_startup,
1436 ev = tevent_context_init(mem_ctx);
1439 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1440 &test8_funcs, &fd[1], &sockd);
1443 ret = sock_daemon_run(ev, sockd, pidfile, false, true, -1);
1444 assert(ret == EINTR);
1451 n = read(fd[0], &ret, sizeof(ret));
1452 assert(n == sizeof(ret));
1455 /* create_session true above, so pid == sid */
1459 ret = kill(pid, SIGTERM);
1462 pid2 = waitpid(pid, &ret, 0);
1463 assert(pid2 == pid);
1464 assert(WEXITSTATUS(ret) == 0);
1472 * Confirm that do_fork causes the daemon to be forked as a separate child
1475 static void test9(TALLOC_CTX *mem_ctx, const char *pidfile,
1476 const char *sockpath)
1481 struct tevent_context *ev;
1482 struct sock_daemon_context *sockd;
1485 char pidstr[20] = { 0 };
1495 /* Reuse test2 funcs for the startup synchronisation */
1496 struct sock_daemon_funcs test9_funcs = {
1497 .startup = test2_startup,
1502 ev = tevent_context_init(mem_ctx);
1505 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1506 &test9_funcs, &fd[1], &sockd);
1509 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1510 assert(ret == EINTR);
1517 n = read(fd[0], &ret, sizeof(ret));
1518 assert(n == sizeof(ret));
1521 /* do_fork false above, so pid should be active */
1525 ret = kill(pid, SIGTERM);
1528 pid2 = waitpid(pid, &ret, 0);
1529 assert(pid2 == pid);
1530 assert(WEXITSTATUS(ret) == 0);
1541 /* Reuse test2 funcs for the startup synchronisation */
1542 struct sock_daemon_funcs test9_funcs = {
1543 .startup = test2_startup,
1544 .shutdown = test2_shutdown,
1549 ev = tevent_context_init(mem_ctx);
1552 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1553 &test9_funcs, &fd[1], &sockd);
1556 ret = sock_daemon_run(ev, sockd, pidfile, true, false, -1);
1557 assert(ret == EINTR);
1564 n = read(fd[0], &ret, sizeof(ret));
1565 assert(n == sizeof(ret));
1568 /* do_fork true above, so pid should have exited */
1569 pid2 = waitpid(pid, &ret, 0);
1570 assert(pid2 == pid);
1571 assert(WEXITSTATUS(ret) == 0);
1573 pidfile_fd = open(pidfile, O_RDONLY, 0644);
1574 assert(pidfile_fd != -1);
1575 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1577 pid2 = (pid_t)atoi(pidstr);
1578 assert(pid != pid2);
1581 ret = kill(pid2, SIGTERM);
1584 n = read(fd[0], &ret, sizeof(ret));
1585 assert(n == sizeof(ret));
1589 * pid2 isn't our child, so can't call waitpid(). kill(pid2, 0)
1590 * is unreliable - pid2 may have been recycled. Above indicates
1591 * that the shutdown function was called, so just do 1 final
1592 * check to see if pidfile has been removed.
1594 ret = stat(sockpath, &st);
1600 static void test10_shutdown(void *private_data)
1602 int fd = *(int *)private_data;
1606 nwritten = write(fd, &ret, sizeof(ret));
1607 assert(nwritten == sizeof(ret));
1610 struct test10_wait_state {
1613 static void test10_wait_done(struct tevent_req *subreq);
1615 static struct tevent_req *test10_wait_send(TALLOC_CTX *mem_ctx,
1616 struct tevent_context *ev,
1619 int fd = *(int *)private_data;
1620 struct tevent_req *req, *subreq;
1621 struct test10_wait_state *state;
1625 req = tevent_req_create(mem_ctx, &state, struct test10_wait_state);
1630 subreq = tevent_wakeup_send(state, ev,
1631 tevent_timeval_current_ofs(10, 0));
1632 if (tevent_req_nomem(subreq, req)) {
1633 return tevent_req_post(req, ev);
1635 tevent_req_set_callback(subreq, test10_wait_done, req);
1637 nwritten = write(fd, &ret, sizeof(ret));
1638 assert(nwritten == sizeof(ret));
1643 static void test10_wait_done(struct tevent_req *subreq)
1645 struct tevent_req *req = tevent_req_callback_data(
1646 subreq, struct tevent_req);
1649 status = tevent_wakeup_recv(subreq);
1651 tevent_req_error(req, EIO);
1655 tevent_req_done(req);
1658 static bool test10_wait_recv(struct tevent_req *req, int *perr)
1662 if (tevent_req_is_unix_error(req, &ret)) {
1672 static struct sock_daemon_funcs test10_funcs = {
1673 .shutdown = test10_shutdown,
1674 .wait_send = test10_wait_send,
1675 .wait_recv = test10_wait_recv,
1681 * Confirm that the daemon starts successfully if there is a stale socket
1684 static void test10(TALLOC_CTX *mem_ctx, const char *pidfile,
1685 const char *sockpath)
1693 char pidstr[20] = { 0 };
1702 struct tevent_context *ev;
1703 struct sock_daemon_context *sockd;
1707 ev = tevent_context_init(mem_ctx);
1710 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1711 &test10_funcs, &fd[1], &sockd);
1714 ret = sock_daemon_add_unix(sockd, sockpath,
1715 &dummy_socket_funcs, NULL);
1718 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1719 assert(ret == EINTR);
1726 n = read(fd[0], &ret, sizeof(ret));
1727 assert(n == sizeof(ret));
1730 /* KILL will leave PID file and socket behind */
1731 ret = kill (pid, SIGKILL);
1734 ret = stat(sockpath, &st);
1746 struct tevent_context *ev;
1747 struct sock_daemon_context *sockd;
1751 ev = tevent_context_init(mem_ctx);
1754 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1755 &test10_funcs, &fd[1], &sockd);
1758 ret = sock_daemon_add_unix(sockd, sockpath,
1759 &dummy_socket_funcs, NULL);
1762 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1763 assert(ret == EINTR);
1770 n = read(fd[0], &ret, sizeof(ret));
1771 assert(n == sizeof(ret));
1774 pidfile_fd = open(pidfile, O_RDONLY, 0644);
1775 assert(pidfile_fd != -1);
1776 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1778 pid2 = (pid_t)atoi(pidstr);
1779 assert(pid == pid2);
1782 ret = kill(pid, SIGTERM);
1785 n = read(fd[0], &ret, sizeof(ret));
1786 assert(n == sizeof(ret));
1789 pid2 = waitpid(pid, &ret, 0);
1790 assert(pid2 == pid);
1791 assert(WEXITSTATUS(ret) == 0);
1795 ret = stat(pidfile, &st);
1798 ret = stat(sockpath, &st);
1802 int main(int argc, const char **argv)
1804 TALLOC_CTX *mem_ctx;
1805 const char *pidfile, *sockpath;
1809 fprintf(stderr, "%s <pidfile> <sockpath> <testnum>\n", argv[0]);
1815 num = atoi(argv[3]);
1817 mem_ctx = talloc_new(NULL);
1818 assert(mem_ctx != NULL);
1822 test1(mem_ctx, pidfile, sockpath);
1826 test2(mem_ctx, pidfile, sockpath);
1830 test3(mem_ctx, pidfile, sockpath);
1834 test4(mem_ctx, pidfile, sockpath);
1838 test5(mem_ctx, pidfile, sockpath);
1842 test6(mem_ctx, pidfile, sockpath);
1846 test7(mem_ctx, pidfile, sockpath);
1850 test8(mem_ctx, pidfile, sockpath);
1854 test9(mem_ctx, pidfile, sockpath);
1858 test10(mem_ctx, pidfile, sockpath);
1862 fprintf(stderr, "Unknown test number %d\n", num);