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:
parent
6d5e40c324
commit
5114d70be6
1 changed files with 8 additions and 13 deletions
21
src/unix.c
21
src/unix.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue