1 /*
2 sock daemon tests
3
4 Copyright (C) Amitay Isaacs 2016
5
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.
10
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.
15
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/>.
18 */
19
20 #include "replace.h"
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
24
25 #include <assert.h>
26
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"
34
35 struct dummy_wait_state {
36 };
37
dummy_wait_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)38 static struct tevent_req *dummy_wait_send(TALLOC_CTX *mem_ctx,
39 struct tevent_context *ev,
40 void *private_data)
41 {
42 struct tevent_req *req;
43 struct dummy_wait_state *state;
44 const char *sockpath = (const char *)private_data;
45 struct stat st;
46 int ret;
47
48 ret = stat(sockpath, &st);
49 assert(ret == 0);
50 assert(S_ISSOCK(st.st_mode));
51
52 req = tevent_req_create(mem_ctx, &state, struct dummy_wait_state);
53 if (req == NULL) {
54 return NULL;
55 }
56
57 tevent_req_done(req);
58 return tevent_req_post(req, ev);
59 }
60
dummy_wait_recv(struct tevent_req * req,int * perr)61 static bool dummy_wait_recv(struct tevent_req *req, int *perr)
62 {
63 return true;
64 }
65
test1_startup_fail(void * private_data)66 static int test1_startup_fail(void *private_data)
67 {
68 return 1;
69 }
70
test1_startup(void * private_data)71 static int test1_startup(void *private_data)
72 {
73 const char *sockpath = (const char *)private_data;
74 struct stat st;
75 int ret;
76
77 ret = stat(sockpath, &st);
78 assert(ret == -1);
79
80 return 0;
81 }
82
83 struct test1_startup_state {
84 };
85
test1_startup_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)86 static struct tevent_req *test1_startup_send(TALLOC_CTX *mem_ctx,
87 struct tevent_context *ev,
88 void *private_data)
89 {
90 struct tevent_req *req;
91 struct test1_startup_state *state;
92
93 req = tevent_req_create(mem_ctx, &state, struct test1_startup_state);
94 if (req == NULL) {
95 return NULL;
96 }
97
98 tevent_req_error(req, 2);
99 return tevent_req_post(req, ev);
100 }
101
test1_startup_recv(struct tevent_req * req,int * perr)102 static bool test1_startup_recv(struct tevent_req *req, int *perr)
103 {
104 if (tevent_req_is_unix_error(req, perr)) {
105 return false;
106 }
107
108 return true;
109 }
110
dummy_read_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct sock_client_context * client,uint8_t * buf,size_t buflen,void * private_data)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,
115 void *private_data)
116 {
117 return NULL;
118 }
119
dummy_read_recv(struct tevent_req * req,int * perr)120 static bool dummy_read_recv(struct tevent_req *req, int *perr)
121 {
122 if (perr != NULL) {
123 *perr = EINVAL;
124 }
125 return false;
126 }
127
128 static struct sock_socket_funcs dummy_socket_funcs = {
129 .read_send = dummy_read_send,
130 .read_recv = dummy_read_recv,
131 };
132
133 /*
134 * test1
135 *
136 * Check setup without actually running daemon
137 */
138
test1(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)139 static void test1(TALLOC_CTX *mem_ctx, const char *pidfile,
140 const char *sockpath)
141 {
142 struct tevent_context *ev;
143 struct sock_daemon_context *sockd;
144 struct sock_daemon_funcs test1_funcs;
145 struct stat st;
146 int ret;
147
148 ev = tevent_context_init(mem_ctx);
149 assert(ev != NULL);
150
151 test1_funcs = (struct sock_daemon_funcs){
152 .startup = test1_startup_fail,
153 };
154
155 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
156 &test1_funcs, NULL, &sockd);
157 assert(ret == 0);
158 assert(sockd != NULL);
159
160 ret = stat(pidfile, &st);
161 assert(ret == -1);
162
163 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
164 assert(ret == EIO);
165 talloc_free(sockd);
166
167 test1_funcs = (struct sock_daemon_funcs){
168 .startup_send = test1_startup_send,
169 .startup_recv = test1_startup_recv,
170 };
171
172 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
173 &test1_funcs, NULL, &sockd);
174 assert(ret == 0);
175 assert(sockd != NULL);
176
177 ret = stat(pidfile, &st);
178 assert(ret == -1);
179
180 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
181 assert(ret == EIO);
182 talloc_free(sockd);
183
184 test1_funcs = (struct sock_daemon_funcs){
185 .startup = test1_startup,
186 .wait_send = dummy_wait_send,
187 .wait_recv = dummy_wait_recv,
188 };
189
190 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
191 &test1_funcs, discard_const(sockpath), &sockd);
192 assert(ret == 0);
193 assert(sockd != NULL);
194
195 ret = sock_daemon_add_unix(sockd, sockpath, &dummy_socket_funcs, NULL);
196 assert(ret == 0);
197
198 ret = stat(sockpath, &st);
199 assert(ret == -1);
200
201 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
202 assert(ret == 0);
203
204 talloc_free(mem_ctx);
205 }
206
207 /*
208 * test2
209 *
210 * Start daemon, check PID file, sock daemon functions, termination,
211 * exit code
212 */
213
test2_startup(void * private_data)214 static int test2_startup(void *private_data)
215 {
216 int fd = *(int *)private_data;
217 int ret = 1;
218 ssize_t nwritten;
219
220 nwritten = write(fd, &ret, sizeof(ret));
221 assert(nwritten == sizeof(ret));
222 return 0;
223 }
224
test2_reconfigure(void * private_data)225 static int test2_reconfigure(void *private_data)
226 {
227 static bool first_time = true;
228 int fd = *(int *)private_data;
229 int ret = 2;
230 ssize_t nwritten;
231
232 nwritten = write(fd, &ret, sizeof(ret));
233 assert(nwritten == sizeof(ret));
234
235 if (first_time) {
236 first_time = false;
237 return 1;
238 }
239
240 return 0;
241 }
242
243 struct test2_reconfigure_state {
244 int fd;
245 };
246
test2_reconfigure_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)247 static struct tevent_req *test2_reconfigure_send(TALLOC_CTX *mem_ctx,
248 struct tevent_context *ev,
249 void *private_data)
250 {
251 struct tevent_req *req;
252 struct test2_reconfigure_state *state;
253 static bool first_time = true;
254
255 req = tevent_req_create(mem_ctx, &state,
256 struct test2_reconfigure_state);
257 if (req == NULL) {
258 return NULL;
259 }
260
261 state->fd = *(int *)private_data;
262
263 if (first_time) {
264 first_time = false;
265 tevent_req_error(req, 2);
266 } else {
267 tevent_req_done(req);
268 }
269
270 return tevent_req_post(req, ev);
271 }
272
test2_reconfigure_recv(struct tevent_req * req,int * perr)273 static bool test2_reconfigure_recv(struct tevent_req *req, int *perr)
274 {
275 struct test2_reconfigure_state *state = tevent_req_data(
276 req, struct test2_reconfigure_state);
277 int ret = 2;
278 ssize_t nwritten;
279
280 nwritten = write(state->fd, &ret, sizeof(ret));
281 assert(nwritten == sizeof(ret));
282
283 if (tevent_req_is_unix_error(req, perr)) {
284 return false;
285 }
286
287 return true;
288 }
289
test2_shutdown(void * private_data)290 static void test2_shutdown(void *private_data)
291 {
292 int fd = *(int *)private_data;
293 int ret = 3;
294 ssize_t nwritten;
295
296 nwritten = write(fd, &ret, sizeof(ret));
297 assert(nwritten == sizeof(ret));
298 }
299
300 struct test2_shutdown_state {
301 int fd;
302 };
303
test2_shutdown_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)304 static struct tevent_req *test2_shutdown_send(TALLOC_CTX *mem_ctx,
305 struct tevent_context *ev,
306 void *private_data)
307 {
308 struct tevent_req *req;
309 struct test2_shutdown_state *state;
310
311 req = tevent_req_create(mem_ctx, &state,
312 struct test2_shutdown_state);
313 if (req == NULL) {
314 return NULL;
315 }
316
317 state->fd = *(int *)private_data;
318
319 tevent_req_done(req);
320 return tevent_req_post(req, ev);
321 }
322
test2_shutdown_recv(struct tevent_req * req)323 static void test2_shutdown_recv(struct tevent_req *req)
324 {
325 struct test2_shutdown_state *state = tevent_req_data(
326 req, struct test2_shutdown_state);
327 int ret = 3;
328 ssize_t nwritten;
329
330 nwritten = write(state->fd, &ret, sizeof(ret));
331 assert(nwritten == sizeof(ret));
332 }
333
test2(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)334 static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
335 const char *sockpath)
336 {
337 struct stat st;
338 int fd[2];
339 pid_t pid, pid2;
340 int ret;
341 ssize_t n;
342 int pidfile_fd;
343 char pidstr[20] = { 0 };
344
345 ret = pipe(fd);
346 assert(ret == 0);
347
348 pid = fork();
349 assert(pid != -1);
350
351 if (pid == 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,
358 };
359
360 close(fd[0]);
361
362 ev = tevent_context_init(mem_ctx);
363 assert(ev != NULL);
364
365 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
366 &test2_funcs, &fd[1], &sockd);
367 assert(ret == 0);
368
369 ret = sock_daemon_add_unix(sockd, sockpath,
370 &dummy_socket_funcs, NULL);
371 assert(ret == 0);
372
373 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
374 assert(ret == EINTR);
375
376 exit(0);
377 }
378
379 close(fd[1]);
380
381 n = read(fd[0], &ret, sizeof(ret));
382 assert(n == sizeof(ret));
383 assert(ret == 1);
384
385 pidfile_fd = open(pidfile, O_RDONLY, 0644);
386 assert(pidfile_fd != -1);
387 ret = fstat(pidfile_fd, &st);
388 assert(ret == 0);
389 assert(S_ISREG(st.st_mode));
390 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
391 assert(n != -1);
392 pid2 = (pid_t)atoi(pidstr);
393 assert(pid == pid2);
394 close(pidfile_fd);
395
396 ret = kill(pid, SIGHUP);
397 assert(ret == 0);
398
399 n = read(fd[0], &ret, sizeof(ret));
400 assert(n == sizeof(ret));
401 assert(ret == 2);
402
403 ret = kill(pid, SIGUSR1);
404 assert(ret == 0);
405
406 n = read(fd[0], &ret, sizeof(ret));
407 assert(n == sizeof(ret));
408 assert(ret == 2);
409
410 ret = kill(pid, SIGTERM);
411 assert(ret == 0);
412
413 n = read(fd[0], &ret, sizeof(ret));
414 assert(n == sizeof(ret));
415 assert(ret == 3);
416
417 pid2 = waitpid(pid, &ret, 0);
418 assert(pid2 == pid);
419 assert(WEXITSTATUS(ret) == 0);
420
421 close(fd[0]);
422
423 ret = stat(pidfile, &st);
424 assert(ret == -1);
425
426 ret = stat(sockpath, &st);
427 assert(ret == -1);
428
429 ret = pipe(fd);
430 assert(ret == 0);
431
432 pid = fork();
433 assert(pid != -1);
434
435 if (pid == 0) {
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,
444 };
445
446 close(fd[0]);
447
448 ev = tevent_context_init(mem_ctx);
449 assert(ev != NULL);
450
451 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
452 &test2_funcs, &fd[1], &sockd);
453 assert(ret == 0);
454
455 ret = sock_daemon_add_unix(sockd, sockpath,
456 &dummy_socket_funcs, NULL);
457 assert(ret == 0);
458
459 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
460 assert(ret == EINTR);
461
462 exit(0);
463 }
464
465 close(fd[1]);
466
467 n = read(fd[0], &ret, sizeof(ret));
468 assert(n == sizeof(ret));
469 assert(ret == 1);
470
471 ret = kill(pid, SIGUSR1);
472 assert(ret == 0);
473
474 n = read(fd[0], &ret, sizeof(ret));
475 assert(n == sizeof(ret));
476 assert(ret == 2);
477
478 ret = kill(pid, SIGHUP);
479 assert(ret == 0);
480
481 n = read(fd[0], &ret, sizeof(ret));
482 assert(n == sizeof(ret));
483 assert(ret == 2);
484
485 ret = kill(pid, SIGTERM);
486 assert(ret == 0);
487
488 n = read(fd[0], &ret, sizeof(ret));
489 assert(n == sizeof(ret));
490 assert(ret == 3);
491
492 pid2 = waitpid(pid, &ret, 0);
493 assert(pid2 == pid);
494 assert(WEXITSTATUS(ret) == 0);
495
496 close(fd[0]);
497 }
498
499 /*
500 * test3
501 *
502 * Start daemon, test watching of (parent) PID
503 */
504
test3(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)505 static void test3(TALLOC_CTX *mem_ctx, const char *pidfile,
506 const char *sockpath)
507 {
508 struct stat st;
509 pid_t pid_watch, pid, pid2;
510 int ret;
511
512 pid_watch = fork();
513 assert(pid_watch != -1);
514
515 if (pid_watch == 0) {
516 sleep(10);
517 exit(0);
518 }
519
520 pid = fork();
521 assert(pid != -1);
522
523 if (pid == 0) {
524 struct tevent_context *ev;
525 struct sock_daemon_context *sockd;
526
527 ev = tevent_context_init(mem_ctx);
528 assert(ev != NULL);
529
530 ret = sock_daemon_setup(mem_ctx, "test3", "file:", "NOTICE",
531 NULL, NULL, &sockd);
532 assert(ret == 0);
533
534 ret = sock_daemon_add_unix(sockd, sockpath,
535 &dummy_socket_funcs, NULL);
536 assert(ret == 0);
537
538 ret = sock_daemon_run(ev, sockd, NULL, false, false, pid_watch);
539 assert(ret == ESRCH);
540
541 exit(0);
542 }
543
544 pid2 = waitpid(pid_watch, &ret, 0);
545 assert(pid2 == pid_watch);
546 assert(WEXITSTATUS(ret) == 0);
547
548 pid2 = waitpid(pid, &ret, 0);
549 assert(pid2 == pid);
550 assert(WEXITSTATUS(ret) == 0);
551
552 ret = stat(pidfile, &st);
553 assert(ret == -1);
554
555 ret = stat(sockpath, &st);
556 assert(ret == -1);
557 }
558
559 /*
560 * test4
561 *
562 * Start daemon, test termination via wait_send function
563 */
564
565 struct test4_wait_state {
566 };
567
568 static void test4_wait_done(struct tevent_req *subreq);
569
test4_wait_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)570 static struct tevent_req *test4_wait_send(TALLOC_CTX *mem_ctx,
571 struct tevent_context *ev,
572 void *private_data)
573 {
574 struct tevent_req *req, *subreq;
575 struct test4_wait_state *state;
576
577 req = tevent_req_create(mem_ctx, &state, struct test4_wait_state);
578 if (req == NULL) {
579 return NULL;
580 }
581
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);
586 }
587 tevent_req_set_callback(subreq, test4_wait_done, req);
588
589 return req;
590 }
591
test4_wait_done(struct tevent_req * subreq)592 static void test4_wait_done(struct tevent_req *subreq)
593 {
594 struct tevent_req *req = tevent_req_callback_data(
595 subreq, struct tevent_req);
596 bool status;
597
598 status = tevent_wakeup_recv(subreq);
599 TALLOC_FREE(subreq);
600
601 if (! status) {
602 tevent_req_error(req, EIO);
603 } else {
604 tevent_req_done(req);
605 }
606 }
607
test4_wait_recv(struct tevent_req * req,int * perr)608 static bool test4_wait_recv(struct tevent_req *req, int *perr)
609 {
610 int ret;
611
612 if (tevent_req_is_unix_error(req, &ret)) {
613 if (perr != NULL) {
614 *perr = ret;
615 }
616 return false;
617 }
618
619 return true;
620 }
621
622 static struct sock_daemon_funcs test4_funcs = {
623 .wait_send = test4_wait_send,
624 .wait_recv = test4_wait_recv,
625 };
626
test4(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)627 static void test4(TALLOC_CTX *mem_ctx, const char *pidfile,
628 const char *sockpath)
629 {
630 struct stat st;
631 pid_t pid, pid2;
632 int ret;
633
634 pid = fork();
635 assert(pid != -1);
636
637 if (pid == 0) {
638 struct tevent_context *ev;
639 struct sock_daemon_context *sockd;
640
641 ev = tevent_context_init(mem_ctx);
642 assert(ev != NULL);
643
644 ret = sock_daemon_setup(mem_ctx, "test4", "file:", "NOTICE",
645 &test4_funcs, NULL, &sockd);
646 assert(ret == 0);
647
648 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
649 assert(ret == 0);
650
651 exit(0);
652 }
653
654 pid2 = waitpid(pid, &ret, 0);
655 assert(pid2 == pid);
656 assert(WEXITSTATUS(ret) == 0);
657
658 ret = stat(pidfile, &st);
659 assert(ret == -1);
660
661 ret = stat(sockpath, &st);
662 assert(ret == -1);
663 }
664
665 /*
666 * test5
667 *
668 * Start daemon, multiple client connects, requests, disconnects
669 */
670
671 #define TEST5_VALID_CLIENTS 10
672 #define TEST5_MAX_CLIENTS 100
673
674 struct test5_pkt {
675 uint32_t len;
676 int data;
677 };
678
679 struct test5_client_state {
680 int id;
681 int fd;
682 bool done;
683 };
684
test5_client_callback(uint8_t * buf,size_t buflen,void * private_data)685 static void test5_client_callback(uint8_t *buf, size_t buflen,
686 void *private_data)
687 {
688 struct test5_client_state *state =
689 (struct test5_client_state *)private_data;
690 struct test5_pkt *pkt;
691 ssize_t n;
692 int ret;
693
694 if (buf == NULL) {
695 assert(buflen == 0);
696
697 ret = 0;
698 } else {
699 assert(buflen == sizeof(struct test5_pkt));
700 pkt = (struct test5_pkt *)buf;
701 assert(pkt->len == sizeof(struct test5_pkt));
702
703 ret = pkt->data;
704 }
705
706 assert(state->fd != -1);
707
708 n = write(state->fd, (void *)&ret, sizeof(int));
709 assert(n == sizeof(int));
710
711 state->done = true;
712 }
713
test5_client(const char * sockpath,int id,pid_t pid_server,pid_t * client_pid)714 static int test5_client(const char *sockpath, int id, pid_t pid_server,
715 pid_t *client_pid)
716 {
717 pid_t pid;
718 int fd[2];
719 int ret;
720 ssize_t n;
721
722 ret = pipe(fd);
723 assert(ret == 0);
724
725 pid = fork();
726 assert(pid != -1);
727
728 if (pid == 0) {
729 struct tevent_context *ev;
730 struct test5_client_state state;
731 struct sock_queue *queue;
732 struct test5_pkt pkt;
733 int conn;
734
735 close(fd[0]);
736
737 ev = tevent_context_init(NULL);
738 assert(ev != NULL);
739
740 conn = sock_connect(sockpath);
741 assert(conn != -1);
742
743 state.id = id;
744 state.fd = fd[1];
745 state.done = false;
746
747 queue = sock_queue_setup(ev, ev, conn,
748 test5_client_callback, &state);
749 assert(queue != NULL);
750
751 pkt.len = 8;
752 pkt.data = 0xbaba;
753
754 ret = sock_queue_write(queue, (uint8_t *)&pkt,
755 sizeof(struct test5_pkt));
756 assert(ret == 0);
757
758 while (! state.done) {
759 tevent_loop_once(ev);
760 }
761
762 close(fd[1]);
763 state.fd = -1;
764
765 while (kill(pid_server, 0) == 0 || errno != ESRCH) {
766 sleep(1);
767 }
768 exit(0);
769 }
770
771 close(fd[1]);
772
773 ret = 0;
774 n = read(fd[0], &ret, sizeof(ret));
775 if (n == 0) {
776 fprintf(stderr, "client id %d read 0 bytes\n", id);
777 }
778 assert(n == 0 || n == sizeof(ret));
779
780 close(fd[0]);
781
782 *client_pid = pid;
783 return ret;
784 }
785
786 struct test5_server_state {
787 int num_clients;
788 };
789
test5_connect(struct sock_client_context * client,pid_t pid,void * private_data)790 static bool test5_connect(struct sock_client_context *client,
791 pid_t pid,
792 void *private_data)
793 {
794 struct test5_server_state *state =
795 (struct test5_server_state *)private_data;
796
797 if (state->num_clients == TEST5_VALID_CLIENTS) {
798 return false;
799 }
800
801 state->num_clients += 1;
802 assert(state->num_clients <= TEST5_VALID_CLIENTS);
803 return true;
804 }
805
test5_disconnect(struct sock_client_context * client,void * private_data)806 static void test5_disconnect(struct sock_client_context *client,
807 void *private_data)
808 {
809 struct test5_server_state *state =
810 (struct test5_server_state *)private_data;
811
812 state->num_clients -= 1;
813 assert(state->num_clients >= 0);
814 }
815
816 struct test5_read_state {
817 struct test5_pkt reply;
818 };
819
820 static void test5_read_done(struct tevent_req *subreq);
821
test5_read_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct sock_client_context * client,uint8_t * buf,size_t buflen,void * private_data)822 static struct tevent_req *test5_read_send(TALLOC_CTX *mem_ctx,
823 struct tevent_context *ev,
824 struct sock_client_context *client,
825 uint8_t *buf, size_t buflen,
826 void *private_data)
827 {
828 struct test5_server_state *server_state =
829 (struct test5_server_state *)private_data;
830 struct tevent_req *req, *subreq;
831 struct test5_read_state *state;
832 struct test5_pkt *pkt;
833
834 req = tevent_req_create(mem_ctx, &state, struct test5_read_state);
835 assert(req != NULL);
836
837 assert(buflen == sizeof(struct test5_pkt));
838
839 pkt = (struct test5_pkt *)buf;
840 assert(pkt->data == 0xbaba);
841
842 state->reply.len = sizeof(struct test5_pkt);
843 state->reply.data = server_state->num_clients;
844
845 subreq = sock_socket_write_send(state, ev, client,
846 (uint8_t *)&state->reply,
847 state->reply.len);
848 assert(subreq != NULL);
849
850 tevent_req_set_callback(subreq, test5_read_done, req);
851
852 return req;
853 }
854
test5_read_done(struct tevent_req * subreq)855 static void test5_read_done(struct tevent_req *subreq)
856 {
857 struct tevent_req *req = tevent_req_callback_data(
858 subreq, struct tevent_req);
859 int ret;
860 bool status;
861
862 status = sock_socket_write_recv(subreq, &ret);
863 TALLOC_FREE(subreq);
864 if (! status) {
865 tevent_req_error(req, ret);
866 return;
867 }
868
869 tevent_req_done(req);
870 }
871
test5_read_recv(struct tevent_req * req,int * perr)872 static bool test5_read_recv(struct tevent_req *req, int *perr)
873 {
874 int ret;
875
876 if (tevent_req_is_unix_error(req, &ret)) {
877 if (perr != NULL) {
878 *perr = ret;
879 }
880 return false;
881 }
882
883 return true;
884 }
885
886 static struct sock_socket_funcs test5_client_funcs = {
887 .connect = test5_connect,
888 .disconnect = test5_disconnect,
889 .read_send = test5_read_send,
890 .read_recv = test5_read_recv,
891 };
892
893 struct test5_wait_state {
894 };
895
test5_wait_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)896 static struct tevent_req *test5_wait_send(TALLOC_CTX *mem_ctx,
897 struct tevent_context *ev,
898 void *private_data)
899 {
900 struct tevent_req *req;
901 struct test5_wait_state *state;
902 int fd = *(int *)private_data;
903 int ret = 1;
904 ssize_t nwritten;
905
906 nwritten = write(fd, &ret, sizeof(ret));
907 assert(nwritten == sizeof(ret));
908 close(fd);
909
910 req = tevent_req_create(mem_ctx, &state, struct test5_wait_state);
911 if (req == NULL) {
912 return NULL;
913 }
914
915 return req;
916 }
917
test5_wait_recv(struct tevent_req * req,int * perr)918 static bool test5_wait_recv(struct tevent_req *req, int *perr)
919 {
920 return true;
921 }
922
923 static struct sock_daemon_funcs test5_funcs = {
924 .wait_send = test5_wait_send,
925 .wait_recv = test5_wait_recv,
926 };
927
test5(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)928 static void test5(TALLOC_CTX *mem_ctx, const char *pidfile,
929 const char *sockpath)
930 {
931 pid_t pid_server, pid;
932 int fd[2], ret, i;
933 ssize_t n;
934 pid_t client_pid[TEST5_MAX_CLIENTS];
935
936 pid = getpid();
937
938 ret = pipe(fd);
939 assert(ret == 0);
940
941 pid_server = fork();
942 assert(pid_server != -1);
943
944 if (pid_server == 0) {
945 struct tevent_context *ev;
946 struct sock_daemon_context *sockd;
947 struct test5_server_state state;
948
949 close(fd[0]);
950
951 ev = tevent_context_init(mem_ctx);
952 assert(ev != NULL);
953
954 ret = sock_daemon_setup(mem_ctx, "test5", "file:", "NOTICE",
955 &test5_funcs, &fd[1], &sockd);
956 assert(ret == 0);
957
958 state.num_clients = 0;
959
960 ret = sock_daemon_add_unix(sockd, sockpath,
961 &test5_client_funcs, &state);
962 assert(ret == 0);
963
964 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
965 assert(ret == EINTR);
966
967 exit(0);
968 }
969
970 close(fd[1]);
971
972 n = read(fd[0], &ret, sizeof(ret));
973 assert(n == sizeof(ret));
974 assert(ret == 1);
975
976 close(fd[0]);
977
978 for (i=0; i<TEST5_MAX_CLIENTS; i++) {
979 ret = test5_client(sockpath, i, pid_server, &client_pid[i]);
980 if (i < TEST5_VALID_CLIENTS) {
981 assert(ret == i+1);
982 } else {
983 assert(ret == 0);
984 }
985 }
986
987 for (i=TEST5_MAX_CLIENTS-1; i>=0; i--) {
988 kill(client_pid[i], SIGKILL);
989
990 pid = wait(&ret);
991 assert(pid != -1);
992 }
993
994 ret = kill(pid_server, SIGTERM);
995 assert(ret == 0);
996
997 pid = waitpid(pid_server, &ret, 0);
998 assert(pid == pid_server);
999 assert(WEXITSTATUS(ret) == 0);
1000 }
1001
1002 /*
1003 * test6
1004 *
1005 * Start daemon, test client connects, requests, replies, disconnects
1006 */
1007
1008 struct test6_pkt {
1009 uint32_t len;
1010 uint32_t data;
1011 };
1012
1013 struct test6_client_state {
1014 bool done;
1015 };
1016
test6_client_callback(uint8_t * buf,size_t buflen,void * private_data)1017 static void test6_client_callback(uint8_t *buf, size_t buflen,
1018 void *private_data)
1019 {
1020 struct test6_client_state *state =
1021 (struct test6_client_state *)private_data;
1022 struct test6_pkt *pkt;
1023
1024 assert(buflen == sizeof(struct test6_pkt));
1025 pkt = (struct test6_pkt *)buf;
1026 assert(pkt->len == sizeof(struct test6_pkt));
1027 assert(pkt->data == 0xffeeddcc);
1028
1029 state->done = true;
1030 }
1031
test6_client(const char * sockpath)1032 static void test6_client(const char *sockpath)
1033 {
1034 struct tevent_context *ev;
1035 struct test6_client_state state;
1036 struct sock_queue *queue;
1037 struct test6_pkt pkt;
1038 int conn, ret;
1039
1040 ev = tevent_context_init(NULL);
1041 assert(ev != NULL);
1042
1043 conn = sock_connect(sockpath);
1044 assert(conn != -1);
1045
1046 state.done = false;
1047
1048 queue = sock_queue_setup(ev, ev, conn,
1049 test6_client_callback, &state);
1050 assert(queue != NULL);
1051
1052 pkt.len = 8;
1053 pkt.data = 0xaabbccdd;
1054
1055 ret = sock_queue_write(queue, (uint8_t *)&pkt,
1056 sizeof(struct test6_pkt));
1057 assert(ret == 0);
1058
1059 while (! state.done) {
1060 tevent_loop_once(ev);
1061 }
1062
1063 talloc_free(ev);
1064 }
1065
1066 struct test6_server_state {
1067 struct sock_daemon_context *sockd;
1068 int fd, done;
1069 };
1070
1071 struct test6_read_state {
1072 struct test6_server_state *server_state;
1073 struct test6_pkt reply;
1074 };
1075
1076 static void test6_read_done(struct tevent_req *subreq);
1077
test6_read_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct sock_client_context * client,uint8_t * buf,size_t buflen,void * private_data)1078 static struct tevent_req *test6_read_send(TALLOC_CTX *mem_ctx,
1079 struct tevent_context *ev,
1080 struct sock_client_context *client,
1081 uint8_t *buf, size_t buflen,
1082 void *private_data)
1083 {
1084 struct test6_server_state *server_state =
1085 (struct test6_server_state *)private_data;
1086 struct tevent_req *req, *subreq;
1087 struct test6_read_state *state;
1088 struct test6_pkt *pkt;
1089
1090 req = tevent_req_create(mem_ctx, &state, struct test6_read_state);
1091 assert(req != NULL);
1092
1093 state->server_state = server_state;
1094
1095 assert(buflen == sizeof(struct test6_pkt));
1096
1097 pkt = (struct test6_pkt *)buf;
1098 assert(pkt->data == 0xaabbccdd);
1099
1100 state->reply.len = sizeof(struct test6_pkt);
1101 state->reply.data = 0xffeeddcc;
1102
1103 subreq = sock_socket_write_send(state, ev, client,
1104 (uint8_t *)&state->reply,
1105 state->reply.len);
1106 assert(subreq != NULL);
1107
1108 tevent_req_set_callback(subreq, test6_read_done, req);
1109
1110 return req;
1111 }
1112
test6_read_done(struct tevent_req * subreq)1113 static void test6_read_done(struct tevent_req *subreq)
1114 {
1115 struct tevent_req *req = tevent_req_callback_data(
1116 subreq, struct tevent_req);
1117 struct test6_read_state *state = tevent_req_data(
1118 req, struct test6_read_state);
1119 int ret;
1120 bool status;
1121
1122 status = sock_socket_write_recv(subreq, &ret);
1123 TALLOC_FREE(subreq);
1124 if (! status) {
1125 tevent_req_error(req, ret);
1126 return;
1127 }
1128
1129 state->server_state->done = 1;
1130 tevent_req_done(req);
1131 }
1132
test6_read_recv(struct tevent_req * req,int * perr)1133 static bool test6_read_recv(struct tevent_req *req, int *perr)
1134 {
1135 int ret;
1136
1137 if (tevent_req_is_unix_error(req, &ret)) {
1138 if (perr != NULL) {
1139 *perr = ret;
1140 }
1141 return false;
1142 }
1143
1144 return true;
1145 }
1146
1147 static struct sock_socket_funcs test6_client_funcs = {
1148 .read_send = test6_read_send,
1149 .read_recv = test6_read_recv,
1150 };
1151
1152 struct test6_wait_state {
1153 struct test6_server_state *server_state;
1154 };
1155
1156 static void test6_wait_done(struct tevent_req *subreq);
1157
test6_wait_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)1158 static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx,
1159 struct tevent_context *ev,
1160 void *private_data)
1161 {
1162 struct test6_server_state *server_state =
1163 (struct test6_server_state *)private_data;
1164 struct tevent_req *req, *subreq;
1165 struct test6_wait_state *state;
1166 ssize_t nwritten;
1167 int ret = 1;
1168
1169 nwritten = write(server_state->fd, &ret, sizeof(ret));
1170 assert(nwritten == sizeof(ret));
1171 close(server_state->fd);
1172 server_state->fd = -1;
1173
1174 req = tevent_req_create(mem_ctx, &state, struct test6_wait_state);
1175 if (req == NULL) {
1176 return NULL;
1177 }
1178
1179 state->server_state = (struct test6_server_state *)private_data;
1180
1181 subreq = tevent_wakeup_send(state, ev,
1182 tevent_timeval_current_ofs(10,0));
1183 if (tevent_req_nomem(subreq, req)) {
1184 return tevent_req_post(req, ev);
1185 }
1186 tevent_req_set_callback(subreq, test6_wait_done, req);
1187
1188 return req;
1189 }
1190
test6_wait_done(struct tevent_req * subreq)1191 static void test6_wait_done(struct tevent_req *subreq)
1192 {
1193 struct tevent_req *req = tevent_req_callback_data(
1194 subreq, struct tevent_req);
1195 struct test6_wait_state *state = tevent_req_data(
1196 req, struct test6_wait_state);
1197 bool status;
1198
1199 status = tevent_wakeup_recv(subreq);
1200 TALLOC_FREE(subreq);
1201 if (! status) {
1202 tevent_req_error(req, EIO);
1203 return;
1204 }
1205
1206 if (state->server_state->done == 0) {
1207 tevent_req_error(req, EIO);
1208 return;
1209 }
1210
1211 tevent_req_done(req);
1212 }
1213
test6_wait_recv(struct tevent_req * req,int * perr)1214 static bool test6_wait_recv(struct tevent_req *req, int *perr)
1215 {
1216 int ret;
1217
1218 if (tevent_req_is_unix_error(req, &ret)) {
1219 if (perr != NULL) {
1220 *perr = ret;
1221 }
1222 return false;
1223 }
1224
1225 return true;
1226 }
1227
1228 static struct sock_daemon_funcs test6_funcs = {
1229 .wait_send = test6_wait_send,
1230 .wait_recv = test6_wait_recv,
1231 };
1232
test6(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)1233 static void test6(TALLOC_CTX *mem_ctx, const char *pidfile,
1234 const char *sockpath)
1235 {
1236 pid_t pid_server, pid;
1237 int fd[2], ret;
1238 ssize_t n;
1239
1240 pid = getpid();
1241
1242 ret = pipe(fd);
1243 assert(ret == 0);
1244
1245 pid_server = fork();
1246 assert(pid_server != -1);
1247
1248 if (pid_server == 0) {
1249 struct tevent_context *ev;
1250 struct sock_daemon_context *sockd;
1251 struct test6_server_state server_state = { 0 };
1252
1253 close(fd[0]);
1254
1255 ev = tevent_context_init(mem_ctx);
1256 assert(ev != NULL);
1257
1258 server_state.fd = fd[1];
1259
1260 ret = sock_daemon_setup(mem_ctx, "test6", "file:", "NOTICE",
1261 &test6_funcs, &server_state,
1262 &sockd);
1263 assert(ret == 0);
1264
1265 server_state.sockd = sockd;
1266 server_state.done = 0;
1267
1268 ret = sock_daemon_add_unix(sockd, sockpath,
1269 &test6_client_funcs, &server_state);
1270 assert(ret == 0);
1271
1272 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
1273 assert(ret == 0);
1274
1275 exit(0);
1276 }
1277
1278 close(fd[1]);
1279
1280 n = read(fd[0], &ret, sizeof(ret));
1281 assert(n == sizeof(ret));
1282 assert(ret == 1);
1283
1284 close(fd[0]);
1285
1286 test6_client(sockpath);
1287
1288 pid = waitpid(pid_server, &ret, 0);
1289 assert(pid == pid_server);
1290 assert(WEXITSTATUS(ret) == 0);
1291 }
1292
1293 /*
1294 * test7
1295 *
1296 * Start daemon twice, confirm PID file contention
1297 */
1298
test7(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)1299 static void test7(TALLOC_CTX *mem_ctx, const char *pidfile,
1300 const char *sockpath)
1301 {
1302 struct sock_daemon_funcs test7_funcs;
1303 struct stat st;
1304 int fd[2];
1305 pid_t pid, pid2;
1306 int ret;
1307 struct tevent_context *ev;
1308 struct sock_daemon_context *sockd;
1309 ssize_t n;
1310
1311 /* Reuse test2 funcs for the startup synchronisation */
1312 test7_funcs = (struct sock_daemon_funcs) {
1313 .startup = test2_startup,
1314 .reconfigure = test2_reconfigure,
1315 .shutdown = test2_shutdown,
1316 };
1317
1318 ret = pipe(fd);
1319 assert(ret == 0);
1320
1321 pid = fork();
1322 assert(pid != -1);
1323
1324 if (pid == 0) {
1325 close(fd[0]);
1326
1327 ev = tevent_context_init(mem_ctx);
1328 assert(ev != NULL);
1329
1330 ret = sock_daemon_setup(mem_ctx, "test7", "file:", "NOTICE",
1331 &test7_funcs, &fd[1], &sockd);
1332 assert(ret == 0);
1333
1334 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1335 assert(ret == EINTR);
1336
1337 exit(0);
1338 }
1339
1340 close(fd[1]);
1341
1342 n = read(fd[0], &ret, sizeof(ret));
1343 assert(n == sizeof(ret));
1344 assert(ret == 1);
1345
1346 ret = stat(pidfile, &st);
1347 assert(ret == 0);
1348 assert(S_ISREG(st.st_mode));
1349
1350 ev = tevent_context_init(mem_ctx);
1351 assert(ev != NULL);
1352
1353 ret = sock_daemon_setup(mem_ctx, "test7-parent", "file:", "NOTICE",
1354 &test7_funcs, &fd[1], &sockd);
1355 assert(ret == 0);
1356
1357 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1358 assert(ret == EEXIST);
1359
1360 ret = kill(pid, SIGTERM);
1361 assert(ret == 0);
1362
1363 n = read(fd[0], &ret, sizeof(ret));
1364 assert(n == sizeof(ret));
1365 assert(ret == 3);
1366
1367 pid2 = waitpid(pid, &ret, 0);
1368 assert(pid2 == pid);
1369 assert(WEXITSTATUS(ret) == 0);
1370
1371 close(fd[0]);
1372 }
1373
1374 /*
1375 * test8
1376 *
1377 * Start daemon, confirm that create_session argument works as expected
1378 */
1379
test8(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)1380 static void test8(TALLOC_CTX *mem_ctx, const char *pidfile,
1381 const char *sockpath)
1382 {
1383 int fd[2];
1384 pid_t pid, pid2, sid;
1385 int ret;
1386 struct tevent_context *ev;
1387 struct sock_daemon_context *sockd;
1388 ssize_t n;
1389
1390 ret = pipe(fd);
1391 assert(ret == 0);
1392
1393 pid = fork();
1394 assert(pid != -1);
1395
1396 if (pid == 0) {
1397 /* Reuse test2 funcs for the startup synchronisation */
1398 struct sock_daemon_funcs test8_funcs = {
1399 .startup = test2_startup,
1400 };
1401
1402 close(fd[0]);
1403
1404 ev = tevent_context_init(mem_ctx);
1405 assert(ev != NULL);
1406
1407 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1408 &test8_funcs, &fd[1], &sockd);
1409 assert(ret == 0);
1410
1411 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1412 assert(ret == EINTR);
1413
1414 exit(0);
1415 }
1416
1417 close(fd[1]);
1418
1419 n = read(fd[0], &ret, sizeof(ret));
1420 assert(n == sizeof(ret));
1421 assert(ret == 1);
1422
1423 /* create_session false above, so pid != sid */
1424 sid = getsid(pid);
1425 assert(pid != sid);
1426
1427 ret = kill(pid, SIGTERM);
1428 assert(ret == 0);
1429
1430 pid2 = waitpid(pid, &ret, 0);
1431 assert(pid2 == pid);
1432 assert(WEXITSTATUS(ret) == 0);
1433
1434 close(fd[0]);
1435
1436 ret = pipe(fd);
1437 assert(ret == 0);
1438
1439 pid = fork();
1440 assert(pid != -1);
1441
1442 if (pid == 0) {
1443 /* Reuse test2 funcs for the startup synchronisation */
1444 struct sock_daemon_funcs test8_funcs = {
1445 .startup = test2_startup,
1446 };
1447
1448 close(fd[0]);
1449
1450 ev = tevent_context_init(mem_ctx);
1451 assert(ev != NULL);
1452
1453 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1454 &test8_funcs, &fd[1], &sockd);
1455 assert(ret == 0);
1456
1457 ret = sock_daemon_run(ev, sockd, pidfile, false, true, -1);
1458 assert(ret == EINTR);
1459
1460 exit(0);
1461 }
1462
1463 close(fd[1]);
1464
1465 n = read(fd[0], &ret, sizeof(ret));
1466 assert(n == sizeof(ret));
1467 assert(ret == 1);
1468
1469 /* create_session true above, so pid == sid */
1470 sid = getsid(pid);
1471 assert(pid == sid);
1472
1473 ret = kill(pid, SIGTERM);
1474 assert(ret == 0);
1475
1476 pid2 = waitpid(pid, &ret, 0);
1477 assert(pid2 == pid);
1478 assert(WEXITSTATUS(ret) == 0);
1479
1480 close(fd[0]);
1481 }
1482
1483 /*
1484 * test9
1485 *
1486 * Confirm that do_fork causes the daemon to be forked as a separate child
1487 */
1488
test9(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)1489 static void test9(TALLOC_CTX *mem_ctx, const char *pidfile,
1490 const char *sockpath)
1491 {
1492 int fd[2];
1493 pid_t pid, pid2;
1494 int ret;
1495 struct tevent_context *ev;
1496 struct sock_daemon_context *sockd;
1497 ssize_t n;
1498 int pidfile_fd;
1499 char pidstr[20] = { 0 };
1500 struct stat st;
1501
1502 ret = pipe(fd);
1503 assert(ret == 0);
1504
1505 pid = fork();
1506 assert(pid != -1);
1507
1508 if (pid == 0) {
1509 /* Reuse test2 funcs for the startup synchronisation */
1510 struct sock_daemon_funcs test9_funcs = {
1511 .startup = test2_startup,
1512 };
1513
1514 close(fd[0]);
1515
1516 ev = tevent_context_init(mem_ctx);
1517 assert(ev != NULL);
1518
1519 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1520 &test9_funcs, &fd[1], &sockd);
1521 assert(ret == 0);
1522
1523 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1524 assert(ret == EINTR);
1525
1526 exit(0);
1527 }
1528
1529 close(fd[1]);
1530
1531 n = read(fd[0], &ret, sizeof(ret));
1532 assert(n == sizeof(ret));
1533 assert(ret == 1);
1534
1535 /* do_fork false above, so pid should be active */
1536 ret = kill(pid, 0);
1537 assert(ret == 0);
1538
1539 ret = kill(pid, SIGTERM);
1540 assert(ret == 0);
1541
1542 pid2 = waitpid(pid, &ret, 0);
1543 assert(pid2 == pid);
1544 assert(WEXITSTATUS(ret) == 0);
1545
1546 close(fd[0]);
1547
1548 ret = pipe(fd);
1549 assert(ret == 0);
1550
1551 pid = fork();
1552 assert(pid != -1);
1553
1554 if (pid == 0) {
1555 /* Reuse test2 funcs for the startup synchronisation */
1556 struct sock_daemon_funcs test9_funcs = {
1557 .startup = test2_startup,
1558 .shutdown = test2_shutdown,
1559 };
1560
1561 close(fd[0]);
1562
1563 ev = tevent_context_init(mem_ctx);
1564 assert(ev != NULL);
1565
1566 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1567 &test9_funcs, &fd[1], &sockd);
1568 assert(ret == 0);
1569
1570 ret = sock_daemon_run(ev, sockd, pidfile, true, false, -1);
1571 assert(ret == EINTR);
1572
1573 exit(0);
1574 }
1575
1576 close(fd[1]);
1577
1578 n = read(fd[0], &ret, sizeof(ret));
1579 assert(n == sizeof(ret));
1580 assert(ret == 1);
1581
1582 /* do_fork true above, so pid should have exited */
1583 pid2 = waitpid(pid, &ret, 0);
1584 assert(pid2 == pid);
1585 assert(WEXITSTATUS(ret) == 0);
1586
1587 pidfile_fd = open(pidfile, O_RDONLY, 0644);
1588 assert(pidfile_fd != -1);
1589 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1590 assert(n != -1);
1591 pid2 = (pid_t)atoi(pidstr);
1592 assert(pid != pid2);
1593 close(pidfile_fd);
1594
1595 ret = kill(pid2, SIGTERM);
1596 assert(ret == 0);
1597
1598 n = read(fd[0], &ret, sizeof(ret));
1599 assert(n == sizeof(ret));
1600 assert(ret == 3);
1601
1602 /*
1603 * pid2 isn't our child, so can't call waitpid(). kill(pid2, 0)
1604 * is unreliable - pid2 may have been recycled. Above indicates
1605 * that the shutdown function was called, so just do 1 final
1606 * check to see if pidfile has been removed.
1607 */
1608 ret = stat(sockpath, &st);
1609 assert(ret == -1);
1610
1611 close(fd[0]);
1612 }
1613
test10_shutdown(void * private_data)1614 static void test10_shutdown(void *private_data)
1615 {
1616 int fd = *(int *)private_data;
1617 int ret = 3;
1618 ssize_t nwritten;
1619
1620 nwritten = write(fd, &ret, sizeof(ret));
1621 assert(nwritten == sizeof(ret));
1622 }
1623
1624 struct test10_wait_state {
1625 };
1626
1627 static void test10_wait_done(struct tevent_req *subreq);
1628
test10_wait_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,void * private_data)1629 static struct tevent_req *test10_wait_send(TALLOC_CTX *mem_ctx,
1630 struct tevent_context *ev,
1631 void *private_data)
1632 {
1633 int fd = *(int *)private_data;
1634 struct tevent_req *req, *subreq;
1635 struct test10_wait_state *state;
1636 size_t nwritten;
1637 int ret = 1;
1638
1639 req = tevent_req_create(mem_ctx, &state, struct test10_wait_state);
1640 if (req == NULL) {
1641 return NULL;
1642 }
1643
1644 subreq = tevent_wakeup_send(state, ev,
1645 tevent_timeval_current_ofs(10, 0));
1646 if (tevent_req_nomem(subreq, req)) {
1647 return tevent_req_post(req, ev);
1648 }
1649 tevent_req_set_callback(subreq, test10_wait_done, req);
1650
1651 nwritten = write(fd, &ret, sizeof(ret));
1652 assert(nwritten == sizeof(ret));
1653
1654 return req;
1655 }
1656
test10_wait_done(struct tevent_req * subreq)1657 static void test10_wait_done(struct tevent_req *subreq)
1658 {
1659 struct tevent_req *req = tevent_req_callback_data(
1660 subreq, struct tevent_req);
1661 bool status;
1662
1663 status = tevent_wakeup_recv(subreq);
1664 if (! status) {
1665 tevent_req_error(req, EIO);
1666 return;
1667 }
1668
1669 tevent_req_done(req);
1670 }
1671
test10_wait_recv(struct tevent_req * req,int * perr)1672 static bool test10_wait_recv(struct tevent_req *req, int *perr)
1673 {
1674 int ret;
1675
1676 if (tevent_req_is_unix_error(req, &ret)) {
1677 if (perr != NULL) {
1678 *perr = ret;
1679 }
1680 return false;
1681 }
1682
1683 return true;
1684 }
1685
1686 static struct sock_daemon_funcs test10_funcs = {
1687 .shutdown = test10_shutdown,
1688 .wait_send = test10_wait_send,
1689 .wait_recv = test10_wait_recv,
1690 };
1691
1692 /*
1693 * test10
1694 *
1695 * Confirm that the daemon starts successfully if there is a stale socket
1696 */
1697
test10(TALLOC_CTX * mem_ctx,const char * pidfile,const char * sockpath)1698 static void test10(TALLOC_CTX *mem_ctx, const char *pidfile,
1699 const char *sockpath)
1700 {
1701 struct stat st;
1702 int fd[2];
1703 pid_t pid, pid2;
1704 int ret;
1705 ssize_t n;
1706 int pidfile_fd;
1707 char pidstr[20] = { 0 };
1708
1709 ret = pipe(fd);
1710 assert(ret == 0);
1711
1712 pid = fork();
1713 assert(pid != -1);
1714
1715 if (pid == 0) {
1716 struct tevent_context *ev;
1717 struct sock_daemon_context *sockd;
1718
1719 close(fd[0]);
1720
1721 ev = tevent_context_init(mem_ctx);
1722 assert(ev != NULL);
1723
1724 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1725 &test10_funcs, &fd[1], &sockd);
1726 assert(ret == 0);
1727
1728 ret = sock_daemon_add_unix(sockd, sockpath,
1729 &dummy_socket_funcs, NULL);
1730 assert(ret == 0);
1731
1732 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1733 assert(ret == EINTR);
1734
1735 exit(0);
1736 }
1737
1738 close(fd[1]);
1739
1740 n = read(fd[0], &ret, sizeof(ret));
1741 assert(n == sizeof(ret));
1742 assert(ret == 1);
1743
1744 /* KILL will leave PID file and socket behind */
1745 ret = kill (pid, SIGKILL);
1746 assert(ret == 0);
1747
1748 pid2 = waitpid(pid, &ret, 0);
1749 assert(pid2 == pid);
1750 assert(WEXITSTATUS(ret) == 0);
1751
1752 ret = stat(sockpath, &st);
1753 assert(ret == 0);
1754
1755 close(fd[0]);
1756
1757 ret = pipe(fd);
1758 assert(ret == 0);
1759
1760 pid = fork();
1761 assert(pid != -1);
1762
1763 if (pid == 0) {
1764 struct tevent_context *ev;
1765 struct sock_daemon_context *sockd;
1766
1767 close(fd[0]);
1768
1769 ev = tevent_context_init(mem_ctx);
1770 assert(ev != NULL);
1771
1772 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1773 &test10_funcs, &fd[1], &sockd);
1774 assert(ret == 0);
1775
1776 ret = sock_daemon_add_unix(sockd, sockpath,
1777 &dummy_socket_funcs, NULL);
1778 assert(ret == 0);
1779
1780 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1781 assert(ret == EINTR);
1782
1783 exit(0);
1784 }
1785
1786 close(fd[1]);
1787
1788 n = read(fd[0], &ret, sizeof(ret));
1789 assert(n == sizeof(ret));
1790 assert(ret == 1);
1791
1792 pidfile_fd = open(pidfile, O_RDONLY, 0644);
1793 assert(pidfile_fd != -1);
1794 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1795 assert(n != -1);
1796 pid2 = (pid_t)atoi(pidstr);
1797 assert(pid == pid2);
1798 close(pidfile_fd);
1799
1800 ret = kill(pid, SIGTERM);
1801 assert(ret == 0);
1802
1803 n = read(fd[0], &ret, sizeof(ret));
1804 assert(n == sizeof(ret));
1805 assert(ret == 3);
1806
1807 pid2 = waitpid(pid, &ret, 0);
1808 assert(pid2 == pid);
1809 assert(WEXITSTATUS(ret) == 0);
1810
1811 close(fd[0]);
1812
1813 ret = stat(pidfile, &st);
1814 assert(ret == -1);
1815
1816 ret = stat(sockpath, &st);
1817 assert(ret == -1);
1818 }
1819
main(int argc,const char ** argv)1820 int main(int argc, const char **argv)
1821 {
1822 TALLOC_CTX *mem_ctx;
1823 const char *pidfile, *sockpath;
1824 int num;
1825
1826 if (argc != 4) {
1827 fprintf(stderr, "%s <pidfile> <sockpath> <testnum>\n", argv[0]);
1828 exit(1);
1829 }
1830
1831 pidfile = argv[1];
1832 sockpath = argv[2];
1833 num = atoi(argv[3]);
1834
1835 mem_ctx = talloc_new(NULL);
1836 assert(mem_ctx != NULL);
1837
1838 switch (num) {
1839 case 1:
1840 test1(mem_ctx, pidfile, sockpath);
1841 break;
1842
1843 case 2:
1844 test2(mem_ctx, pidfile, sockpath);
1845 break;
1846
1847 case 3:
1848 test3(mem_ctx, pidfile, sockpath);
1849 break;
1850
1851 case 4:
1852 test4(mem_ctx, pidfile, sockpath);
1853 break;
1854
1855 case 5:
1856 test5(mem_ctx, pidfile, sockpath);
1857 break;
1858
1859 case 6:
1860 test6(mem_ctx, pidfile, sockpath);
1861 break;
1862
1863 case 7:
1864 test7(mem_ctx, pidfile, sockpath);
1865 break;
1866
1867 case 8:
1868 test8(mem_ctx, pidfile, sockpath);
1869 break;
1870
1871 case 9:
1872 test9(mem_ctx, pidfile, sockpath);
1873 break;
1874
1875 case 10:
1876 test10(mem_ctx, pidfile, sockpath);
1877 break;
1878
1879 default:
1880 fprintf(stderr, "Unknown test number %d\n", num);
1881 }
1882
1883 return 0;
1884 }
1885