[Libguestfs] [PATCH libnbd] python: Implement nbd.aio_connect for AF_UNIX
Eric Blake
eblake at redhat.com
Wed Jun 30 21:38:33 UTC 2021
On Wed, Jun 30, 2021 at 08:22:19PM +0100, Richard W.M. Jones wrote:
> This call previously just called abort(). Implement it for Unix
> domain sockets (the easy case). Implementing it for AF_INET and
> AF_INET6 is more complicated so that is left as a to-do.
Still, fixing it to return an error instead of abort()ing is nice.
>
> Note also that implementing this fully for Python is a bit pointless.
> It would be easier for a Python program to call
> nbd.aio_connect_tcp(host, port) instead of calling
> nbd.aio_connect((host, port)). Both cases would do hostname lookups
> but the former is already implemented.
> ---
> @@ -92,3 +94,64 @@ nbd_internal_py_free_string_list (char **argv)
> free (argv[i]);
> free (argv);
> }
> +
> +/* Convert a Python object into a struct sockaddr, according to the
> + * general rules described here:
> + * https://docs.python.org/3/library/socket.html
Python's representation is complex!
> + *
> + * There is a function in cpython called getsockaddrarg which roughly
> + * does the same thing, but in cpython they know the socket family
> + * already (which we do not). In any case that function cannot be
> + * called directly.
> + */
> +int
> +nbd_internal_py_get_sockaddr (PyObject *addr,
> + struct sockaddr_storage *ss, socklen_t *len)
> +{
> + memset (ss, 0, sizeof *ss);
> +
> + if (PyUnicode_Check (addr)) { /* AF_UNIX */
> + struct sockaddr_un *sun = (struct sockaddr_un *)ss;
> + const char *unixsocket;
> + size_t namelen;
> +
> + sun->sun_family = AF_UNIX;
> + unixsocket = PyUnicode_AsUTF8 (addr);
> + if (!unixsocket)
> + goto err;
Given the PyUnicode_Check() call above, this is unlikely to fail; but
checking for failure anyway is good practice.
> + namelen = strlen (unixsocket);
> + if (namelen > sizeof sun->sun_path) {
> + PyErr_SetString (PyExc_RuntimeError,
> + "get_sockaddr: Unix domain socket name too long");
> + return -1;
> + }
> + memcpy (sun->sun_path, unixsocket, namelen);
> + *len = sizeof *sun;
> + return 0;
> + }
> +
> +#if 0
> + else if (PyTuple_Check (addr)) {
> + Py_ssize_t n = PyTuple_Size (addr);
> +
> + switch (n) {
> + case 2: /* AF_INET */
> + /* XXX TODO */
> + break;
> +
> + case 4: /* AF_INET6 */
> + /* XXX TODO */
> + break;
The python docs implied that the last two fields were optional for
AF_INET6, which makes this even more complicated. But this is all #if
0 until someone needs and implements it anyway.
Patch looks good to me.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
More information about the Libguestfs
mailing list