Merge branch 'ab/sparse-index-cleanup'
[git] / t / helper / test-simple-ipc.c
1 /*
2  * test-simple-ipc.c: verify that the Inter-Process Communication works.
3  */
4
5 #include "test-tool.h"
6 #include "cache.h"
7 #include "strbuf.h"
8 #include "simple-ipc.h"
9 #include "parse-options.h"
10 #include "thread-utils.h"
11 #include "strvec.h"
12
13 #ifndef SUPPORTS_SIMPLE_IPC
14 int cmd__simple_ipc(int argc, const char **argv)
15 {
16         die("simple IPC not available on this platform");
17 }
18 #else
19
20 /*
21  * The test daemon defines an "application callback" that supports a
22  * series of commands (see `test_app_cb()`).
23  *
24  * Unknown commands are caught here and we send an error message back
25  * to the client process.
26  */
27 static int app__unhandled_command(const char *command,
28                                   ipc_server_reply_cb *reply_cb,
29                                   struct ipc_server_reply_data *reply_data)
30 {
31         struct strbuf buf = STRBUF_INIT;
32         int ret;
33
34         strbuf_addf(&buf, "unhandled command: %s", command);
35         ret = reply_cb(reply_data, buf.buf, buf.len);
36         strbuf_release(&buf);
37
38         return ret;
39 }
40
41 /*
42  * Reply with a single very large buffer.  This is to ensure that
43  * long response are properly handled -- whether the chunking occurs
44  * in the kernel or in the (probably pkt-line) layer.
45  */
46 #define BIG_ROWS (10000)
47 static int app__big_command(ipc_server_reply_cb *reply_cb,
48                             struct ipc_server_reply_data *reply_data)
49 {
50         struct strbuf buf = STRBUF_INIT;
51         int row;
52         int ret;
53
54         for (row = 0; row < BIG_ROWS; row++)
55                 strbuf_addf(&buf, "big: %.75d\n", row);
56
57         ret = reply_cb(reply_data, buf.buf, buf.len);
58         strbuf_release(&buf);
59
60         return ret;
61 }
62
63 /*
64  * Reply with a series of lines.  This is to ensure that we can incrementally
65  * compute the response and chunk it to the client.
66  */
67 #define CHUNK_ROWS (10000)
68 static int app__chunk_command(ipc_server_reply_cb *reply_cb,
69                               struct ipc_server_reply_data *reply_data)
70 {
71         struct strbuf buf = STRBUF_INIT;
72         int row;
73         int ret;
74
75         for (row = 0; row < CHUNK_ROWS; row++) {
76                 strbuf_setlen(&buf, 0);
77                 strbuf_addf(&buf, "big: %.75d\n", row);
78                 ret = reply_cb(reply_data, buf.buf, buf.len);
79         }
80
81         strbuf_release(&buf);
82
83         return ret;
84 }
85
86 /*
87  * Slowly reply with a series of lines.  This is to model an expensive to
88  * compute chunked response (which might happen if this callback is running
89  * in a thread and is fighting for a lock with other threads).
90  */
91 #define SLOW_ROWS     (1000)
92 #define SLOW_DELAY_MS (10)
93 static int app__slow_command(ipc_server_reply_cb *reply_cb,
94                              struct ipc_server_reply_data *reply_data)
95 {
96         struct strbuf buf = STRBUF_INIT;
97         int row;
98         int ret;
99
100         for (row = 0; row < SLOW_ROWS; row++) {
101                 strbuf_setlen(&buf, 0);
102                 strbuf_addf(&buf, "big: %.75d\n", row);
103                 ret = reply_cb(reply_data, buf.buf, buf.len);
104                 sleep_millisec(SLOW_DELAY_MS);
105         }
106
107         strbuf_release(&buf);
108
109         return ret;
110 }
111
112 /*
113  * The client sent a command followed by a (possibly very) large buffer.
114  */
115 static int app__sendbytes_command(const char *received,
116                                   ipc_server_reply_cb *reply_cb,
117                                   struct ipc_server_reply_data *reply_data)
118 {
119         struct strbuf buf_resp = STRBUF_INIT;
120         const char *p = "?";
121         int len_ballast = 0;
122         int k;
123         int errs = 0;
124         int ret;
125
126         if (skip_prefix(received, "sendbytes ", &p))
127                 len_ballast = strlen(p);
128
129         /*
130          * Verify that the ballast is n copies of a single letter.
131          * And that the multi-threaded IO layer didn't cross the streams.
132          */
133         for (k = 1; k < len_ballast; k++)
134                 if (p[k] != p[0])
135                         errs++;
136
137         if (errs)
138                 strbuf_addf(&buf_resp, "errs:%d\n", errs);
139         else
140                 strbuf_addf(&buf_resp, "rcvd:%c%08d\n", p[0], len_ballast);
141
142         ret = reply_cb(reply_data, buf_resp.buf, buf_resp.len);
143
144         strbuf_release(&buf_resp);
145
146         return ret;
147 }
148
149 /*
150  * An arbitrary fixed address to verify that the application instance
151  * data is handled properly.
152  */
153 static int my_app_data = 42;
154
155 static ipc_server_application_cb test_app_cb;
156
157 /*
158  * This is the "application callback" that sits on top of the
159  * "ipc-server".  It completely defines the set of commands supported
160  * by this application.
161  */
162 static int test_app_cb(void *application_data,
163                        const char *command,
164                        ipc_server_reply_cb *reply_cb,
165                        struct ipc_server_reply_data *reply_data)
166 {
167         /*
168          * Verify that we received the application-data that we passed
169          * when we started the ipc-server.  (We have several layers of
170          * callbacks calling callbacks and it's easy to get things mixed
171          * up (especially when some are "void*").)
172          */
173         if (application_data != (void*)&my_app_data)
174                 BUG("application_cb: application_data pointer wrong");
175
176         if (!strcmp(command, "quit")) {
177                 /*
178                  * The client sent a "quit" command.  This is an async
179                  * request for the server to shutdown.
180                  *
181                  * We DO NOT send the client a response message
182                  * (because we have nothing to say and the other
183                  * server threads have not yet stopped).
184                  *
185                  * Tell the ipc-server layer to start shutting down.
186                  * This includes: stop listening for new connections
187                  * on the socket/pipe and telling all worker threads
188                  * to finish/drain their outgoing responses to other
189                  * clients.
190                  *
191                  * This DOES NOT force an immediate sync shutdown.
192                  */
193                 return SIMPLE_IPC_QUIT;
194         }
195
196         if (!strcmp(command, "ping")) {
197                 const char *answer = "pong";
198                 return reply_cb(reply_data, answer, strlen(answer));
199         }
200
201         if (!strcmp(command, "big"))
202                 return app__big_command(reply_cb, reply_data);
203
204         if (!strcmp(command, "chunk"))
205                 return app__chunk_command(reply_cb, reply_data);
206
207         if (!strcmp(command, "slow"))
208                 return app__slow_command(reply_cb, reply_data);
209
210         if (starts_with(command, "sendbytes "))
211                 return app__sendbytes_command(command, reply_cb, reply_data);
212
213         return app__unhandled_command(command, reply_cb, reply_data);
214 }
215
216 struct cl_args
217 {
218         const char *subcommand;
219         const char *path;
220         const char *token;
221
222         int nr_threads;
223         int max_wait_sec;
224         int bytecount;
225         int batchsize;
226
227         char bytevalue;
228 };
229
230 static struct cl_args cl_args = {
231         .subcommand = NULL,
232         .path = "ipc-test",
233         .token = NULL,
234
235         .nr_threads = 5,
236         .max_wait_sec = 60,
237         .bytecount = 1024,
238         .batchsize = 10,
239
240         .bytevalue = 'x',
241 };
242
243 /*
244  * This process will run as a simple-ipc server and listen for IPC commands
245  * from client processes.
246  */
247 static int daemon__run_server(void)
248 {
249         int ret;
250
251         struct ipc_server_opts opts = {
252                 .nr_threads = cl_args.nr_threads,
253         };
254
255         /*
256          * Synchronously run the ipc-server.  We don't need any application
257          * instance data, so pass an arbitrary pointer (that we'll later
258          * verify made the round trip).
259          */
260         ret = ipc_server_run(cl_args.path, &opts, test_app_cb, (void*)&my_app_data);
261         if (ret == -2)
262                 error(_("socket/pipe already in use: '%s'"), cl_args.path);
263         else if (ret == -1)
264                 error_errno(_("could not start server on: '%s'"), cl_args.path);
265
266         return ret;
267 }
268
269 #ifndef GIT_WINDOWS_NATIVE
270 /*
271  * This is adapted from `daemonize()`.  Use `fork()` to directly create and
272  * run the daemon in a child process.
273  */
274 static int spawn_server(pid_t *pid)
275 {
276         struct ipc_server_opts opts = {
277                 .nr_threads = cl_args.nr_threads,
278         };
279
280         *pid = fork();
281
282         switch (*pid) {
283         case 0:
284                 if (setsid() == -1)
285                         error_errno(_("setsid failed"));
286                 close(0);
287                 close(1);
288                 close(2);
289                 sanitize_stdfds();
290
291                 return ipc_server_run(cl_args.path, &opts, test_app_cb,
292                                       (void*)&my_app_data);
293
294         case -1:
295                 return error_errno(_("could not spawn daemon in the background"));
296
297         default:
298                 return 0;
299         }
300 }
301 #else
302 /*
303  * Conceptually like `daemonize()` but different because Windows does not
304  * have `fork(2)`.  Spawn a normal Windows child process but without the
305  * limitations of `start_command()` and `finish_command()`.
306  */
307 static int spawn_server(pid_t *pid)
308 {
309         char test_tool_exe[MAX_PATH];
310         struct strvec args = STRVEC_INIT;
311         int in, out;
312
313         GetModuleFileNameA(NULL, test_tool_exe, MAX_PATH);
314
315         in = open("/dev/null", O_RDONLY);
316         out = open("/dev/null", O_WRONLY);
317
318         strvec_push(&args, test_tool_exe);
319         strvec_push(&args, "simple-ipc");
320         strvec_push(&args, "run-daemon");
321         strvec_pushf(&args, "--name=%s", cl_args.path);
322         strvec_pushf(&args, "--threads=%d", cl_args.nr_threads);
323
324         *pid = mingw_spawnvpe(args.v[0], args.v, NULL, NULL, in, out, out);
325         close(in);
326         close(out);
327
328         strvec_clear(&args);
329
330         if (*pid < 0)
331                 return error(_("could not spawn daemon in the background"));
332
333         return 0;
334 }
335 #endif
336
337 /*
338  * This is adapted from `wait_or_whine()`.  Watch the child process and
339  * let it get started and begin listening for requests on the socket
340  * before reporting our success.
341  */
342 static int wait_for_server_startup(pid_t pid_child)
343 {
344         int status;
345         pid_t pid_seen;
346         enum ipc_active_state s;
347         time_t time_limit, now;
348
349         time(&time_limit);
350         time_limit += cl_args.max_wait_sec;
351
352         for (;;) {
353                 pid_seen = waitpid(pid_child, &status, WNOHANG);
354
355                 if (pid_seen == -1)
356                         return error_errno(_("waitpid failed"));
357
358                 else if (pid_seen == 0) {
359                         /*
360                          * The child is still running (this should be
361                          * the normal case).  Try to connect to it on
362                          * the socket and see if it is ready for
363                          * business.
364                          *
365                          * If there is another daemon already running,
366                          * our child will fail to start (possibly
367                          * after a timeout on the lock), but we don't
368                          * care (who responds) if the socket is live.
369                          */
370                         s = ipc_get_active_state(cl_args.path);
371                         if (s == IPC_STATE__LISTENING)
372                                 return 0;
373
374                         time(&now);
375                         if (now > time_limit)
376                                 return error(_("daemon not online yet"));
377
378                         continue;
379                 }
380
381                 else if (pid_seen == pid_child) {
382                         /*
383                          * The new child daemon process shutdown while
384                          * it was starting up, so it is not listening
385                          * on the socket.
386                          *
387                          * Try to ping the socket in the odd chance
388                          * that another daemon started (or was already
389                          * running) while our child was starting.
390                          *
391                          * Again, we don't care who services the socket.
392                          */
393                         s = ipc_get_active_state(cl_args.path);
394                         if (s == IPC_STATE__LISTENING)
395                                 return 0;
396
397                         /*
398                          * We don't care about the WEXITSTATUS() nor
399                          * any of the WIF*(status) values because
400                          * `cmd__simple_ipc()` does the `!!result`
401                          * trick on all function return values.
402                          *
403                          * So it is sufficient to just report the
404                          * early shutdown as an error.
405                          */
406                         return error(_("daemon failed to start"));
407                 }
408
409                 else
410                         return error(_("waitpid is confused"));
411         }
412 }
413
414 /*
415  * This process will start a simple-ipc server in a background process and
416  * wait for it to become ready.  This is like `daemonize()` but gives us
417  * more control and better error reporting (and makes it easier to write
418  * unit tests).
419  */
420 static int daemon__start_server(void)
421 {
422         pid_t pid_child;
423         int ret;
424
425         /*
426          * Run the actual daemon in a background process.
427          */
428         ret = spawn_server(&pid_child);
429         if (pid_child <= 0)
430                 return ret;
431
432         /*
433          * Let the parent wait for the child process to get started
434          * and begin listening for requests on the socket.
435          */
436         ret = wait_for_server_startup(pid_child);
437
438         return ret;
439 }
440
441 /*
442  * This process will run a quick probe to see if a simple-ipc server
443  * is active on this path.
444  *
445  * Returns 0 if the server is alive.
446  */
447 static int client__probe_server(void)
448 {
449         enum ipc_active_state s;
450
451         s = ipc_get_active_state(cl_args.path);
452         switch (s) {
453         case IPC_STATE__LISTENING:
454                 return 0;
455
456         case IPC_STATE__NOT_LISTENING:
457                 return error("no server listening at '%s'", cl_args.path);
458
459         case IPC_STATE__PATH_NOT_FOUND:
460                 return error("path not found '%s'", cl_args.path);
461
462         case IPC_STATE__INVALID_PATH:
463                 return error("invalid pipe/socket name '%s'", cl_args.path);
464
465         case IPC_STATE__OTHER_ERROR:
466         default:
467                 return error("other error for '%s'", cl_args.path);
468         }
469 }
470
471 /*
472  * Send an IPC command token to an already-running server daemon and
473  * print the response.
474  *
475  * This is a simple 1 word command/token that `test_app_cb()` (in the
476  * daemon process) will understand.
477  */
478 static int client__send_ipc(void)
479 {
480         const char *command = "(no-command)";
481         struct strbuf buf = STRBUF_INIT;
482         struct ipc_client_connect_options options
483                 = IPC_CLIENT_CONNECT_OPTIONS_INIT;
484
485         if (cl_args.token && *cl_args.token)
486                 command = cl_args.token;
487
488         options.wait_if_busy = 1;
489         options.wait_if_not_found = 0;
490
491         if (!ipc_client_send_command(cl_args.path, &options, command, &buf)) {
492                 if (buf.len) {
493                         printf("%s\n", buf.buf);
494                         fflush(stdout);
495                 }
496                 strbuf_release(&buf);
497
498                 return 0;
499         }
500
501         return error("failed to send '%s' to '%s'", command, cl_args.path);
502 }
503
504 /*
505  * Send an IPC command to an already-running server and ask it to
506  * shutdown.  "send quit" is an async request and queues a shutdown
507  * event in the server, so we spin and wait here for it to actually
508  * shutdown to make the unit tests a little easier to write.
509  */
510 static int client__stop_server(void)
511 {
512         int ret;
513         time_t time_limit, now;
514         enum ipc_active_state s;
515
516         time(&time_limit);
517         time_limit += cl_args.max_wait_sec;
518
519         cl_args.token = "quit";
520
521         ret = client__send_ipc();
522         if (ret)
523                 return ret;
524
525         for (;;) {
526                 sleep_millisec(100);
527
528                 s = ipc_get_active_state(cl_args.path);
529
530                 if (s != IPC_STATE__LISTENING) {
531                         /*
532                          * The socket/pipe is gone and/or has stopped
533                          * responding.  Lets assume that the daemon
534                          * process has exited too.
535                          */
536                         return 0;
537                 }
538
539                 time(&now);
540                 if (now > time_limit)
541                         return error(_("daemon has not shutdown yet"));
542         }
543 }
544
545 /*
546  * Send an IPC command followed by ballast to confirm that a large
547  * message can be sent and that the kernel or pkt-line layers will
548  * properly chunk it and that the daemon receives the entire message.
549  */
550 static int do_sendbytes(int bytecount, char byte, const char *path,
551                         const struct ipc_client_connect_options *options)
552 {
553         struct strbuf buf_send = STRBUF_INIT;
554         struct strbuf buf_resp = STRBUF_INIT;
555
556         strbuf_addstr(&buf_send, "sendbytes ");
557         strbuf_addchars(&buf_send, byte, bytecount);
558
559         if (!ipc_client_send_command(path, options, buf_send.buf, &buf_resp)) {
560                 strbuf_rtrim(&buf_resp);
561                 printf("sent:%c%08d %s\n", byte, bytecount, buf_resp.buf);
562                 fflush(stdout);
563                 strbuf_release(&buf_send);
564                 strbuf_release(&buf_resp);
565
566                 return 0;
567         }
568
569         return error("client failed to sendbytes(%d, '%c') to '%s'",
570                      bytecount, byte, path);
571 }
572
573 /*
574  * Send an IPC command with ballast to an already-running server daemon.
575  */
576 static int client__sendbytes(void)
577 {
578         struct ipc_client_connect_options options
579                 = IPC_CLIENT_CONNECT_OPTIONS_INIT;
580
581         options.wait_if_busy = 1;
582         options.wait_if_not_found = 0;
583         options.uds_disallow_chdir = 0;
584
585         return do_sendbytes(cl_args.bytecount, cl_args.bytevalue, cl_args.path,
586                             &options);
587 }
588
589 struct multiple_thread_data {
590         pthread_t pthread_id;
591         struct multiple_thread_data *next;
592         const char *path;
593         int bytecount;
594         int batchsize;
595         int sum_errors;
596         int sum_good;
597         char letter;
598 };
599
600 static void *multiple_thread_proc(void *_multiple_thread_data)
601 {
602         struct multiple_thread_data *d = _multiple_thread_data;
603         int k;
604         struct ipc_client_connect_options options
605                 = IPC_CLIENT_CONNECT_OPTIONS_INIT;
606
607         options.wait_if_busy = 1;
608         options.wait_if_not_found = 0;
609         /*
610          * A multi-threaded client should not be randomly calling chdir().
611          * The test will pass without this restriction because the test is
612          * not otherwise accessing the filesystem, but it makes us honest.
613          */
614         options.uds_disallow_chdir = 1;
615
616         trace2_thread_start("multiple");
617
618         for (k = 0; k < d->batchsize; k++) {
619                 if (do_sendbytes(d->bytecount + k, d->letter, d->path, &options))
620                         d->sum_errors++;
621                 else
622                         d->sum_good++;
623         }
624
625         trace2_thread_exit();
626         return NULL;
627 }
628
629 /*
630  * Start a client-side thread pool.  Each thread sends a series of
631  * IPC requests.  Each request is on a new connection to the server.
632  */
633 static int client__multiple(void)
634 {
635         struct multiple_thread_data *list = NULL;
636         int k;
637         int sum_join_errors = 0;
638         int sum_thread_errors = 0;
639         int sum_good = 0;
640
641         for (k = 0; k < cl_args.nr_threads; k++) {
642                 struct multiple_thread_data *d = xcalloc(1, sizeof(*d));
643                 d->next = list;
644                 d->path = cl_args.path;
645                 d->bytecount = cl_args.bytecount + cl_args.batchsize*(k/26);
646                 d->batchsize = cl_args.batchsize;
647                 d->sum_errors = 0;
648                 d->sum_good = 0;
649                 d->letter = 'A' + (k % 26);
650
651                 if (pthread_create(&d->pthread_id, NULL, multiple_thread_proc, d)) {
652                         warning("failed to create thread[%d] skipping remainder", k);
653                         free(d);
654                         break;
655                 }
656
657                 list = d;
658         }
659
660         while (list) {
661                 struct multiple_thread_data *d = list;
662
663                 if (pthread_join(d->pthread_id, NULL))
664                         sum_join_errors++;
665
666                 sum_thread_errors += d->sum_errors;
667                 sum_good += d->sum_good;
668
669                 list = d->next;
670                 free(d);
671         }
672
673         printf("client (good %d) (join %d), (errors %d)\n",
674                sum_good, sum_join_errors, sum_thread_errors);
675
676         return (sum_join_errors + sum_thread_errors) ? 1 : 0;
677 }
678
679 int cmd__simple_ipc(int argc, const char **argv)
680 {
681         const char * const simple_ipc_usage[] = {
682                 N_("test-helper simple-ipc is-active    [<name>] [<options>]"),
683                 N_("test-helper simple-ipc run-daemon   [<name>] [<threads>]"),
684                 N_("test-helper simple-ipc start-daemon [<name>] [<threads>] [<max-wait>]"),
685                 N_("test-helper simple-ipc stop-daemon  [<name>] [<max-wait>]"),
686                 N_("test-helper simple-ipc send         [<name>] [<token>]"),
687                 N_("test-helper simple-ipc sendbytes    [<name>] [<bytecount>] [<byte>]"),
688                 N_("test-helper simple-ipc multiple     [<name>] [<threads>] [<bytecount>] [<batchsize>]"),
689                 NULL
690         };
691
692         const char *bytevalue = NULL;
693
694         struct option options[] = {
695 #ifndef GIT_WINDOWS_NATIVE
696                 OPT_STRING(0, "name", &cl_args.path, N_("name"), N_("name or pathname of unix domain socket")),
697 #else
698                 OPT_STRING(0, "name", &cl_args.path, N_("name"), N_("named-pipe name")),
699 #endif
700                 OPT_INTEGER(0, "threads", &cl_args.nr_threads, N_("number of threads in server thread pool")),
701                 OPT_INTEGER(0, "max-wait", &cl_args.max_wait_sec, N_("seconds to wait for daemon to start or stop")),
702
703                 OPT_INTEGER(0, "bytecount", &cl_args.bytecount, N_("number of bytes")),
704                 OPT_INTEGER(0, "batchsize", &cl_args.batchsize, N_("number of requests per thread")),
705
706                 OPT_STRING(0, "byte", &bytevalue, N_("byte"), N_("ballast character")),
707                 OPT_STRING(0, "token", &cl_args.token, N_("token"), N_("command token to send to the server")),
708
709                 OPT_END()
710         };
711
712         if (argc < 2)
713                 usage_with_options(simple_ipc_usage, options);
714
715         if (argc == 2 && !strcmp(argv[1], "-h"))
716                 usage_with_options(simple_ipc_usage, options);
717
718         if (argc == 2 && !strcmp(argv[1], "SUPPORTS_SIMPLE_IPC"))
719                 return 0;
720
721         cl_args.subcommand = argv[1];
722
723         argc--;
724         argv++;
725
726         argc = parse_options(argc, argv, NULL, options, simple_ipc_usage, 0);
727
728         if (cl_args.nr_threads < 1)
729                 cl_args.nr_threads = 1;
730         if (cl_args.max_wait_sec < 0)
731                 cl_args.max_wait_sec = 0;
732         if (cl_args.bytecount < 1)
733                 cl_args.bytecount = 1;
734         if (cl_args.batchsize < 1)
735                 cl_args.batchsize = 1;
736
737         if (bytevalue && *bytevalue)
738                 cl_args.bytevalue = bytevalue[0];
739
740         /*
741          * Use '!!' on all dispatch functions to map from `error()` style
742          * (returns -1) style to `test_must_fail` style (expects 1).  This
743          * makes shell error messages less confusing.
744          */
745
746         if (!strcmp(cl_args.subcommand, "is-active"))
747                 return !!client__probe_server();
748
749         if (!strcmp(cl_args.subcommand, "run-daemon"))
750                 return !!daemon__run_server();
751
752         if (!strcmp(cl_args.subcommand, "start-daemon"))
753                 return !!daemon__start_server();
754
755         /*
756          * Client commands follow.  Ensure a server is running before
757          * sending any data.  This might be overkill, but then again
758          * this is a test harness.
759          */
760
761         if (!strcmp(cl_args.subcommand, "stop-daemon")) {
762                 if (client__probe_server())
763                         return 1;
764                 return !!client__stop_server();
765         }
766
767         if (!strcmp(cl_args.subcommand, "send")) {
768                 if (client__probe_server())
769                         return 1;
770                 return !!client__send_ipc();
771         }
772
773         if (!strcmp(cl_args.subcommand, "sendbytes")) {
774                 if (client__probe_server())
775                         return 1;
776                 return !!client__sendbytes();
777         }
778
779         if (!strcmp(cl_args.subcommand, "multiple")) {
780                 if (client__probe_server())
781                         return 1;
782                 return !!client__multiple();
783         }
784
785         die("Unhandled subcommand: '%s'", cl_args.subcommand);
786 }
787 #endif