1

我正在修复一个调用gethostname(),旧代码将hostName数组声明为 10 个字符,导致边界错误,因为主机名比那个大。我的解决方法是声明hostName使用MAXHOSTNAMELEN(我的平台parm.h声明为 64)。另一位程序员现在说需要将数组声明为hostName[MAXHOSTNAMELEN+1]清除,因为(来自他的电子邮件):

这来自手册页:POSIX.1-2001 保证“主机名(不包括终止的空字节)限于 HOST_NAME_MAX 字节”</p>

因此,要处理所有情况,您必须将缓冲区大小加一并使用空字符初始化缓冲区。

现在我在网上看到的每个示例都在执行 a char hostName[MAXHOSTNAMELEN],并且由于调用要么有效要么无效,因此将数组归零或将其初始化为 null 对我来说毫无意义,hostName因为如果它有效,则数组被设置为主机名称,如果不是,则调用返回错误。

将参数声明或初始化为的可靠方法是什么gethostname()

4

1 回答 1

2

POSIX 规范说:

返回的名称应以空结尾,除非 namelen 的长度不足以容纳主机名,则返回的名称应被截断,并且未指定返回的名称是否以空结尾。

主机名限制为 {HOST_NAME_MAX} 个字节。

在您的系统上,我假设MAXHOSTNAMELEN对应于规范所称的HOST_NAME_MAX. 因此,制作缓冲区MAXHOSTNAMELEN+1字节并将该大小传递给gethostname()应该保证您不必进行零初始化。

如果您没有进行零初始化,并且您没有那个额外的+1字节,那么当缓冲区不够长时,您可能会遇到失败,因为它“未指定返回的名称是否为空终止”。

也就是说,如果您的平台不严格符合标准,则零填充可能有用或必要。告诉你这样做的程序员是有原因的——这个原因是否特定于你的平台的一个怪癖?

编辑规范还说参数是“名称nameLen参数指向的数组的大小” 。由于它是数组的大小,而不是要存储在该数组中的主机名的大小,因此在数组中为终止符提供空间是一个好习惯。从历史上看,大多数域名标签都不是 64 字节,因此过去没有 64 字节的代码可能工作得很好。但是,使用 更安全,不必假设或猜测。\0+1+1

编辑 2我认为“保存主机名的长度不足”可以说是模棱两可的。但是,规范不能打算gethostname()注销提供的数组的末尾。因此,我将“insufficient length to hold the host name”取为“insufficient length to hold the host name plus the null-terminator byte ”。这是我个人的解释,但与我的经验是一致的。

于 2016-10-24T13:28:08.597 回答