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
);
988 pid
= waitpid(pid_server
, &ret
, 0);
989 assert(pid
== pid_server
);
990 assert(WEXITSTATUS(ret
) == 0);
996 * Start daemon, test client connects, requests, replies, disconnects
1004 struct test6_client_state
{
1008 static void test6_client_callback(uint8_t *buf
, size_t buflen
,
1011 struct test6_client_state
*state
=
1012 (struct test6_client_state
*)private_data
;
1013 struct test6_pkt
*pkt
;
1015 assert(buflen
== sizeof(struct test6_pkt
));
1016 pkt
= (struct test6_pkt
*)buf
;
1017 assert(pkt
->len
== sizeof(struct test6_pkt
));
1018 assert(pkt
->data
== 0xffeeddcc);
1023 static void test6_client(const char *sockpath
)
1025 struct tevent_context
*ev
;
1026 struct test6_client_state state
;
1027 struct sock_queue
*queue
;
1028 struct test6_pkt pkt
;
1031 ev
= tevent_context_init(NULL
);
1034 conn
= sock_connect(sockpath
);
1039 queue
= sock_queue_setup(ev
, ev
, conn
,
1040 test6_client_callback
, &state
);
1041 assert(queue
!= NULL
);
1044 pkt
.data
= 0xaabbccdd;
1046 ret
= sock_queue_write(queue
, (uint8_t *)&pkt
,
1047 sizeof(struct test6_pkt
));
1050 while (! state
.done
) {
1051 tevent_loop_once(ev
);
1057 struct test6_server_state
{
1058 struct sock_daemon_context
*sockd
;
1062 struct test6_read_state
{
1063 struct test6_server_state
*server_state
;
1064 struct test6_pkt reply
;
1067 static void test6_read_done(struct tevent_req
*subreq
);
1069 static struct tevent_req
*test6_read_send(TALLOC_CTX
*mem_ctx
,
1070 struct tevent_context
*ev
,
1071 struct sock_client_context
*client
,
1072 uint8_t *buf
, size_t buflen
,
1075 struct test6_server_state
*server_state
=
1076 (struct test6_server_state
*)private_data
;
1077 struct tevent_req
*req
, *subreq
;
1078 struct test6_read_state
*state
;
1079 struct test6_pkt
*pkt
;
1081 req
= tevent_req_create(mem_ctx
, &state
, struct test6_read_state
);
1082 assert(req
!= NULL
);
1084 state
->server_state
= server_state
;
1086 assert(buflen
== sizeof(struct test6_pkt
));
1088 pkt
= (struct test6_pkt
*)buf
;
1089 assert(pkt
->data
== 0xaabbccdd);
1091 state
->reply
.len
= sizeof(struct test6_pkt
);
1092 state
->reply
.data
= 0xffeeddcc;
1094 subreq
= sock_socket_write_send(state
, ev
, client
,
1095 (uint8_t *)&state
->reply
,
1097 assert(subreq
!= NULL
);
1099 tevent_req_set_callback(subreq
, test6_read_done
, req
);
1104 static void test6_read_done(struct tevent_req
*subreq
)
1106 struct tevent_req
*req
= tevent_req_callback_data(
1107 subreq
, struct tevent_req
);
1108 struct test6_read_state
*state
= tevent_req_data(
1109 req
, struct test6_read_state
);
1113 status
= sock_socket_write_recv(subreq
, &ret
);
1114 TALLOC_FREE(subreq
);
1116 tevent_req_error(req
, ret
);
1120 state
->server_state
->done
= 1;
1121 tevent_req_done(req
);
1124 static bool test6_read_recv(struct tevent_req
*req
, int *perr
)
1128 if (tevent_req_is_unix_error(req
, &ret
)) {
1138 static struct sock_socket_funcs test6_client_funcs
= {
1139 .read_send
= test6_read_send
,
1140 .read_recv
= test6_read_recv
,
1143 struct test6_wait_state
{
1144 struct test6_server_state
*server_state
;
1147 static void test6_wait_done(struct tevent_req
*subreq
);
1149 static struct tevent_req
*test6_wait_send(TALLOC_CTX
*mem_ctx
,
1150 struct tevent_context
*ev
,
1153 struct test6_server_state
*server_state
=
1154 (struct test6_server_state
*)private_data
;
1155 struct tevent_req
*req
, *subreq
;
1156 struct test6_wait_state
*state
;
1160 nwritten
= write(server_state
->fd
, &ret
, sizeof(ret
));
1161 assert(nwritten
== sizeof(ret
));
1162 close(server_state
->fd
);
1163 server_state
->fd
= -1;
1165 req
= tevent_req_create(mem_ctx
, &state
, struct test6_wait_state
);
1170 state
->server_state
= (struct test6_server_state
*)private_data
;
1172 subreq
= tevent_wakeup_send(state
, ev
,
1173 tevent_timeval_current_ofs(10,0));
1174 if (tevent_req_nomem(subreq
, req
)) {
1175 return tevent_req_post(req
, ev
);
1177 tevent_req_set_callback(subreq
, test6_wait_done
, req
);
1182 static void test6_wait_done(struct tevent_req
*subreq
)
1184 struct tevent_req
*req
= tevent_req_callback_data(
1185 subreq
, struct tevent_req
);
1186 struct test6_wait_state
*state
= tevent_req_data(
1187 req
, struct test6_wait_state
);
1190 status
= tevent_wakeup_recv(subreq
);
1191 TALLOC_FREE(subreq
);
1193 tevent_req_error(req
, EIO
);
1197 if (state
->server_state
->done
== 0) {
1198 tevent_req_error(req
, EIO
);
1202 tevent_req_done(req
);
1205 static bool test6_wait_recv(struct tevent_req
*req
, int *perr
)
1209 if (tevent_req_is_unix_error(req
, &ret
)) {
1219 static struct sock_daemon_funcs test6_funcs
= {
1220 .wait_send
= test6_wait_send
,
1221 .wait_recv
= test6_wait_recv
,
1224 static void test6(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1225 const char *sockpath
)
1227 pid_t pid_server
, pid
;
1236 pid_server
= fork();
1237 assert(pid_server
!= -1);
1239 if (pid_server
== 0) {
1240 struct tevent_context
*ev
;
1241 struct sock_daemon_context
*sockd
;
1242 struct test6_server_state server_state
= { 0 };
1246 ev
= tevent_context_init(mem_ctx
);
1249 server_state
.fd
= fd
[1];
1251 ret
= sock_daemon_setup(mem_ctx
, "test6", "file:", "NOTICE",
1252 &test6_funcs
, &server_state
,
1256 server_state
.sockd
= sockd
;
1257 server_state
.done
= 0;
1259 ret
= sock_daemon_add_unix(sockd
, sockpath
,
1260 &test6_client_funcs
, &server_state
);
1263 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, pid
);
1271 n
= read(fd
[0], &ret
, sizeof(ret
));
1272 assert(n
== sizeof(ret
));
1277 test6_client(sockpath
);
1279 pid
= waitpid(pid_server
, &ret
, 0);
1280 assert(pid
== pid_server
);
1281 assert(WEXITSTATUS(ret
) == 0);
1287 * Start daemon twice, confirm PID file contention
1290 static void test7(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1291 const char *sockpath
)
1293 struct sock_daemon_funcs test7_funcs
;
1298 struct tevent_context
*ev
;
1299 struct sock_daemon_context
*sockd
;
1302 /* Reuse test2 funcs for the startup synchronisation */
1303 test7_funcs
= (struct sock_daemon_funcs
) {
1304 .startup
= test2_startup
,
1305 .reconfigure
= test2_reconfigure
,
1306 .shutdown
= test2_shutdown
,
1318 ev
= tevent_context_init(mem_ctx
);
1321 ret
= sock_daemon_setup(mem_ctx
, "test7", "file:", "NOTICE",
1322 &test7_funcs
, &fd
[1], &sockd
);
1325 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1326 assert(ret
== EINTR
);
1333 n
= read(fd
[0], &ret
, sizeof(ret
));
1334 assert(n
== sizeof(ret
));
1337 ret
= stat(pidfile
, &st
);
1339 assert(S_ISREG(st
.st_mode
));
1341 ev
= tevent_context_init(mem_ctx
);
1344 ret
= sock_daemon_setup(mem_ctx
, "test7-parent", "file:", "NOTICE",
1345 &test7_funcs
, &fd
[1], &sockd
);
1348 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1349 assert(ret
== EEXIST
);
1351 ret
= kill(pid
, SIGTERM
);
1354 n
= read(fd
[0], &ret
, sizeof(ret
));
1355 assert(n
== sizeof(ret
));
1358 pid2
= waitpid(pid
, &ret
, 0);
1359 assert(pid2
== pid
);
1360 assert(WEXITSTATUS(ret
) == 0);
1368 * Start daemon, confirm that create_session argument works as expected
1371 static void test8(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1372 const char *sockpath
)
1375 pid_t pid
, pid2
, sid
;
1377 struct tevent_context
*ev
;
1378 struct sock_daemon_context
*sockd
;
1388 /* Reuse test2 funcs for the startup synchronisation */
1389 struct sock_daemon_funcs test8_funcs
= {
1390 .startup
= test2_startup
,
1395 ev
= tevent_context_init(mem_ctx
);
1398 ret
= sock_daemon_setup(mem_ctx
, "test8", "file:", "NOTICE",
1399 &test8_funcs
, &fd
[1], &sockd
);
1402 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1403 assert(ret
== EINTR
);
1410 n
= read(fd
[0], &ret
, sizeof(ret
));
1411 assert(n
== sizeof(ret
));
1414 /* create_session false above, so pid != sid */
1418 ret
= kill(pid
, SIGTERM
);
1421 pid2
= waitpid(pid
, &ret
, 0);
1422 assert(pid2
== pid
);
1423 assert(WEXITSTATUS(ret
) == 0);
1434 /* Reuse test2 funcs for the startup synchronisation */
1435 struct sock_daemon_funcs test8_funcs
= {
1436 .startup
= test2_startup
,
1441 ev
= tevent_context_init(mem_ctx
);
1444 ret
= sock_daemon_setup(mem_ctx
, "test8", "file:", "NOTICE",
1445 &test8_funcs
, &fd
[1], &sockd
);
1448 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, true, -1);
1449 assert(ret
== EINTR
);
1456 n
= read(fd
[0], &ret
, sizeof(ret
));
1457 assert(n
== sizeof(ret
));
1460 /* create_session true above, so pid == sid */
1464 ret
= kill(pid
, SIGTERM
);
1467 pid2
= waitpid(pid
, &ret
, 0);
1468 assert(pid2
== pid
);
1469 assert(WEXITSTATUS(ret
) == 0);
1477 * Confirm that do_fork causes the daemon to be forked as a separate child
1480 static void test9(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1481 const char *sockpath
)
1486 struct tevent_context
*ev
;
1487 struct sock_daemon_context
*sockd
;
1490 char pidstr
[20] = { 0 };
1500 /* Reuse test2 funcs for the startup synchronisation */
1501 struct sock_daemon_funcs test9_funcs
= {
1502 .startup
= test2_startup
,
1507 ev
= tevent_context_init(mem_ctx
);
1510 ret
= sock_daemon_setup(mem_ctx
, "test9", "file:", "NOTICE",
1511 &test9_funcs
, &fd
[1], &sockd
);
1514 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1515 assert(ret
== EINTR
);
1522 n
= read(fd
[0], &ret
, sizeof(ret
));
1523 assert(n
== sizeof(ret
));
1526 /* do_fork false above, so pid should be active */
1530 ret
= kill(pid
, SIGTERM
);
1533 pid2
= waitpid(pid
, &ret
, 0);
1534 assert(pid2
== pid
);
1535 assert(WEXITSTATUS(ret
) == 0);
1546 /* Reuse test2 funcs for the startup synchronisation */
1547 struct sock_daemon_funcs test9_funcs
= {
1548 .startup
= test2_startup
,
1549 .shutdown
= test2_shutdown
,
1554 ev
= tevent_context_init(mem_ctx
);
1557 ret
= sock_daemon_setup(mem_ctx
, "test9", "file:", "NOTICE",
1558 &test9_funcs
, &fd
[1], &sockd
);
1561 ret
= sock_daemon_run(ev
, sockd
, pidfile
, true, false, -1);
1562 assert(ret
== EINTR
);
1569 n
= read(fd
[0], &ret
, sizeof(ret
));
1570 assert(n
== sizeof(ret
));
1573 /* do_fork true above, so pid should have exited */
1574 pid2
= waitpid(pid
, &ret
, 0);
1575 assert(pid2
== pid
);
1576 assert(WEXITSTATUS(ret
) == 0);
1578 pidfile_fd
= open(pidfile
, O_RDONLY
, 0644);
1579 assert(pidfile_fd
!= -1);
1580 n
= read(pidfile_fd
, pidstr
, sizeof(pidstr
)-1);
1582 pid2
= (pid_t
)atoi(pidstr
);
1583 assert(pid
!= pid2
);
1586 ret
= kill(pid2
, SIGTERM
);
1589 n
= read(fd
[0], &ret
, sizeof(ret
));
1590 assert(n
== sizeof(ret
));
1594 * pid2 isn't our child, so can't call waitpid(). kill(pid2, 0)
1595 * is unreliable - pid2 may have been recycled. Above indicates
1596 * that the shutdown function was called, so just do 1 final
1597 * check to see if pidfile has been removed.
1599 ret
= stat(sockpath
, &st
);
1605 static void test10_shutdown(void *private_data
)
1607 int fd
= *(int *)private_data
;
1611 nwritten
= write(fd
, &ret
, sizeof(ret
));
1612 assert(nwritten
== sizeof(ret
));
1615 struct test10_wait_state
{
1618 static void test10_wait_done(struct tevent_req
*subreq
);
1620 static struct tevent_req
*test10_wait_send(TALLOC_CTX
*mem_ctx
,
1621 struct tevent_context
*ev
,
1624 int fd
= *(int *)private_data
;
1625 struct tevent_req
*req
, *subreq
;
1626 struct test10_wait_state
*state
;
1630 req
= tevent_req_create(mem_ctx
, &state
, struct test10_wait_state
);
1635 subreq
= tevent_wakeup_send(state
, ev
,
1636 tevent_timeval_current_ofs(10, 0));
1637 if (tevent_req_nomem(subreq
, req
)) {
1638 return tevent_req_post(req
, ev
);
1640 tevent_req_set_callback(subreq
, test10_wait_done
, req
);
1642 nwritten
= write(fd
, &ret
, sizeof(ret
));
1643 assert(nwritten
== sizeof(ret
));
1648 static void test10_wait_done(struct tevent_req
*subreq
)
1650 struct tevent_req
*req
= tevent_req_callback_data(
1651 subreq
, struct tevent_req
);
1654 status
= tevent_wakeup_recv(subreq
);
1656 tevent_req_error(req
, EIO
);
1660 tevent_req_done(req
);
1663 static bool test10_wait_recv(struct tevent_req
*req
, int *perr
)
1667 if (tevent_req_is_unix_error(req
, &ret
)) {
1677 static struct sock_daemon_funcs test10_funcs
= {
1678 .shutdown
= test10_shutdown
,
1679 .wait_send
= test10_wait_send
,
1680 .wait_recv
= test10_wait_recv
,
1686 * Confirm that the daemon starts successfully if there is a stale socket
1689 static void test10(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1690 const char *sockpath
)
1698 char pidstr
[20] = { 0 };
1707 struct tevent_context
*ev
;
1708 struct sock_daemon_context
*sockd
;
1712 ev
= tevent_context_init(mem_ctx
);
1715 ret
= sock_daemon_setup(mem_ctx
, "test10", "file:", "NOTICE",
1716 &test10_funcs
, &fd
[1], &sockd
);
1719 ret
= sock_daemon_add_unix(sockd
, sockpath
,
1720 &dummy_socket_funcs
, NULL
);
1723 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1724 assert(ret
== EINTR
);
1731 n
= read(fd
[0], &ret
, sizeof(ret
));
1732 assert(n
== sizeof(ret
));
1735 /* KILL will leave PID file and socket behind */
1736 ret
= kill (pid
, SIGKILL
);
1739 pid2
= waitpid(pid
, &ret
, 0);
1740 assert(pid2
== pid
);
1741 assert(WEXITSTATUS(ret
) == 0);
1743 ret
= stat(sockpath
, &st
);
1755 struct tevent_context
*ev
;
1756 struct sock_daemon_context
*sockd
;
1760 ev
= tevent_context_init(mem_ctx
);
1763 ret
= sock_daemon_setup(mem_ctx
, "test10", "file:", "NOTICE",
1764 &test10_funcs
, &fd
[1], &sockd
);
1767 ret
= sock_daemon_add_unix(sockd
, sockpath
,
1768 &dummy_socket_funcs
, NULL
);
1771 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1772 assert(ret
== EINTR
);
1779 n
= read(fd
[0], &ret
, sizeof(ret
));
1780 assert(n
== sizeof(ret
));
1783 pidfile_fd
= open(pidfile
, O_RDONLY
, 0644);
1784 assert(pidfile_fd
!= -1);
1785 n
= read(pidfile_fd
, pidstr
, sizeof(pidstr
)-1);
1787 pid2
= (pid_t
)atoi(pidstr
);
1788 assert(pid
== pid2
);
1791 ret
= kill(pid
, SIGTERM
);
1794 n
= read(fd
[0], &ret
, sizeof(ret
));
1795 assert(n
== sizeof(ret
));
1798 pid2
= waitpid(pid
, &ret
, 0);
1799 assert(pid2
== pid
);
1800 assert(WEXITSTATUS(ret
) == 0);
1804 ret
= stat(pidfile
, &st
);
1807 ret
= stat(sockpath
, &st
);
1811 int main(int argc
, const char **argv
)
1813 TALLOC_CTX
*mem_ctx
;
1814 const char *pidfile
, *sockpath
;
1818 fprintf(stderr
, "%s <pidfile> <sockpath> <testnum>\n", argv
[0]);
1824 num
= atoi(argv
[3]);
1826 mem_ctx
= talloc_new(NULL
);
1827 assert(mem_ctx
!= NULL
);
1831 test1(mem_ctx
, pidfile
, sockpath
);
1835 test2(mem_ctx
, pidfile
, sockpath
);
1839 test3(mem_ctx
, pidfile
, sockpath
);
1843 test4(mem_ctx
, pidfile
, sockpath
);
1847 test5(mem_ctx
, pidfile
, sockpath
);
1851 test6(mem_ctx
, pidfile
, sockpath
);
1855 test7(mem_ctx
, pidfile
, sockpath
);
1859 test8(mem_ctx
, pidfile
, sockpath
);
1863 test9(mem_ctx
, pidfile
, sockpath
);
1867 test10(mem_ctx
, pidfile
, sockpath
);
1871 fprintf(stderr
, "Unknown test number %d\n", num
);