unix connect/bind: compute addr size the same regardless of extra fields

I.e. taking a Unix sockaddr's maximum size, subtracting the one variable
field's max size and adding the size of that field's content gets us the
actual size anytime. This gives us less duplication and only a single
piece of code used across all Unices: i.e. the same code gets tested on
all.

In particular the current makefile, when used on FreeBSD (which *does*
have the sun_len field, but appears to ignore its contents) the
addr-length passed to connect() and bind() is one to small because the
sun_len field's space is neglected in the previous size computation.
This change removes the unnecessary dependency on the build system for
the correctness of the addr length computation.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
This commit is contained in:
Giel van Schijndel 2014-07-09 22:15:57 +02:00
parent 6d5e40c324
commit 5114d70be6

View file

@ -191,20 +191,17 @@ static int meth_accept(lua_State *L) {
static const char *unix_trybind(p_unix un, const char *path) {
struct sockaddr_un local;
size_t len = strlen(path);
size_t addrlen;
int err;
if (len >= sizeof(local.sun_path)) return "path too long";
memset(&local, 0, sizeof(local));
strcpy(local.sun_path, path);
local.sun_family = AF_UNIX;
addrlen = sizeof(local) - sizeof(local.sun_path) + len;
#ifdef UNIX_HAS_SUN_LEN
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
+ len + 1;
err = socket_bind(&un->sock, (SA *) &local, local.sun_len);
#else
err = socket_bind(&un->sock, (SA *) &local,
sizeof(local.sun_family) + len);
local.sun_len = addrlen + 1;
#endif
err = socket_bind(&un->sock, (SA *) &local, addrlen);
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}
@ -229,20 +226,18 @@ static const char *unix_tryconnect(p_unix un, const char *path)
{
struct sockaddr_un remote;
int err;
size_t addrlen;
size_t len = strlen(path);
if (len >= sizeof(remote.sun_path)) return "path too long";
memset(&remote, 0, sizeof(remote));
strcpy(remote.sun_path, path);
remote.sun_family = AF_UNIX;
timeout_markstart(&un->tm);
addrlen = sizeof(remote) - sizeof(remote.sun_path) + len;
#ifdef UNIX_HAS_SUN_LEN
remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
+ len + 1;
err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm);
#else
err = socket_connect(&un->sock, (SA *) &remote,
sizeof(remote.sun_family) + len, &un->tm);
remote.sun_len = addrlen + 1;
#endif
err = socket_connect(&un->sock, (SA *) &remote, addrlen, &un->tm);
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}