-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
One very relevant usage of ioctl functions (at least on Linux) is for querying extended attributes in files. As seen in https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html ,
The type of the argument given to the FS_IOC_GETFLAGS and
FS_IOC_SETFLAGS operations is int *, notwithstanding the
implication in the kernel source file include/uapi/linux/fs.h
that the argument is long *.
What this means is that the attr field in ioctl(fd, FS_IOC_GETFLAGS, &attr); and ioctl(fd, FS_IOC_SETFLAGS, &attr); is always a 32-bit signed integer. This means that using the IoctlGetInt and IoctlSetPointerInt functions is wrong for these values, because Go's int will be 32-bit or 64-bit, depending on the platform's pointer width. It happens to work on little endian platforms, but it will definitely be wrong on 64-bit big endian platforms (so at least ppc64 and some mips, maybe aarch64be? not sure go supports that).
x/sys/unix does provide IoctlGetUint32, but that has the wrong sign, unfortunately.
There is a workaround, which is using IoctlGetUint32 and converting to an int32, and using IoctlSetInt(fd, req, int(uintptr(unsafe.Pointer(attr))) instead of IoctlSetPointerInt, but these are hardly ergonomic.
Therefore, I would suggest providing IoctlGetInt32, IoctlSetPointerInt32 and IoctlSetInt32 functions. If homogenous coverage is desirable, a *Uint32 set could be added as well.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status