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 struct sock_daemon_funcs test1_funcs
= {
67 .wait_send
= dummy_wait_send
,
68 .wait_recv
= dummy_wait_recv
,
71 static struct tevent_req
*dummy_read_send(TALLOC_CTX
*mem_ctx
,
72 struct tevent_context
*ev
,
73 struct sock_client_context
*client
,
74 uint8_t *buf
, size_t buflen
,
80 static bool dummy_read_recv(struct tevent_req
*req
, int *perr
)
88 static struct sock_socket_funcs dummy_socket_funcs
= {
89 .read_send
= dummy_read_send
,
90 .read_recv
= dummy_read_recv
,
96 * Check setup without actually running daemon
99 static void test1(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
100 const char *sockpath
)
102 struct tevent_context
*ev
;
103 struct sock_daemon_context
*sockd
;
107 ret
= sock_daemon_setup(mem_ctx
, "test1", "file:", "NOTICE",
108 &test1_funcs
, discard_const(sockpath
), &sockd
);
110 assert(sockd
!= NULL
);
112 ret
= stat(pidfile
, &st
);
115 ret
= sock_daemon_add_unix(sockd
, sockpath
, &dummy_socket_funcs
, NULL
);
118 ret
= stat(sockpath
, &st
);
121 ev
= tevent_context_init(mem_ctx
);
124 ret
= sock_daemon_run(ev
, sockd
, NULL
, false, false, -1);
127 talloc_free(mem_ctx
);
133 * Start daemon, check PID file, sock daemon functions, termination,
137 static void test2_startup(void *private_data
)
139 int fd
= *(int *)private_data
;
143 nwritten
= write(fd
, &ret
, sizeof(ret
));
144 assert(nwritten
== sizeof(ret
));
147 static void test2_reconfigure(void *private_data
)
149 int fd
= *(int *)private_data
;
153 nwritten
= write(fd
, &ret
, sizeof(ret
));
154 assert(nwritten
== sizeof(ret
));
157 static void test2_shutdown(void *private_data
)
159 int fd
= *(int *)private_data
;
163 nwritten
= write(fd
, &ret
, sizeof(ret
));
164 assert(nwritten
== sizeof(ret
));
167 static struct sock_daemon_funcs test2_funcs
= {
168 .startup
= test2_startup
,
169 .reconfigure
= test2_reconfigure
,
170 .shutdown
= test2_shutdown
,
173 static void test2(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
174 const char *sockpath
)
182 char pidstr
[20] = { 0 };
191 struct tevent_context
*ev
;
192 struct sock_daemon_context
*sockd
;
196 ev
= tevent_context_init(mem_ctx
);
199 ret
= sock_daemon_setup(mem_ctx
, "test2", "file:", "NOTICE",
200 &test2_funcs
, &fd
[1], &sockd
);
203 ret
= sock_daemon_add_unix(sockd
, sockpath
,
204 &dummy_socket_funcs
, NULL
);
207 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
208 assert(ret
== EINTR
);
215 n
= read(fd
[0], &ret
, sizeof(ret
));
216 assert(n
== sizeof(ret
));
219 pidfile_fd
= open(pidfile
, O_RDONLY
, 0644);
220 assert(pidfile_fd
!= -1);
221 ret
= fstat(pidfile_fd
, &st
);
223 assert(S_ISREG(st
.st_mode
));
224 n
= read(pidfile_fd
, pidstr
, sizeof(pidstr
)-1);
226 pid2
= (pid_t
)atoi(pidstr
);
230 ret
= kill(pid
, SIGHUP
);
233 n
= read(fd
[0], &ret
, sizeof(ret
));
234 assert(n
== sizeof(ret
));
237 ret
= kill(pid
, SIGUSR1
);
240 n
= read(fd
[0], &ret
, sizeof(ret
));
241 assert(n
== sizeof(ret
));
244 ret
= kill(pid
, SIGTERM
);
247 n
= read(fd
[0], &ret
, sizeof(ret
));
248 assert(n
== sizeof(ret
));
251 pid2
= waitpid(pid
, &ret
, 0);
253 assert(WEXITSTATUS(ret
) == 0);
257 ret
= stat(pidfile
, &st
);
260 ret
= stat(sockpath
, &st
);
267 * Start daemon, test watching of (parent) PID
270 static void test3(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
271 const char *sockpath
)
274 pid_t pid_watch
, pid
, pid2
;
278 assert(pid_watch
!= -1);
280 if (pid_watch
== 0) {
289 struct tevent_context
*ev
;
290 struct sock_daemon_context
*sockd
;
292 ev
= tevent_context_init(mem_ctx
);
295 ret
= sock_daemon_setup(mem_ctx
, "test3", "file:", "NOTICE",
299 ret
= sock_daemon_add_unix(sockd
, sockpath
,
300 &dummy_socket_funcs
, NULL
);
303 ret
= sock_daemon_run(ev
, sockd
, NULL
, false, false, pid_watch
);
304 assert(ret
== ESRCH
);
309 pid2
= waitpid(pid_watch
, &ret
, 0);
310 assert(pid2
== pid_watch
);
311 assert(WEXITSTATUS(ret
) == 0);
313 pid2
= waitpid(pid
, &ret
, 0);
315 assert(WEXITSTATUS(ret
) == 0);
317 ret
= stat(pidfile
, &st
);
320 ret
= stat(sockpath
, &st
);
327 * Start daemon, test termination via wait_send function
330 struct test4_wait_state
{
333 static void test4_wait_done(struct tevent_req
*subreq
);
335 static struct tevent_req
*test4_wait_send(TALLOC_CTX
*mem_ctx
,
336 struct tevent_context
*ev
,
339 struct tevent_req
*req
, *subreq
;
340 struct test4_wait_state
*state
;
342 req
= tevent_req_create(mem_ctx
, &state
, struct test4_wait_state
);
347 subreq
= tevent_wakeup_send(state
, ev
,
348 tevent_timeval_current_ofs(10,0));
349 if (tevent_req_nomem(subreq
, req
)) {
350 return tevent_req_post(req
, ev
);
352 tevent_req_set_callback(subreq
, test4_wait_done
, req
);
357 static void test4_wait_done(struct tevent_req
*subreq
)
359 struct tevent_req
*req
= tevent_req_callback_data(
360 subreq
, struct tevent_req
);
363 status
= tevent_wakeup_recv(subreq
);
367 tevent_req_error(req
, EIO
);
369 tevent_req_done(req
);
373 static bool test4_wait_recv(struct tevent_req
*req
, int *perr
)
377 if (tevent_req_is_unix_error(req
, &ret
)) {
387 static struct sock_daemon_funcs test4_funcs
= {
388 .wait_send
= test4_wait_send
,
389 .wait_recv
= test4_wait_recv
,
392 static void test4(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
393 const char *sockpath
)
403 struct tevent_context
*ev
;
404 struct sock_daemon_context
*sockd
;
406 ev
= tevent_context_init(mem_ctx
);
409 ret
= sock_daemon_setup(mem_ctx
, "test4", "file:", "NOTICE",
410 &test4_funcs
, NULL
, &sockd
);
413 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
419 pid2
= waitpid(pid
, &ret
, 0);
421 assert(WEXITSTATUS(ret
) == 0);
423 ret
= stat(pidfile
, &st
);
426 ret
= stat(sockpath
, &st
);
433 * Start daemon, multiple client connects, requests, disconnects
436 #define TEST5_MAX_CLIENTS 10
443 struct test5_client_state
{
449 static void test5_client_callback(uint8_t *buf
, size_t buflen
,
452 struct test5_client_state
*state
=
453 (struct test5_client_state
*)private_data
;
454 struct test5_pkt
*pkt
;
463 assert(buflen
== sizeof(struct test5_pkt
));
464 pkt
= (struct test5_pkt
*)buf
;
465 assert(pkt
->len
== sizeof(struct test5_pkt
));
470 assert(state
->fd
!= -1);
472 n
= write(state
->fd
, (void *)&ret
, sizeof(int));
473 assert(n
== sizeof(int));
478 static int test5_client(const char *sockpath
, int id
)
492 struct tevent_context
*ev
;
493 struct test5_client_state state
;
494 struct sock_queue
*queue
;
495 struct test5_pkt pkt
;
500 ev
= tevent_context_init(NULL
);
503 conn
= sock_connect(sockpath
);
510 queue
= sock_queue_setup(ev
, ev
, conn
,
511 test5_client_callback
, &state
);
512 assert(queue
!= NULL
);
517 ret
= sock_queue_write(queue
, (uint8_t *)&pkt
,
518 sizeof(struct test5_pkt
));
521 while (! state
.done
) {
522 tevent_loop_once(ev
);
535 n
= read(fd
[0], &ret
, sizeof(ret
));
537 fprintf(stderr
, "client id %d read 0 bytes\n", id
);
539 assert(n
== 0 || n
== sizeof(ret
));
546 struct test5_server_state
{
550 static bool test5_connect(struct sock_client_context
*client
,
553 struct test5_server_state
*state
=
554 (struct test5_server_state
*)private_data
;
556 if (state
->num_clients
== TEST5_MAX_CLIENTS
) {
560 state
->num_clients
+= 1;
561 assert(state
->num_clients
<= TEST5_MAX_CLIENTS
);
565 static void test5_disconnect(struct sock_client_context
*client
,
568 struct test5_server_state
*state
=
569 (struct test5_server_state
*)private_data
;
571 state
->num_clients
-= 1;
572 assert(state
->num_clients
>= 0);
575 struct test5_read_state
{
576 struct test5_pkt reply
;
579 static void test5_read_done(struct tevent_req
*subreq
);
581 static struct tevent_req
*test5_read_send(TALLOC_CTX
*mem_ctx
,
582 struct tevent_context
*ev
,
583 struct sock_client_context
*client
,
584 uint8_t *buf
, size_t buflen
,
587 struct test5_server_state
*server_state
=
588 (struct test5_server_state
*)private_data
;
589 struct tevent_req
*req
, *subreq
;
590 struct test5_read_state
*state
;
591 struct test5_pkt
*pkt
;
593 req
= tevent_req_create(mem_ctx
, &state
, struct test5_read_state
);
596 assert(buflen
== sizeof(struct test5_pkt
));
598 pkt
= (struct test5_pkt
*)buf
;
599 assert(pkt
->data
== 0xbaba);
601 state
->reply
.len
= sizeof(struct test5_pkt
);
602 state
->reply
.data
= server_state
->num_clients
;
604 subreq
= sock_socket_write_send(state
, ev
, client
,
605 (uint8_t *)&state
->reply
,
607 assert(subreq
!= NULL
);
609 tevent_req_set_callback(subreq
, test5_read_done
, req
);
614 static void test5_read_done(struct tevent_req
*subreq
)
616 struct tevent_req
*req
= tevent_req_callback_data(
617 subreq
, struct tevent_req
);
621 status
= sock_socket_write_recv(subreq
, &ret
);
624 tevent_req_error(req
, ret
);
628 tevent_req_done(req
);
631 static bool test5_read_recv(struct tevent_req
*req
, int *perr
)
635 if (tevent_req_is_unix_error(req
, &ret
)) {
645 static struct sock_socket_funcs test5_client_funcs
= {
646 .connect
= test5_connect
,
647 .disconnect
= test5_disconnect
,
648 .read_send
= test5_read_send
,
649 .read_recv
= test5_read_recv
,
652 static void test5_startup(void *private_data
)
654 int fd
= *(int *)private_data
;
658 nwritten
= write(fd
, &ret
, sizeof(ret
));
659 assert(nwritten
== sizeof(ret
));
663 static struct sock_daemon_funcs test5_funcs
= {
664 .startup
= test5_startup
,
667 static void test5(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
668 const char *sockpath
)
670 pid_t pid_server
, pid
;
680 assert(pid_server
!= -1);
682 if (pid_server
== 0) {
683 struct tevent_context
*ev
;
684 struct sock_daemon_context
*sockd
;
685 struct test5_server_state state
;
689 ev
= tevent_context_init(mem_ctx
);
692 ret
= sock_daemon_setup(mem_ctx
, "test5", "file:", "NOTICE",
693 &test5_funcs
, &fd
[1], &sockd
);
696 state
.num_clients
= 0;
698 ret
= sock_daemon_add_unix(sockd
, sockpath
,
699 &test5_client_funcs
, &state
);
702 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, pid
);
703 assert(ret
== EINTR
);
710 n
= read(fd
[0], &ret
, sizeof(ret
));
711 assert(n
== sizeof(ret
));
716 for (i
=0; i
<100; i
++) {
717 ret
= test5_client(sockpath
, i
);
718 if (i
< TEST5_MAX_CLIENTS
) {
725 for (i
=0; i
<100; i
++) {
730 ret
= kill(pid_server
, SIGTERM
);
737 * Start daemon, test client connects, requests, replies, disconnects
745 struct test6_client_state
{
749 static void test6_client_callback(uint8_t *buf
, size_t buflen
,
752 struct test6_client_state
*state
=
753 (struct test6_client_state
*)private_data
;
754 struct test6_pkt
*pkt
;
756 assert(buflen
== sizeof(struct test6_pkt
));
757 pkt
= (struct test6_pkt
*)buf
;
758 assert(pkt
->len
== sizeof(struct test6_pkt
));
759 assert(pkt
->data
== 0xffeeddcc);
764 static void test6_client(const char *sockpath
)
766 struct tevent_context
*ev
;
767 struct test6_client_state state
;
768 struct sock_queue
*queue
;
769 struct test6_pkt pkt
;
772 ev
= tevent_context_init(NULL
);
775 conn
= sock_connect(sockpath
);
780 queue
= sock_queue_setup(ev
, ev
, conn
,
781 test6_client_callback
, &state
);
782 assert(queue
!= NULL
);
785 pkt
.data
= 0xaabbccdd;
787 ret
= sock_queue_write(queue
, (uint8_t *)&pkt
,
788 sizeof(struct test6_pkt
));
791 while (! state
.done
) {
792 tevent_loop_once(ev
);
798 struct test6_server_state
{
799 struct sock_daemon_context
*sockd
;
803 struct test6_read_state
{
804 struct test6_server_state
*server_state
;
805 struct test6_pkt reply
;
808 static void test6_read_done(struct tevent_req
*subreq
);
810 static struct tevent_req
*test6_read_send(TALLOC_CTX
*mem_ctx
,
811 struct tevent_context
*ev
,
812 struct sock_client_context
*client
,
813 uint8_t *buf
, size_t buflen
,
816 struct test6_server_state
*server_state
=
817 (struct test6_server_state
*)private_data
;
818 struct tevent_req
*req
, *subreq
;
819 struct test6_read_state
*state
;
820 struct test6_pkt
*pkt
;
822 req
= tevent_req_create(mem_ctx
, &state
, struct test6_read_state
);
825 state
->server_state
= server_state
;
827 assert(buflen
== sizeof(struct test6_pkt
));
829 pkt
= (struct test6_pkt
*)buf
;
830 assert(pkt
->data
== 0xaabbccdd);
832 state
->reply
.len
= sizeof(struct test6_pkt
);
833 state
->reply
.data
= 0xffeeddcc;
835 subreq
= sock_socket_write_send(state
, ev
, client
,
836 (uint8_t *)&state
->reply
,
838 assert(subreq
!= NULL
);
840 tevent_req_set_callback(subreq
, test6_read_done
, req
);
845 static void test6_read_done(struct tevent_req
*subreq
)
847 struct tevent_req
*req
= tevent_req_callback_data(
848 subreq
, struct tevent_req
);
849 struct test6_read_state
*state
= tevent_req_data(
850 req
, struct test6_read_state
);
854 status
= sock_socket_write_recv(subreq
, &ret
);
857 tevent_req_error(req
, ret
);
861 state
->server_state
->done
= 1;
862 tevent_req_done(req
);
865 static bool test6_read_recv(struct tevent_req
*req
, int *perr
)
869 if (tevent_req_is_unix_error(req
, &ret
)) {
879 static struct sock_socket_funcs test6_client_funcs
= {
880 .read_send
= test6_read_send
,
881 .read_recv
= test6_read_recv
,
884 static void test6_startup(void *private_data
)
886 struct test6_server_state
*server_state
=
887 (struct test6_server_state
*)private_data
;
891 nwritten
= write(server_state
->fd
, &ret
, sizeof(ret
));
892 assert(nwritten
== sizeof(ret
));
893 close(server_state
->fd
);
894 server_state
->fd
= -1;
897 struct test6_wait_state
{
898 struct test6_server_state
*server_state
;
901 static void test6_wait_done(struct tevent_req
*subreq
);
903 static struct tevent_req
*test6_wait_send(TALLOC_CTX
*mem_ctx
,
904 struct tevent_context
*ev
,
907 struct tevent_req
*req
, *subreq
;
908 struct test6_wait_state
*state
;
910 req
= tevent_req_create(mem_ctx
, &state
, struct test6_wait_state
);
915 state
->server_state
= (struct test6_server_state
*)private_data
;
917 subreq
= tevent_wakeup_send(state
, ev
,
918 tevent_timeval_current_ofs(10,0));
919 if (tevent_req_nomem(subreq
, req
)) {
920 return tevent_req_post(req
, ev
);
922 tevent_req_set_callback(subreq
, test6_wait_done
, req
);
927 static void test6_wait_done(struct tevent_req
*subreq
)
929 struct tevent_req
*req
= tevent_req_callback_data(
930 subreq
, struct tevent_req
);
931 struct test6_wait_state
*state
= tevent_req_data(
932 req
, struct test6_wait_state
);
935 status
= tevent_wakeup_recv(subreq
);
938 tevent_req_error(req
, EIO
);
942 if (state
->server_state
->done
== 0) {
943 tevent_req_error(req
, EIO
);
947 tevent_req_done(req
);
950 static bool test6_wait_recv(struct tevent_req
*req
, int *perr
)
954 if (tevent_req_is_unix_error(req
, &ret
)) {
964 static struct sock_daemon_funcs test6_funcs
= {
965 .startup
= test6_startup
,
966 .wait_send
= test6_wait_send
,
967 .wait_recv
= test6_wait_recv
,
970 static void test6(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
971 const char *sockpath
)
973 pid_t pid_server
, pid
;
983 assert(pid_server
!= -1);
985 if (pid_server
== 0) {
986 struct tevent_context
*ev
;
987 struct sock_daemon_context
*sockd
;
988 struct test6_server_state server_state
= { 0 };
992 ev
= tevent_context_init(mem_ctx
);
995 server_state
.fd
= fd
[1];
997 ret
= sock_daemon_setup(mem_ctx
, "test6", "file:", "NOTICE",
998 &test6_funcs
, &server_state
,
1002 server_state
.sockd
= sockd
;
1003 server_state
.done
= 0;
1005 ret
= sock_daemon_add_unix(sockd
, sockpath
,
1006 &test6_client_funcs
, &server_state
);
1009 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, pid
);
1017 n
= read(fd
[0], &ret
, sizeof(ret
));
1018 assert(n
== sizeof(ret
));
1023 test6_client(sockpath
);
1032 * Start daemon twice, confirm PID file contention
1035 static void test7(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1036 const char *sockpath
)
1042 struct tevent_context
*ev
;
1043 struct sock_daemon_context
*sockd
;
1055 ev
= tevent_context_init(mem_ctx
);
1058 /* Reuse test2 funcs for the startup synchronisation */
1059 ret
= sock_daemon_setup(mem_ctx
, "test7", "file:", "NOTICE",
1060 &test2_funcs
, &fd
[1], &sockd
);
1063 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1064 assert(ret
== EINTR
);
1071 n
= read(fd
[0], &ret
, sizeof(ret
));
1072 assert(n
== sizeof(ret
));
1075 ret
= stat(pidfile
, &st
);
1077 assert(S_ISREG(st
.st_mode
));
1079 ev
= tevent_context_init(mem_ctx
);
1082 /* Reuse test2 funcs for the startup synchronisation */
1083 ret
= sock_daemon_setup(mem_ctx
, "test7-parent", "file:", "NOTICE",
1084 &test2_funcs
, &fd
[1], &sockd
);
1087 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1088 assert(ret
== EEXIST
);
1090 ret
= kill(pid
, SIGTERM
);
1093 n
= read(fd
[0], &ret
, sizeof(ret
));
1094 assert(n
== sizeof(ret
));
1097 pid2
= waitpid(pid
, &ret
, 0);
1098 assert(pid2
== pid
);
1099 assert(WEXITSTATUS(ret
) == 0);
1107 * Start daemon, confirm that create_session argument works as expected
1110 static void test8(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1111 const char *sockpath
)
1114 pid_t pid
, pid2
, sid
;
1116 struct tevent_context
*ev
;
1117 struct sock_daemon_context
*sockd
;
1129 ev
= tevent_context_init(mem_ctx
);
1132 /* Reuse test2 funcs for the startup synchronisation */
1133 ret
= sock_daemon_setup(mem_ctx
, "test8", "file:", "NOTICE",
1134 &test2_funcs
, &fd
[1], &sockd
);
1137 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1138 assert(ret
== EINTR
);
1145 n
= read(fd
[0], &ret
, sizeof(ret
));
1146 assert(n
== sizeof(ret
));
1149 /* create_session false above, so pid != sid */
1153 ret
= kill(pid
, SIGTERM
);
1156 n
= read(fd
[0], &ret
, sizeof(ret
));
1157 assert(n
== sizeof(ret
));
1160 pid2
= waitpid(pid
, &ret
, 0);
1161 assert(pid2
== pid
);
1162 assert(WEXITSTATUS(ret
) == 0);
1175 ev
= tevent_context_init(mem_ctx
);
1178 /* Reuse test2 funcs for the startup synchronisation */
1179 ret
= sock_daemon_setup(mem_ctx
, "test8", "file:", "NOTICE",
1180 &test2_funcs
, &fd
[1], &sockd
);
1183 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, true, -1);
1184 assert(ret
== EINTR
);
1191 n
= read(fd
[0], &ret
, sizeof(ret
));
1192 assert(n
== sizeof(ret
));
1195 /* create_session true above, so pid == sid */
1199 ret
= kill(pid
, SIGTERM
);
1202 n
= read(fd
[0], &ret
, sizeof(ret
));
1203 assert(n
== sizeof(ret
));
1206 pid2
= waitpid(pid
, &ret
, 0);
1207 assert(pid2
== pid
);
1208 assert(WEXITSTATUS(ret
) == 0);
1216 * Confirm that do_fork causes the daemon to be forked as a separate child
1219 static void test9(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1220 const char *sockpath
)
1225 struct tevent_context
*ev
;
1226 struct sock_daemon_context
*sockd
;
1229 char pidstr
[20] = { 0 };
1241 ev
= tevent_context_init(mem_ctx
);
1244 /* Reuse test2 funcs for the startup synchronisation */
1245 ret
= sock_daemon_setup(mem_ctx
, "test9", "file:", "NOTICE",
1246 &test2_funcs
, &fd
[1], &sockd
);
1249 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1250 assert(ret
== EINTR
);
1257 n
= read(fd
[0], &ret
, sizeof(ret
));
1258 assert(n
== sizeof(ret
));
1261 /* do_fork false above, so pid should be active */
1265 ret
= kill(pid
, SIGTERM
);
1268 n
= read(fd
[0], &ret
, sizeof(ret
));
1269 assert(n
== sizeof(ret
));
1272 pid2
= waitpid(pid
, &ret
, 0);
1273 assert(pid2
== pid
);
1274 assert(WEXITSTATUS(ret
) == 0);
1287 ev
= tevent_context_init(mem_ctx
);
1290 /* Reuse test2 funcs for the startup synchronisation */
1291 ret
= sock_daemon_setup(mem_ctx
, "test9", "file:", "NOTICE",
1292 &test2_funcs
, &fd
[1], &sockd
);
1295 ret
= sock_daemon_run(ev
, sockd
, pidfile
, true, false, -1);
1296 assert(ret
== EINTR
);
1303 n
= read(fd
[0], &ret
, sizeof(ret
));
1304 assert(n
== sizeof(ret
));
1307 /* do_fork true above, so pid should have exited */
1308 pid2
= waitpid(pid
, &ret
, 0);
1309 assert(pid2
== pid
);
1310 assert(WEXITSTATUS(ret
) == 0);
1312 pidfile_fd
= open(pidfile
, O_RDONLY
, 0644);
1313 assert(pidfile_fd
!= -1);
1314 n
= read(pidfile_fd
, pidstr
, sizeof(pidstr
)-1);
1316 pid2
= (pid_t
)atoi(pidstr
);
1317 assert(pid
!= pid2
);
1320 ret
= kill(pid2
, SIGTERM
);
1323 n
= read(fd
[0], &ret
, sizeof(ret
));
1324 assert(n
== sizeof(ret
));
1328 * pid2 isn't our child, so can't call waitpid(). kill(pid2, 0)
1329 * is unreliable - pid2 may have been recycled. Above indicates
1330 * that the shutdown function was called, so just do 1 final
1331 * check to see if pidfile has been removed.
1333 ret
= stat(sockpath
, &st
);
1342 * Confirm that the daemon starts successfully if there is a stale socket
1345 static void test10(TALLOC_CTX
*mem_ctx
, const char *pidfile
,
1346 const char *sockpath
)
1354 char pidstr
[20] = { 0 };
1363 struct tevent_context
*ev
;
1364 struct sock_daemon_context
*sockd
;
1368 ev
= tevent_context_init(mem_ctx
);
1371 ret
= sock_daemon_setup(mem_ctx
, "test10", "file:", "NOTICE",
1372 &test2_funcs
, &fd
[1], &sockd
);
1375 ret
= sock_daemon_add_unix(sockd
, sockpath
,
1376 &dummy_socket_funcs
, NULL
);
1379 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1380 assert(ret
== EINTR
);
1387 n
= read(fd
[0], &ret
, sizeof(ret
));
1388 assert(n
== sizeof(ret
));
1391 /* KILL will leave PID file and socket behind */
1392 ret
= kill (pid
, SIGKILL
);
1395 ret
= stat(sockpath
, &st
);
1407 struct tevent_context
*ev
;
1408 struct sock_daemon_context
*sockd
;
1412 ev
= tevent_context_init(mem_ctx
);
1415 ret
= sock_daemon_setup(mem_ctx
, "test10", "file:", "NOTICE",
1416 &test2_funcs
, &fd
[1], &sockd
);
1419 ret
= sock_daemon_add_unix(sockd
, sockpath
,
1420 &dummy_socket_funcs
, NULL
);
1423 ret
= sock_daemon_run(ev
, sockd
, pidfile
, false, false, -1);
1424 assert(ret
== EINTR
);
1431 n
= read(fd
[0], &ret
, sizeof(ret
));
1432 assert(n
== sizeof(ret
));
1435 pidfile_fd
= open(pidfile
, O_RDONLY
, 0644);
1436 assert(pidfile_fd
!= -1);
1437 n
= read(pidfile_fd
, pidstr
, sizeof(pidstr
)-1);
1439 pid2
= (pid_t
)atoi(pidstr
);
1440 assert(pid
== pid2
);
1443 ret
= kill(pid
, SIGTERM
);
1446 n
= read(fd
[0], &ret
, sizeof(ret
));
1447 assert(n
== sizeof(ret
));
1450 pid2
= waitpid(pid
, &ret
, 0);
1451 assert(pid2
== pid
);
1452 assert(WEXITSTATUS(ret
) == 0);
1456 ret
= stat(pidfile
, &st
);
1459 ret
= stat(sockpath
, &st
);
1463 int main(int argc
, const char **argv
)
1465 TALLOC_CTX
*mem_ctx
;
1466 const char *pidfile
, *sockpath
;
1470 fprintf(stderr
, "%s <pidfile> <sockpath> <testnum>\n", argv
[0]);
1476 num
= atoi(argv
[3]);
1478 mem_ctx
= talloc_new(NULL
);
1479 assert(mem_ctx
!= NULL
);
1483 test1(mem_ctx
, pidfile
, sockpath
);
1487 test2(mem_ctx
, pidfile
, sockpath
);
1491 test3(mem_ctx
, pidfile
, sockpath
);
1495 test4(mem_ctx
, pidfile
, sockpath
);
1499 test5(mem_ctx
, pidfile
, sockpath
);
1503 test6(mem_ctx
, pidfile
, sockpath
);
1507 test7(mem_ctx
, pidfile
, sockpath
);
1511 test8(mem_ctx
, pidfile
, sockpath
);
1515 test9(mem_ctx
, pidfile
, sockpath
);
1519 test10(mem_ctx
, pidfile
, sockpath
);
1523 fprintf(stderr
, "Unknown test number %d\n", num
);