我正在修复对 gethostname()
的调用,其中旧代码将 hostName
数组声明为10个字符,从而导致边界错误,因为主机名大于那个 . 我的修复是使用 MAXHOSTNAMELEN
(我的平台的 parm.h
声明为64)声明 hostName
. 另一个程序员现在说数组需要声明为 hostName[MAXHOSTNAMELEN+1]
并清除,因为(来自他的电子邮件):
这是来自手册页:POSIX.1-2001保证“主机名(不包括终止空字节)仅限于HOST_NAME_MAX字节”因此,要处理所有情况,必须在缓冲区大小中添加一个并初始化缓冲区带有空字符 .
现在我在网上看到的每个例子都在做一个 char hostName[MAXHOSTNAMELEN]
并且因为调用有效或者没有,所以将 hostName
数组清零或将其初始化为null是没有意义的,因为如果它工作,则数组被设置为主机名,如果不是,则调用返回错误 .
将参数声明或初始化为 gethostname()
的可靠方法是什么?
1 回答
POSIX spec说:
在您的系统上,我假设
MAXHOSTNAMELEN
对应于规范称为HOST_NAME_MAX
的内容 . 因此,使缓冲区MAXHOSTNAMELEN+1
字节并将该大小传递给gethostname()
应该保证您不必进行零初始化 .如果您没有进行零初始化,并且没有额外的
+1
字节,则当缓冲区不够长时,可能会因为它是"unspecified whether the returned name is null-terminated"而遇到故障 .也就是说,如果您的平台不是严格符合标准的,那么零填充可能是有用的或必要的 . 告诉你这样做的程序员有一个理由 - 这个特定于你的平台怪癖的原因吗?
Edit spec还表示
nameLen
参数是“name参数指向的数组的大小” . 由于它是数组的大小而不是要存储在该数组中的主机名的大小,因此在数组中为\0
终止符提供空间是一种很好的做法 . 从历史上看,大多数域名标签都不是64字节,因此没有+1
的代码在过去可能运行良好 . 不过更安全地使用+1
,而不必假设或猜测 .Edit 2 我认为"insufficient length to hold the host name"可以说是含糊不清的 . 但是,规范不能打算
gethostname()
应该注销所提供数组的末尾 . 因此,我将"insufficient length to hold the host name"表示“保持主机名加上空终止符字节的长度不足” . 这是我个人的解释,但这符合我的经验 .