ctdb-common: Add async version of shutdown in sock_daemon
[samba.git] / ctdb / tests / src / sock_daemon_test.c
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
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
61 static bool dummy_wait_recv(struct tevent_req *req, int *perr)
62 {
63         return true;
64 }
65
66 static int test1_startup_fail(void *private_data)
67 {
68         return 1;
69 }
70
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_MAX_CLIENTS       10
672
673 struct test5_pkt {
674         uint32_t len;
675         int data;
676 };
677
678 struct test5_client_state {
679         int id;
680         int fd;
681         bool done;
682 };
683
684 static void test5_client_callback(uint8_t *buf, size_t buflen,
685                                   void *private_data)
686 {
687         struct test5_client_state *state =
688                 (struct test5_client_state *)private_data;
689         struct test5_pkt *pkt;
690         ssize_t n;
691         int ret;
692
693         if (buf == NULL) {
694                 assert(buflen == 0);
695
696                 ret = 0;
697         } else {
698                 assert(buflen == sizeof(struct test5_pkt));
699                 pkt = (struct test5_pkt *)buf;
700                 assert(pkt->len == sizeof(struct test5_pkt));
701
702                 ret = pkt->data;
703         }
704
705         assert(state->fd != -1);
706
707         n = write(state->fd, (void *)&ret, sizeof(int));
708         assert(n == sizeof(int));
709
710         state->done = true;
711 }
712
713 static int test5_client(const char *sockpath, int id)
714 {
715         pid_t pid;
716         int fd[2];
717         int ret;
718         ssize_t n;
719
720         ret = pipe(fd);
721         assert(ret == 0);
722
723         pid = fork();
724         assert(pid != -1);
725
726         if (pid == 0) {
727                 struct tevent_context *ev;
728                 struct test5_client_state state;
729                 struct sock_queue *queue;
730                 struct test5_pkt pkt;
731                 int conn;
732
733                 close(fd[0]);
734
735                 ev = tevent_context_init(NULL);
736                 assert(ev != NULL);
737
738                 conn = sock_connect(sockpath);
739                 assert(conn != -1);
740
741                 state.id = id;
742                 state.fd = fd[1];
743                 state.done = false;
744
745                 queue = sock_queue_setup(ev, ev, conn,
746                                          test5_client_callback, &state);
747                 assert(queue != NULL);
748
749                 pkt.len = 8;
750                 pkt.data = 0xbaba;
751
752                 ret = sock_queue_write(queue, (uint8_t *)&pkt,
753                                        sizeof(struct test5_pkt));
754                 assert(ret == 0);
755
756                 while (! state.done) {
757                         tevent_loop_once(ev);
758                 }
759
760                 close(fd[0]);
761                 state.fd = -1;
762
763                 sleep(10);
764                 exit(0);
765         }
766
767         close(fd[1]);
768
769         ret = 0;
770         n = read(fd[0], &ret, sizeof(ret));
771         if (n == 0) {
772                 fprintf(stderr, "client id %d read 0 bytes\n", id);
773         }
774         assert(n == 0 || n == sizeof(ret));
775
776         close(fd[0]);
777
778         return ret;
779 }
780
781 struct test5_server_state {
782         int num_clients;
783 };
784
785 static bool test5_connect(struct sock_client_context *client,
786                           void *private_data)
787 {
788         struct test5_server_state *state =
789                 (struct test5_server_state *)private_data;
790
791         if (state->num_clients == TEST5_MAX_CLIENTS) {
792                 return false;
793         }
794
795         state->num_clients += 1;
796         assert(state->num_clients <= TEST5_MAX_CLIENTS);
797         return true;
798 }
799
800 static void test5_disconnect(struct sock_client_context *client,
801                              void *private_data)
802 {
803         struct test5_server_state *state =
804                 (struct test5_server_state *)private_data;
805
806         state->num_clients -= 1;
807         assert(state->num_clients >= 0);
808 }
809
810 struct test5_read_state {
811         struct test5_pkt reply;
812 };
813
814 static void test5_read_done(struct tevent_req *subreq);
815
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,
820                                           void *private_data)
821 {
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;
827
828         req = tevent_req_create(mem_ctx, &state, struct test5_read_state);
829         assert(req != NULL);
830
831         assert(buflen == sizeof(struct test5_pkt));
832
833         pkt = (struct test5_pkt *)buf;
834         assert(pkt->data == 0xbaba);
835
836         state->reply.len = sizeof(struct test5_pkt);
837         state->reply.data = server_state->num_clients;
838
839         subreq = sock_socket_write_send(state, ev, client,
840                                         (uint8_t *)&state->reply,
841                                         state->reply.len);
842         assert(subreq != NULL);
843
844         tevent_req_set_callback(subreq, test5_read_done, req);
845
846         return req;
847 }
848
849 static void test5_read_done(struct tevent_req *subreq)
850 {
851         struct tevent_req *req = tevent_req_callback_data(
852                 subreq, struct tevent_req);
853         int ret;
854         bool status;
855
856         status = sock_socket_write_recv(subreq, &ret);
857         TALLOC_FREE(subreq);
858         if (! status) {
859                 tevent_req_error(req, ret);
860                 return;
861         }
862
863         tevent_req_done(req);
864 }
865
866 static bool test5_read_recv(struct tevent_req *req, int *perr)
867 {
868         int ret;
869
870         if (tevent_req_is_unix_error(req, &ret)) {
871                 if (perr != NULL) {
872                         *perr = ret;
873                 }
874                 return false;
875         }
876
877         return true;
878 }
879
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,
885 };
886
887 struct test5_wait_state {
888 };
889
890 static struct tevent_req *test5_wait_send(TALLOC_CTX *mem_ctx,
891                                           struct tevent_context *ev,
892                                           void *private_data)
893 {
894         struct tevent_req *req;
895         struct test5_wait_state *state;
896         int fd = *(int *)private_data;
897         int ret = 1;
898         ssize_t nwritten;
899
900         nwritten = write(fd, &ret, sizeof(ret));
901         assert(nwritten == sizeof(ret));
902         close(fd);
903
904         req = tevent_req_create(mem_ctx, &state, struct test5_wait_state);
905         if (req == NULL) {
906                 return NULL;
907         }
908
909         return req;
910 }
911
912 static bool test5_wait_recv(struct tevent_req *req, int *perr)
913 {
914         return true;
915 }
916
917 static struct sock_daemon_funcs test5_funcs = {
918         .wait_send = test5_wait_send,
919         .wait_recv = test5_wait_recv,
920 };
921
922 static void test5(TALLOC_CTX *mem_ctx, const char *pidfile,
923                   const char *sockpath)
924 {
925         pid_t pid_server, pid;
926         int fd[2], ret, i;
927         ssize_t n;
928
929         pid = getpid();
930
931         ret = pipe(fd);
932         assert(ret == 0);
933
934         pid_server = fork();
935         assert(pid_server != -1);
936
937         if (pid_server == 0) {
938                 struct tevent_context *ev;
939                 struct sock_daemon_context *sockd;
940                 struct test5_server_state state;
941
942                 close(fd[0]);
943
944                 ev = tevent_context_init(mem_ctx);
945                 assert(ev != NULL);
946
947                 ret = sock_daemon_setup(mem_ctx, "test5", "file:", "NOTICE",
948                                         &test5_funcs, &fd[1], &sockd);
949                 assert(ret == 0);
950
951                 state.num_clients = 0;
952
953                 ret = sock_daemon_add_unix(sockd, sockpath,
954                                            &test5_client_funcs, &state);
955                 assert(ret == 0);
956
957                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
958                 assert(ret == EINTR);
959
960                 exit(0);
961         }
962
963         close(fd[1]);
964
965         n = read(fd[0], &ret, sizeof(ret));
966         assert(n == sizeof(ret));
967         assert(ret == 1);
968
969         close(fd[0]);
970
971         for (i=0; i<100; i++) {
972                 ret = test5_client(sockpath, i);
973                 if (i < TEST5_MAX_CLIENTS) {
974                         assert(ret == i+1);
975                 } else {
976                         assert(ret == 0);
977                 }
978         }
979
980         for (i=0; i<100; i++) {
981                 pid = wait(&ret);
982                 assert(pid != -1);
983         }
984
985         ret = kill(pid_server, SIGTERM);
986         assert(ret == 0);
987 }
988
989 /*
990  * test6
991  *
992  * Start daemon, test client connects, requests, replies, disconnects
993  */
994
995 struct test6_pkt {
996         uint32_t len;
997         uint32_t data;
998 };
999
1000 struct test6_client_state {
1001         bool done;
1002 };
1003
1004 static void test6_client_callback(uint8_t *buf, size_t buflen,
1005                                   void *private_data)
1006 {
1007         struct test6_client_state *state =
1008                 (struct test6_client_state *)private_data;
1009         struct test6_pkt *pkt;
1010
1011         assert(buflen == sizeof(struct test6_pkt));
1012         pkt = (struct test6_pkt *)buf;
1013         assert(pkt->len == sizeof(struct test6_pkt));
1014         assert(pkt->data == 0xffeeddcc);
1015
1016         state->done = true;
1017 }
1018
1019 static void test6_client(const char *sockpath)
1020 {
1021         struct tevent_context *ev;
1022         struct test6_client_state state;
1023         struct sock_queue *queue;
1024         struct test6_pkt pkt;
1025         int conn, ret;
1026
1027         ev = tevent_context_init(NULL);
1028         assert(ev != NULL);
1029
1030         conn = sock_connect(sockpath);
1031         assert(conn != -1);
1032
1033         state.done = false;
1034
1035         queue = sock_queue_setup(ev, ev, conn,
1036                                  test6_client_callback, &state);
1037         assert(queue != NULL);
1038
1039         pkt.len = 8;
1040         pkt.data = 0xaabbccdd;
1041
1042         ret = sock_queue_write(queue, (uint8_t *)&pkt,
1043                                sizeof(struct test6_pkt));
1044         assert(ret == 0);
1045
1046         while (! state.done) {
1047                 tevent_loop_once(ev);
1048         }
1049
1050         talloc_free(ev);
1051 }
1052
1053 struct test6_server_state {
1054         struct sock_daemon_context *sockd;
1055         int fd, done;
1056 };
1057
1058 struct test6_read_state {
1059         struct test6_server_state *server_state;
1060         struct test6_pkt reply;
1061 };
1062
1063 static void test6_read_done(struct tevent_req *subreq);
1064
1065 static struct tevent_req *test6_read_send(TALLOC_CTX *mem_ctx,
1066                                           struct tevent_context *ev,
1067                                           struct sock_client_context *client,
1068                                           uint8_t *buf, size_t buflen,
1069                                           void *private_data)
1070 {
1071         struct test6_server_state *server_state =
1072                 (struct test6_server_state *)private_data;
1073         struct tevent_req *req, *subreq;
1074         struct test6_read_state *state;
1075         struct test6_pkt *pkt;
1076
1077         req = tevent_req_create(mem_ctx, &state, struct test6_read_state);
1078         assert(req != NULL);
1079
1080         state->server_state = server_state;
1081
1082         assert(buflen == sizeof(struct test6_pkt));
1083
1084         pkt = (struct test6_pkt *)buf;
1085         assert(pkt->data == 0xaabbccdd);
1086
1087         state->reply.len = sizeof(struct test6_pkt);
1088         state->reply.data = 0xffeeddcc;
1089
1090         subreq = sock_socket_write_send(state, ev, client,
1091                                         (uint8_t *)&state->reply,
1092                                         state->reply.len);
1093         assert(subreq != NULL);
1094
1095         tevent_req_set_callback(subreq, test6_read_done, req);
1096
1097         return req;
1098 }
1099
1100 static void test6_read_done(struct tevent_req *subreq)
1101 {
1102         struct tevent_req *req = tevent_req_callback_data(
1103                 subreq, struct tevent_req);
1104         struct test6_read_state *state = tevent_req_data(
1105                 req, struct test6_read_state);
1106         int ret;
1107         bool status;
1108
1109         status = sock_socket_write_recv(subreq, &ret);
1110         TALLOC_FREE(subreq);
1111         if (! status) {
1112                 tevent_req_error(req, ret);
1113                 return;
1114         }
1115
1116         state->server_state->done = 1;
1117         tevent_req_done(req);
1118 }
1119
1120 static bool test6_read_recv(struct tevent_req *req, int *perr)
1121 {
1122         int ret;
1123
1124         if (tevent_req_is_unix_error(req, &ret)) {
1125                 if (perr != NULL) {
1126                         *perr = ret;
1127                 }
1128                 return false;
1129         }
1130
1131         return true;
1132 }
1133
1134 static struct sock_socket_funcs test6_client_funcs = {
1135         .read_send = test6_read_send,
1136         .read_recv = test6_read_recv,
1137 };
1138
1139 struct test6_wait_state {
1140         struct test6_server_state *server_state;
1141 };
1142
1143 static void test6_wait_done(struct tevent_req *subreq);
1144
1145 static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx,
1146                                           struct tevent_context *ev,
1147                                           void *private_data)
1148 {
1149         struct test6_server_state *server_state =
1150                 (struct test6_server_state *)private_data;
1151         struct tevent_req *req, *subreq;
1152         struct test6_wait_state *state;
1153         ssize_t nwritten;
1154         int ret = 1;
1155
1156         nwritten = write(server_state->fd, &ret, sizeof(ret));
1157         assert(nwritten == sizeof(ret));
1158         close(server_state->fd);
1159         server_state->fd = -1;
1160
1161         req = tevent_req_create(mem_ctx, &state, struct test6_wait_state);
1162         if (req == NULL) {
1163                 return NULL;
1164         }
1165
1166         state->server_state = (struct test6_server_state *)private_data;
1167
1168         subreq = tevent_wakeup_send(state, ev,
1169                                     tevent_timeval_current_ofs(10,0));
1170         if (tevent_req_nomem(subreq, req)) {
1171                 return tevent_req_post(req, ev);
1172         }
1173         tevent_req_set_callback(subreq, test6_wait_done, req);
1174
1175         return req;
1176 }
1177
1178 static void test6_wait_done(struct tevent_req *subreq)
1179 {
1180         struct tevent_req *req = tevent_req_callback_data(
1181                 subreq, struct tevent_req);
1182         struct test6_wait_state *state = tevent_req_data(
1183                 req, struct test6_wait_state);
1184         bool status;
1185
1186         status = tevent_wakeup_recv(subreq);
1187         TALLOC_FREE(subreq);
1188         if (! status) {
1189                 tevent_req_error(req, EIO);
1190                 return;
1191         }
1192
1193         if (state->server_state->done == 0) {
1194                 tevent_req_error(req, EIO);
1195                 return;
1196         }
1197
1198         tevent_req_done(req);
1199 }
1200
1201 static bool test6_wait_recv(struct tevent_req *req, int *perr)
1202 {
1203         int ret;
1204
1205         if (tevent_req_is_unix_error(req, &ret)) {
1206                 if (perr != NULL) {
1207                         *perr = ret;
1208                 }
1209                 return false;
1210         }
1211
1212         return true;
1213 }
1214
1215 static struct sock_daemon_funcs test6_funcs = {
1216         .wait_send = test6_wait_send,
1217         .wait_recv = test6_wait_recv,
1218 };
1219
1220 static void test6(TALLOC_CTX *mem_ctx, const char *pidfile,
1221                   const char *sockpath)
1222 {
1223         pid_t pid_server, pid;
1224         int fd[2], ret;
1225         ssize_t n;
1226
1227         pid = getpid();
1228
1229         ret = pipe(fd);
1230         assert(ret == 0);
1231
1232         pid_server = fork();
1233         assert(pid_server != -1);
1234
1235         if (pid_server == 0) {
1236                 struct tevent_context *ev;
1237                 struct sock_daemon_context *sockd;
1238                 struct test6_server_state server_state = { 0 };
1239
1240                 close(fd[0]);
1241
1242                 ev = tevent_context_init(mem_ctx);
1243                 assert(ev != NULL);
1244
1245                 server_state.fd = fd[1];
1246
1247                 ret = sock_daemon_setup(mem_ctx, "test6", "file:", "NOTICE",
1248                                         &test6_funcs, &server_state,
1249                                         &sockd);
1250                 assert(ret == 0);
1251
1252                 server_state.sockd = sockd;
1253                 server_state.done = 0;
1254
1255                 ret = sock_daemon_add_unix(sockd, sockpath,
1256                                            &test6_client_funcs, &server_state);
1257                 assert(ret == 0);
1258
1259                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
1260                 assert(ret == 0);
1261
1262                 exit(0);
1263         }
1264
1265         close(fd[1]);
1266
1267         n = read(fd[0], &ret, sizeof(ret));
1268         assert(n == sizeof(ret));
1269         assert(ret == 1);
1270
1271         close(fd[0]);
1272
1273         test6_client(sockpath);
1274
1275         pid = wait(&ret);
1276         assert(pid != -1);
1277 }
1278
1279 /*
1280  * test7
1281  *
1282  * Start daemon twice, confirm PID file contention
1283  */
1284
1285 static void test7(TALLOC_CTX *mem_ctx, const char *pidfile,
1286                   const char *sockpath)
1287 {
1288         struct sock_daemon_funcs test7_funcs;
1289         struct stat st;
1290         int fd[2];
1291         pid_t pid, pid2;
1292         int ret;
1293         struct tevent_context *ev;
1294         struct sock_daemon_context *sockd;
1295         ssize_t n;
1296
1297         /* Reuse test2 funcs for the startup synchronisation */
1298         test7_funcs = (struct sock_daemon_funcs) {
1299                 .startup = test2_startup,
1300                 .reconfigure = test2_reconfigure,
1301                 .shutdown = test2_shutdown,
1302         };
1303
1304         ret = pipe(fd);
1305         assert(ret == 0);
1306
1307         pid = fork();
1308         assert(pid != -1);
1309
1310         if (pid == 0) {
1311                 close(fd[0]);
1312
1313                 ev = tevent_context_init(mem_ctx);
1314                 assert(ev != NULL);
1315
1316                 ret = sock_daemon_setup(mem_ctx, "test7", "file:", "NOTICE",
1317                                         &test7_funcs, &fd[1], &sockd);
1318                 assert(ret == 0);
1319
1320                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1321                 assert(ret == EINTR);
1322
1323                 exit(0);
1324         }
1325
1326         close(fd[1]);
1327
1328         n = read(fd[0], &ret, sizeof(ret));
1329         assert(n == sizeof(ret));
1330         assert(ret == 1);
1331
1332         ret = stat(pidfile, &st);
1333         assert(ret == 0);
1334         assert(S_ISREG(st.st_mode));
1335
1336         ev = tevent_context_init(mem_ctx);
1337         assert(ev != NULL);
1338
1339         ret = sock_daemon_setup(mem_ctx, "test7-parent", "file:", "NOTICE",
1340                                 &test7_funcs, &fd[1], &sockd);
1341         assert(ret == 0);
1342
1343         ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1344         assert(ret == EEXIST);
1345
1346         ret = kill(pid, SIGTERM);
1347         assert(ret == 0);
1348
1349         n = read(fd[0], &ret, sizeof(ret));
1350         assert(n == sizeof(ret));
1351         assert(ret == 3);
1352
1353         pid2 = waitpid(pid, &ret, 0);
1354         assert(pid2 == pid);
1355         assert(WEXITSTATUS(ret) == 0);
1356
1357         close(fd[0]);
1358 }
1359
1360 /*
1361  * test8
1362  *
1363  * Start daemon, confirm that create_session argument works as expected
1364  */
1365
1366 static void test8(TALLOC_CTX *mem_ctx, const char *pidfile,
1367                   const char *sockpath)
1368 {
1369         int fd[2];
1370         pid_t pid, pid2, sid;
1371         int ret;
1372         struct tevent_context *ev;
1373         struct sock_daemon_context *sockd;
1374         ssize_t n;
1375
1376         ret = pipe(fd);
1377         assert(ret == 0);
1378
1379         pid = fork();
1380         assert(pid != -1);
1381
1382         if (pid == 0) {
1383                 /* Reuse test2 funcs for the startup synchronisation */
1384                 struct sock_daemon_funcs test8_funcs = {
1385                         .startup = test2_startup,
1386                 };
1387
1388                 close(fd[0]);
1389
1390                 ev = tevent_context_init(mem_ctx);
1391                 assert(ev != NULL);
1392
1393                 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1394                                         &test8_funcs, &fd[1], &sockd);
1395                 assert(ret == 0);
1396
1397                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1398                 assert(ret == EINTR);
1399
1400                 exit(0);
1401         }
1402
1403         close(fd[1]);
1404
1405         n = read(fd[0], &ret, sizeof(ret));
1406         assert(n == sizeof(ret));
1407         assert(ret == 1);
1408
1409         /* create_session false above, so pid != sid */
1410         sid = getsid(pid);
1411         assert(pid != sid);
1412
1413         ret = kill(pid, SIGTERM);
1414         assert(ret == 0);
1415
1416         pid2 = waitpid(pid, &ret, 0);
1417         assert(pid2 == pid);
1418         assert(WEXITSTATUS(ret) == 0);
1419
1420         close(fd[0]);
1421
1422         ret = pipe(fd);
1423         assert(ret == 0);
1424
1425         pid = fork();
1426         assert(pid != -1);
1427
1428         if (pid == 0) {
1429                 /* Reuse test2 funcs for the startup synchronisation */
1430                 struct sock_daemon_funcs test8_funcs = {
1431                         .startup = test2_startup,
1432                 };
1433
1434                 close(fd[0]);
1435
1436                 ev = tevent_context_init(mem_ctx);
1437                 assert(ev != NULL);
1438
1439                 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1440                                         &test8_funcs, &fd[1], &sockd);
1441                 assert(ret == 0);
1442
1443                 ret = sock_daemon_run(ev, sockd, pidfile, false, true, -1);
1444                 assert(ret == EINTR);
1445
1446                 exit(0);
1447         }
1448
1449         close(fd[1]);
1450
1451         n = read(fd[0], &ret, sizeof(ret));
1452         assert(n == sizeof(ret));
1453         assert(ret == 1);
1454
1455         /* create_session true above, so pid == sid */
1456         sid = getsid(pid);
1457         assert(pid == sid);
1458
1459         ret = kill(pid, SIGTERM);
1460         assert(ret == 0);
1461
1462         pid2 = waitpid(pid, &ret, 0);
1463         assert(pid2 == pid);
1464         assert(WEXITSTATUS(ret) == 0);
1465
1466         close(fd[0]);
1467 }
1468
1469 /*
1470  * test9
1471  *
1472  * Confirm that do_fork causes the daemon to be forked as a separate child
1473  */
1474
1475 static void test9(TALLOC_CTX *mem_ctx, const char *pidfile,
1476                   const char *sockpath)
1477 {
1478         int fd[2];
1479         pid_t pid, pid2;
1480         int ret;
1481         struct tevent_context *ev;
1482         struct sock_daemon_context *sockd;
1483         ssize_t n;
1484         int pidfile_fd;
1485         char pidstr[20] = { 0 };
1486         struct stat st;
1487
1488         ret = pipe(fd);
1489         assert(ret == 0);
1490
1491         pid = fork();
1492         assert(pid != -1);
1493
1494         if (pid == 0) {
1495                 /* Reuse test2 funcs for the startup synchronisation */
1496                 struct sock_daemon_funcs test9_funcs = {
1497                         .startup = test2_startup,
1498                 };
1499
1500                 close(fd[0]);
1501
1502                 ev = tevent_context_init(mem_ctx);
1503                 assert(ev != NULL);
1504
1505                 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1506                                         &test9_funcs, &fd[1], &sockd);
1507                 assert(ret == 0);
1508
1509                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1510                 assert(ret == EINTR);
1511
1512                 exit(0);
1513         }
1514
1515         close(fd[1]);
1516
1517         n = read(fd[0], &ret, sizeof(ret));
1518         assert(n == sizeof(ret));
1519         assert(ret == 1);
1520
1521         /* do_fork false above, so pid should be active */
1522         ret = kill(pid, 0);
1523         assert(ret == 0);
1524
1525         ret = kill(pid, SIGTERM);
1526         assert(ret == 0);
1527
1528         pid2 = waitpid(pid, &ret, 0);
1529         assert(pid2 == pid);
1530         assert(WEXITSTATUS(ret) == 0);
1531
1532         close(fd[0]);
1533
1534         ret = pipe(fd);
1535         assert(ret == 0);
1536
1537         pid = fork();
1538         assert(pid != -1);
1539
1540         if (pid == 0) {
1541                 /* Reuse test2 funcs for the startup synchronisation */
1542                 struct sock_daemon_funcs test9_funcs = {
1543                         .startup = test2_startup,
1544                         .shutdown = test2_shutdown,
1545                 };
1546
1547                 close(fd[0]);
1548
1549                 ev = tevent_context_init(mem_ctx);
1550                 assert(ev != NULL);
1551
1552                 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1553                                         &test9_funcs, &fd[1], &sockd);
1554                 assert(ret == 0);
1555
1556                 ret = sock_daemon_run(ev, sockd, pidfile, true, false, -1);
1557                 assert(ret == EINTR);
1558
1559                 exit(0);
1560         }
1561
1562         close(fd[1]);
1563
1564         n = read(fd[0], &ret, sizeof(ret));
1565         assert(n == sizeof(ret));
1566         assert(ret == 1);
1567
1568         /* do_fork true above, so pid should have exited */
1569         pid2 = waitpid(pid, &ret, 0);
1570         assert(pid2 == pid);
1571         assert(WEXITSTATUS(ret) == 0);
1572
1573         pidfile_fd = open(pidfile, O_RDONLY, 0644);
1574         assert(pidfile_fd != -1);
1575         n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1576         assert(n != -1);
1577         pid2 = (pid_t)atoi(pidstr);
1578         assert(pid != pid2);
1579         close(pidfile_fd);
1580
1581         ret = kill(pid2, SIGTERM);
1582         assert(ret == 0);
1583
1584         n = read(fd[0], &ret, sizeof(ret));
1585         assert(n == sizeof(ret));
1586         assert(ret == 3);
1587
1588         /*
1589          * pid2 isn't our child, so can't call waitpid().  kill(pid2, 0)
1590          * is unreliable - pid2 may have been recycled.  Above indicates
1591          * that the shutdown function was called, so just do 1 final
1592          * check to see if pidfile has been removed.
1593          */
1594         ret = stat(sockpath, &st);
1595         assert(ret == -1);
1596
1597         close(fd[0]);
1598 }
1599
1600 static void test10_shutdown(void *private_data)
1601 {
1602         int fd = *(int *)private_data;
1603         int ret = 3;
1604         ssize_t nwritten;
1605
1606         nwritten = write(fd, &ret, sizeof(ret));
1607         assert(nwritten == sizeof(ret));
1608 }
1609
1610 struct test10_wait_state {
1611 };
1612
1613 static void test10_wait_done(struct tevent_req *subreq);
1614
1615 static struct tevent_req *test10_wait_send(TALLOC_CTX *mem_ctx,
1616                                            struct tevent_context *ev,
1617                                            void *private_data)
1618 {
1619         int fd = *(int *)private_data;
1620         struct tevent_req *req, *subreq;
1621         struct test10_wait_state *state;
1622         size_t nwritten;
1623         int ret = 1;
1624
1625         req = tevent_req_create(mem_ctx, &state, struct test10_wait_state);
1626         if (req == NULL) {
1627                 return NULL;
1628         }
1629
1630         subreq = tevent_wakeup_send(state, ev,
1631                                     tevent_timeval_current_ofs(10, 0));
1632         if (tevent_req_nomem(subreq, req)) {
1633                 return tevent_req_post(req, ev);
1634         }
1635         tevent_req_set_callback(subreq, test10_wait_done, req);
1636
1637         nwritten = write(fd, &ret, sizeof(ret));
1638         assert(nwritten == sizeof(ret));
1639
1640         return req;
1641 }
1642
1643 static void test10_wait_done(struct tevent_req *subreq)
1644 {
1645         struct tevent_req *req = tevent_req_callback_data(
1646                 subreq, struct tevent_req);
1647         bool status;
1648
1649         status = tevent_wakeup_recv(subreq);
1650         if (! status) {
1651                 tevent_req_error(req, EIO);
1652                 return;
1653         }
1654
1655         tevent_req_done(req);
1656 }
1657
1658 static bool test10_wait_recv(struct tevent_req *req, int *perr)
1659 {
1660         int ret;
1661
1662         if (tevent_req_is_unix_error(req, &ret)) {
1663                 if (perr != NULL) {
1664                         *perr = ret;
1665                 }
1666                 return false;
1667         }
1668
1669         return true;
1670 }
1671
1672 static struct sock_daemon_funcs test10_funcs = {
1673         .shutdown = test10_shutdown,
1674         .wait_send = test10_wait_send,
1675         .wait_recv = test10_wait_recv,
1676 };
1677
1678 /*
1679  * test10
1680  *
1681  * Confirm that the daemon starts successfully if there is a stale socket
1682  */
1683
1684 static void test10(TALLOC_CTX *mem_ctx, const char *pidfile,
1685                   const char *sockpath)
1686 {
1687         struct stat st;
1688         int fd[2];
1689         pid_t pid, pid2;
1690         int ret;
1691         ssize_t n;
1692         int pidfile_fd;
1693         char pidstr[20] = { 0 };
1694
1695         ret = pipe(fd);
1696         assert(ret == 0);
1697
1698         pid = fork();
1699         assert(pid != -1);
1700
1701         if (pid == 0) {
1702                 struct tevent_context *ev;
1703                 struct sock_daemon_context *sockd;
1704
1705                 close(fd[0]);
1706
1707                 ev = tevent_context_init(mem_ctx);
1708                 assert(ev != NULL);
1709
1710                 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1711                                         &test10_funcs, &fd[1], &sockd);
1712                 assert(ret == 0);
1713
1714                 ret = sock_daemon_add_unix(sockd, sockpath,
1715                                            &dummy_socket_funcs, NULL);
1716                 assert(ret == 0);
1717
1718                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1719                 assert(ret == EINTR);
1720
1721                 exit(0);
1722         }
1723
1724         close(fd[1]);
1725
1726         n = read(fd[0], &ret, sizeof(ret));
1727         assert(n == sizeof(ret));
1728         assert(ret == 1);
1729
1730         /* KILL will leave PID file and socket behind */
1731         ret = kill (pid, SIGKILL);
1732         assert(ret == 0);
1733
1734         ret = stat(sockpath, &st);
1735         assert(ret == 0);
1736
1737         close(fd[0]);
1738
1739         ret = pipe(fd);
1740         assert(ret == 0);
1741
1742         pid = fork();
1743         assert(pid != -1);
1744
1745         if (pid == 0) {
1746                 struct tevent_context *ev;
1747                 struct sock_daemon_context *sockd;
1748
1749                 close(fd[0]);
1750
1751                 ev = tevent_context_init(mem_ctx);
1752                 assert(ev != NULL);
1753
1754                 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1755                                         &test10_funcs, &fd[1], &sockd);
1756                 assert(ret == 0);
1757
1758                 ret = sock_daemon_add_unix(sockd, sockpath,
1759                                            &dummy_socket_funcs, NULL);
1760                 assert(ret == 0);
1761
1762                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1763                 assert(ret == EINTR);
1764
1765                 exit(0);
1766         }
1767
1768         close(fd[1]);
1769
1770         n = read(fd[0], &ret, sizeof(ret));
1771         assert(n == sizeof(ret));
1772         assert(ret == 1);
1773
1774         pidfile_fd = open(pidfile, O_RDONLY, 0644);
1775         assert(pidfile_fd != -1);
1776         n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1777         assert(n != -1);
1778         pid2 = (pid_t)atoi(pidstr);
1779         assert(pid == pid2);
1780         close(pidfile_fd);
1781
1782         ret = kill(pid, SIGTERM);
1783         assert(ret == 0);
1784
1785         n = read(fd[0], &ret, sizeof(ret));
1786         assert(n == sizeof(ret));
1787         assert(ret == 3);
1788
1789         pid2 = waitpid(pid, &ret, 0);
1790         assert(pid2 == pid);
1791         assert(WEXITSTATUS(ret) == 0);
1792
1793         close(fd[0]);
1794
1795         ret = stat(pidfile, &st);
1796         assert(ret == -1);
1797
1798         ret = stat(sockpath, &st);
1799         assert(ret == -1);
1800 }
1801
1802 int main(int argc, const char **argv)
1803 {
1804         TALLOC_CTX *mem_ctx;
1805         const char *pidfile, *sockpath;
1806         int num;
1807
1808         if (argc != 4) {
1809                 fprintf(stderr, "%s <pidfile> <sockpath> <testnum>\n", argv[0]);
1810                 exit(1);
1811         }
1812
1813         pidfile = argv[1];
1814         sockpath = argv[2];
1815         num = atoi(argv[3]);
1816
1817         mem_ctx = talloc_new(NULL);
1818         assert(mem_ctx != NULL);
1819
1820         switch (num) {
1821         case 1:
1822                 test1(mem_ctx, pidfile, sockpath);
1823                 break;
1824
1825         case 2:
1826                 test2(mem_ctx, pidfile, sockpath);
1827                 break;
1828
1829         case 3:
1830                 test3(mem_ctx, pidfile, sockpath);
1831                 break;
1832
1833         case 4:
1834                 test4(mem_ctx, pidfile, sockpath);
1835                 break;
1836
1837         case 5:
1838                 test5(mem_ctx, pidfile, sockpath);
1839                 break;
1840
1841         case 6:
1842                 test6(mem_ctx, pidfile, sockpath);
1843                 break;
1844
1845         case 7:
1846                 test7(mem_ctx, pidfile, sockpath);
1847                 break;
1848
1849         case 8:
1850                 test8(mem_ctx, pidfile, sockpath);
1851                 break;
1852
1853         case 9:
1854                 test9(mem_ctx, pidfile, sockpath);
1855                 break;
1856
1857         case 10:
1858                 test10(mem_ctx, pidfile, sockpath);
1859                 break;
1860
1861         default:
1862                 fprintf(stderr, "Unknown test number %d\n", num);
1863         }
1864
1865         return 0;
1866 }