Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: x/sys/unix: add IoctlRetInt() #33966

Closed
kolyshkin opened this issue Aug 30, 2019 · 5 comments
Closed

proposal: x/sys/unix: add IoctlRetInt() #33966

kolyshkin opened this issue Aug 30, 2019 · 5 comments

Comments

@kolyshkin
Copy link
Contributor

I propose to add the following function to x/sys/unix:

// IoctlRetInt performs an ioctl operation specified by req on a device
// associated with opened file descriptor fd, and returns a non-negative
// integer that is returned by the ioctl syscall. 
func IoctlRetInt(fd int, req uint) (int, error) {
	ret, _, err := unix.Syscall(unix.SYS_IOCTL, fd, req, 0)
 	if err != 0 {
 		return 0, err
 	}
 	return int(ret), nil
}

and amend the IoctlGetInt() documentation with the following text:

A few ioctl requests use the return value as an output parameter;
for those, use IoctlRetInt instead of this function.

Motivation

Currently, x/sys/unix provides a few functions to deal with ioctls. In particular, IoctlGetInt(), which "performs an ioctl operation which gets an integer value". It does that by passing a pointer to an integer to a syscall and returning that integer. The value returned from syscall is treated as success/failure flag (0 means success, -1 means failure, and in such case errno is used to figure out the underlying error).

It appears that there are a few ioctls in Linux (I'm not sure about other OSs) that does not use the above way to return an int, but rather they use the syscall's return value (in case it's not negative). As ioctl(2) man page says,

RETURN VALUE
Usually, on success zero is returned. A few ioctl() requests use the return value as an
output parameter and return a nonnegative value on success. On error, -1 is returned,
and errno is set appropriately.

Currently I am aware of at least 6 ioctls that do that (return the value directly):

  • LOOP_CTL_* ioctls on /dev/loop-control (all 3 of them). Source: loop(4)
  • NS_* ioctls (3 out of 4) on /proc/PID/ns/*. Source: ioctl_ns(2)

There might be some more, but since in general ioctls are not well documented and there's no definitive list. I am not sure how many more are there.

Obviously, using IoctlGetInt() for such ioctls would be a big mistake, as 0 will always be returned. For example, here is the bug in Docker: moby/moby#39801

@tklauser
Copy link
Member

I'm OK with adding such a function for Linux.

/cc @ianlancetaylor @bradfitz

@tklauser tklauser changed the title x/sys: proposal: add IoctlRetInt() to unix/ proposal: x/sys/unix: add IoctlRetInt() Aug 30, 2019
@ianlancetaylor
Copy link
Contributor

OK with me.

@gopherbot
Copy link

Change https://golang.org/cl/192780 mentions this issue: unix: add IoctlRetInt

@kolyshkin
Copy link
Contributor Author

I'm OK with adding such a function for Linux.

@tklauser I was able to find at least one Solaris ioctl that also uses syscall return value, it is I_FIND (see https://docs.oracle.com/cd/E26502_01/html/E29044/streamio-7i.html#REFMAN7streamio-7i)

@kolyshkin
Copy link
Contributor Author

... so I have added this new function this for all UNIX versions

@golang golang locked and limited conversation to collaborators Sep 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants