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

x/sys/unix: InotifyRmWatch should take int, not uint32 #32020

Closed
ghost opened this issue May 14, 2019 · 11 comments
Closed

x/sys/unix: InotifyRmWatch should take int, not uint32 #32020

ghost opened this issue May 14, 2019 · 11 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@ghost
Copy link

ghost commented May 14, 2019

What version of Go are you using (go version)?

$ go version
go1.10.4 linux/amd64

Does this issue reproduce with the latest release?

Yes, https://github.com/golang/sys/blob/master/unix/zsyscall_linux_arm64.go still shows the following signature: InotifyRmWatch(fd int, watchdesc uint32).

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home//.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home//go"
GORACE=""
GOROOT="/usr/lib/go-1.10"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.10/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build762147821=/tmp/go-build -gno-record-gcc-switches"

What did you do?

wd,_ := unix.InotifyAddWatch(...) // wd is of type int
unix.InotifyRmWatch(..., wd) // function expects uint32 but wd is of type int

What did you expect to see?

According to man, inotify_rm_watch is defined as: int inotify_rm_watch(int fd, int wd). So I would expect InotifyRmWatch to take two regular ints.

What did you see instead?

Compiler complaining about type conversion (int -> uint32).

@gopherbot gopherbot added this to the Unreleased milestone May 14, 2019
@FiloSottile
Copy link
Contributor

The definition in syscall_linux.go dates back to 5 years ago, but it does look mismatched.

/cc owners @ianlancetaylor @bradfitz @tklauser

@FiloSottile FiloSottile added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 14, 2019
@bradfitz
Copy link
Contributor

I guess it depends whether changing it would do more good than harm.

I suspect it'd break a number of people and the benefit of changing it seems low-ish.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 7, 2022
@mknyszek mknyszek moved this to Triage Backlog in Go Compiler / Runtime Jul 15, 2022
@akemrir
Copy link

akemrir commented Oct 8, 2024

This looks like discrepancy. Refering to inotify man pages:
https://www.man7.org/linux/man-pages/man2/inotify_rm_watch.2.html

int inotify_rm_watch(int fd, int wd);

https://www.man7.org/linux/man-pages/man2/inotify_add_watch.2.html

int inotify_add_watch(int fd, const char *pathname, uint32_t mask);

wd and return values when adding watch in inotify are of the same types.

Go code is generated from: src/syscall/syscall_linux.go
Where we have:

...
//sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
//sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
...

uint32 is generally used for masks and modes

Even found in old articles it's always stated as int:
https://lwn.net/Articles/604686/

In linux kernel we can see:
any-linux-any/linux/inotify.h

/* For O_CLOEXEC and O_NONBLOCK */
#include <linux/fcntl.h>
#include <linux/types.h>

/*
 * struct inotify_event - structure read from the inotify device for each event
 *
 * When you are watching a directory, you will receive the filename for events
 * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
 */
struct inotify_event {
	__s32		wd;		/* watch descriptor */
	__u32		mask;		/* watch mask */
	__u32		cookie;		/* cookie to synchronize two events */
	__u32		len;		/* length (including nulls) of name */
	char		name[];	/* stub for possible name */
};

types.h
-> asm/types.h
-> asm-generic/types.h
-> asm-generic/int-ll64.h

showing

#ifndef __ASSEMBLY__
/*
 * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
 * header files exported to user space
 */

typedef __signed__ char __s8;
typedef unsigned char __u8;

typedef __signed__ short __s16;
typedef unsigned short __u16;

typedef __signed__ int __s32;
typedef unsigned int __u32;

@ianlancetaylor
Copy link
Member

Perhaps we made a mistake, but changing this now would just break existing working code for no benefit.

@ianlancetaylor ianlancetaylor closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 2024
@github-project-automation github-project-automation bot moved this from Triage Backlog to Done in Go Compiler / Runtime Oct 8, 2024
@akemrir
Copy link

akemrir commented Oct 9, 2024

Ok, it would break existing working code, but this hangs for more than 5 years.
I've found a trace in api/go1.txt with same signature...

I would like to ask: when it could be fixed?

@illarion
Copy link

illarion commented Oct 9, 2024

@ianlancetaylor Now we have versions, so maybe, there's a chance to have syscall/v2 package, with fixed discrepancies like this, without breaking backward compatibility ?

@ianlancetaylor
Copy link
Member

Yes, we could fix this with a v2 package. But it seems like a minor detail. Perhaps I've missed something, but is there anything that can't be done with the current implementation? Aren't we just talking about adding a type conversion that shouldn't be needed? And it's not like this is a widely used function.

@akemrir
Copy link

akemrir commented Oct 10, 2024

It brings inconsistency and unnecessary checks/conversions on developer side.
That's why I wanted to address this.

Could you elaborate more on not widely used function?
Maybe now it's not so bad to bring this change?

@ianlancetaylor
Copy link
Member

It's not a widely used function, which means that few programmers will run into this inconsistency.

We take backward compatibility seriously (see https://go.dev/doc/go1compat), so even though only a few programs use this function we aren't going to break them without a really good reason.

The situation is clearly unfortunate, and I wish we had done better back when this function was introduced in 2010 (https://golang.org/cl/2241045). However, in a case like this, where there is no good solution and no clear path forward, not changing anything is the best of a set of bad choices.

@akemrir
Copy link

akemrir commented Oct 11, 2024

Could we at least mark it to be fixed in future?

@ianlancetaylor
Copy link
Member

As long as we understand that the future is a very long way off, sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Development

No branches or pull requests

6 participants