Solaris(64 位)开发者指南

谨慎使用 ioctl()

过去,指定的一些 ioctl(2) 调用非常不当。遗憾的是,ioctl() 完全不执行编译时类型检查,因此,可能难以找到错误的来源。

请考虑使用两个 ioctl() 调用:一个用来处理 32 位值 (IOP32) 的指针,另一个用来处理长值 (IOPLONG) 的指针。

以下代码样例作为 32 位应用程序的一部分来运行:

	int a, d;

	long b;

	...

	if (ioctl(d, IOP32, &b) == -1)

			return (errno);

	if (ioctl(d, IOPLONG, &a) == -1)

			return (errno);

编译此代码段并将其作为 32 位应用程序的一部分运行时,这两个 ioctl(2) 调用均可正常工作。

编译此代码段并将其作为 64 位应用程序的一部分运行时,这两个 ioctl() 调用也将成功返回。但是,这两个 ioctl() 均无法正常工作。第一个 ioctl() 传递的容器太大,并且在大端字节序实现中,内核将从 64 位字的错误部分向外复制数据或向其中复制数据。即使在小端字节序实现中,该容器也可能在高 32 位中包含栈垃圾。第二个 ioctl() 会从字中向外复制或向其中复制过多的数据,从而导致读取错误的值或破坏用户栈上的相邻变量。