-
-
Notifications
You must be signed in to change notification settings - Fork 29
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
Fix link and socket detection in search methods #14
Conversation
Codecov Report
@@ Coverage Diff @@
## master #14 +/- ##
==========================================
- Coverage 92.63% 86.77% -5.86%
==========================================
Files 6 5 -1
Lines 190 121 -69
==========================================
- Hits 176 105 -71
- Misses 13 15 +2
Partials 1 1
Continue to review full report at Codecov.
|
Hi @djdv. Thank you for the PR. So there are no issues with finding the file when using Is there any way to isolate this scenario? Are the |
It seems so. This continues to work fine for files, but now also detects the socket I'm searching for. (this probably already worked fine on *nix, but not on Windows because of golang/go#33357).
I can. I put an example of how I'm getting and using the path below, but it's kind of convoluted.
It seems like no, but this may be a bug in Go (same issue linked above), I'm not sure if this will change or not. fmt.Printf("%d\n", fi.Mode()&os.ModeSocket) is returning 0 when the fi comes from these Unix sockets. It seems like it should though.
I was wondering about that specifically. It seems like as the application developer you would still want to get a path to broken links (so that you can detect this and warn, or fix the path) Current usage: https://www.youtube.com/watch?v=Bd5wSKKf4ac ...
if service.Interactive() { // use the most user-specific path
if servicePath, err = xdg.RuntimeFile(serviceName); err != nil {
return nil, err
}
} else { // For system services, use the least user-specific path
// NOTE: xdg standard says this list should always have a fallback
// (so this list should never contain less than 1 element - regardless of platform)
leastLocalDir := xdg.ConfigDirs[len(xdg.ConfigDirs)-1]
servicePath = filepath.Join(leastLocalDir, serviceName)
}
return multiaddr.NewMultiaddr("/unix/" + servicePath)
} Client side, we'll come back to this same function, and use whichever path has the socket in it. func localServiceMaddr() (multiaddr.Multiaddr, error) {
ourName := filepath.Base(os.Args[0])
ourName = strings.TrimSuffix(ourName, filepath.Ext(ourName))
serviceName := filepath.Join(ourName, serviceTarget)
// use existing if found
servicePath, err := xdg.SearchRuntimeFile(serviceName)
if err == nil {
return multiaddr.NewMultiaddr("/unix/" + servicePath)
// ^ this returns the path we expect if the server is being run by a regular user
}
if servicePath, err = xdg.SearchConfigFile(serviceName); err == nil {
return multiaddr.NewMultiaddr("/unix/" + servicePath)
// ^ this returns the path we expect if the server is running globally on the system
}
... With |
Wow, thank you for the detailed explanation. |
I made a quick test on Windows using the C server from golang/go#33357. With the server started, I called Are you sure you have the right permissions set on the |
:^)
Seems like a good idea to me. 👍 Any special existence checking code will still remain in
I'm wondering if it has something to do with versions. I'm using Go 1.16, on Windows 10 (19042.844). I tried using more relaxed permissions, but couldn't get I tried various tools against these paths: https://www.youtube.com/watch?v=J3hjW65Acns I'll have to see if a clean VM has different results than my current host environment. |
I updated Go to 1.16 and installed all the Windows updates so that we have matching environments and still cannot reproduce the issue using the C server from that issue. I want to be able to reproduce it so that I can add test cases for any changes I introduce. Would it be possible for you to make a video showcasing how you reproduce the issue using the C server and that Go sample from golang/go#33357? You could also link the video to your comment on that issue. |
@adrg
Strange. I tried this in a relatively stock VM as well as my host but got the same problem.
For sure :^) I noticed a few other projects are implementing similar workarounds by using Going to implement the fallback idea you mentioned, and see about making a test case for this too. |
I removed the previous change ( Locally I get this:
The underlying error is being lost inside of I think we're blocked on upstream making changes to As for broken symlinks, I can implement the fallback check if you'd like. Likewise let me know if there's any changes that should be made for the test itself. I kind of copy pasted it quickly from the one above. lol |
Hi @djdv. Sorry for the late response. Yeah, the workaround seems like the only option for now, although it's a bit of a challenge to create test cases for the changes. There's also the issue that Not sure what's the best course of action. Ideally, the problem would be solved by a Windows update or by the Go team. But we cannot be sure that it will happen soon. In any case, if we were to implement the workaround, I think it is best to limit that behavior to Windows. Another option (not ideal) would be to use |
Since we don't use the result and only want to know if the target exists, we can skip resolving symlinks and processing of any other special files (like Unix sockets).
I changed
and it creates, detects, and cleans up the sockets. Edit: this looks relevant I also split |
Thanks @djdv. I think I'm going to go with |
Superseded by: #16 |
Since we don't use the result and only want to know if the target exists, we can do even less processing of the target by using Lstat.
That is, don't resolve links, don't call file relevant stat methods on non-files like sockets, etc. Just check if they exist.
This specifically resolves an issue with
os.Stat
returning an error if the path is a Unix domain socket, on Windows (despite the path being valid and usable).For example, this: golang/go#33357 (comment)
will return
CreateFile server.sock: The file cannot be accessed by the system.
While changing to
Lstat
returns information on the target without error.I'm experiencing this same issue with my own Go program which is creating and using valid Unix sockets, but they're not being found by
xdg.SearchRuntimeFile
,xdg.SearchConfigFile
, etc.This specific issue with Stat may need to be fixed upstream, but using Lstat here may still make sense for symlinks, and other types.
*(Unless this goes against some xdg expectation, I'm not sure)