Closes#873.
When `datasette -p 0 --root` was used, the printed auth-token URL
contained the literal placeholder port 0 instead of the OS-assigned
port that uvicorn would later bind to. Same applied to `--open`.
Fix: when `port == 0` and we need to print/open a URL before the
server starts (because of --root or --open), pre-bind a TCP socket
on (host, 0), read the assigned port via getsockname(), and hand the
bound socket to uvicorn via Server.run(sockets=[...]). uvicorn.run()'s
own `fd=` parameter assumes AF_UNIX so we use the Config/Server API
in this branch only; the existing uvicorn.run() path is unchanged.
Adds a regression test that launches `datasette --memory -p 0 --root`,
parses the printed URL, asserts the port is non-zero, and confirms a
server is actually listening on that port.