Files
linuxkit/projects/miragesdk/src/fdd/fdd.ml
Thomas Gazagnaire 56229e486b sdk: add a file-descriptor sharing server
```
$ fdd init &
$ fdd share /tmp/foo # serve a fresh socketpair on that path
$ fdd test /tmp/foo  # read the socketpair and test that it works
```

Instead of `fdd test` (which is only useful for testing), users are expected to
connect to the unix domain socket and call `recvmsg(2)`. They will get one side
of the socketpair. Two different processes can do this and they will be able to
talk to each other.

Signed-off-by: Thomas Gazagnaire <thomas@gazagnaire.org>
2017-06-29 17:53:49 +02:00

72 lines
2.0 KiB
OCaml

open Cmdliner
let socket =
let doc =
Arg.info ~docv:"PATH"
~doc:"Socket to communicate with the FDD server." ["s"; "socket"]
in
Arg.(value & opt string "/var/run/fdd.sock" doc)
let share =
let doc =
Arg.info ~docv:"PATH" ~doc:"The path to use to share the socketpair." []
in
Arg.(required & pos 0 (some string) None doc)
let setup_log style_renderer level =
Fmt_tty.setup_std_outputs ?style_renderer ();
Logs.set_level level;
let pp_header ppf x =
Fmt.pf ppf "%5d: %a " (Unix.getpid ()) Logs_fmt.pp_header x
in
Logs.set_reporter (Logs_fmt.reporter ~pp_header ());
()
let setup_log =
Term.(const setup_log $ Fmt_cli.style_renderer () $ Logs_cli.level ())
let run f = Lwt_main.run f
let init =
let f socket () = run (Init.f socket) in
Term.(const f $ socket $ setup_log),
Term.info "init" ~doc:"Start the FDD server"
let test =
let f share () = run (Test.f share) in
Term.(const f $ share $ setup_log),
Term.info "test" ~doc:"Test a socketpair share."
let share =
let f socket share () = run (Share.f ~socket ~share) in
Term.(const f $ socket $ share $ setup_log),
Term.info "share" ~doc:"Share a new socketpair on a given unix domain socket."
let default =
let usage () =
Fmt.pr "usage: fdd [--version]\n\
\ [--help]\n\
\ <command> [<args>]\n\
\n\
The most commonly used subcommands are:\n\
\ init start a new FDD server\n\
\ share share a new socketpair\n\
\ test test a socketpair share\n\
\n\
See `fdd help <command>` for more information on a specific \
command.\n%!"
in
Term.(const usage $ const ()),
Term.info "fdd" ~version:"%%VERSION%%"
~doc:"Share socketpairs over unix domain sockets."
let cmds = [
init;
share;
test;
]
let () = match Term.eval_choice default cmds with
| `Error _ -> exit 1
| `Ok () |`Help |`Version -> exit 0