你应该使用SUN_LEN
宏。这是来自我的Mac上的/usr/include/sys/un.h
:
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define SUN_LEN(su) \
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
编辑:
是的,它不具备可移植性和POSIX兼容性,但我们在真实的平台上工作,不是吗?
问题是你必须将路径以零结尾,并且上面的代码和sizeof( struct sockaddr_un )
一样好,但在从用户复制到内核时可能会节省一些字节,但浪费一些strlen
周期。
看看Linux如何处理该长度(来自http://lxr.linux.no/linux+v2.6.32/net/unix/af_unix.c#L200):
static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned *hashp)
{
if (len <= sizeof(short) || len > sizeofsunaddr)[len] = 0;
len = strlen(sunaddr->sun_path)+1+sizeof(short);
return len;
}
*hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
return len;
}
这里,len
直接来自于第三个参数传递到 bind
系统调用,但是 sunaddr
已经被复制到内核空间并具有该长度。你不能拥有比 sizeof(sockadd_un)
更长的地址。内核无论如何都会执行 strlen
。
所以,在整个过程中使用 sizeof(sockaddr_un)
可能更加安全,但是告诉内核确切的长度也不会有任何问题。
SUN_LEN
,也没有对你进行投票。但我对SUN_LEN
的来源很感兴趣,所以我谷歌了一下,并找到了这篇非常有信息量的帖子:http://mail-index.netbsd.org/tech-net/2006/10/11/0008.html - Stéphan KochenSUN_LEN
不具可移植性,也不在 POSIX 中。 - mark4o