-
Notifications
You must be signed in to change notification settings - Fork 41
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
[Windows] Cannot write to hosts with elevation/sudo #27
Comments
Not all that familiar with Go, but I've managed to get as far as showing the actual error behind hostess not being able to write to the hosts file:
After changing line 77 of MaybeError(c, err.Error()) |
Have toyed around with this - again, not terribly familar with the language. Lines 192+ of // Save writes the Hostfile to disk to /etc/hosts or to the location specified
// by the HOSTESS_PATH environment variable (if set). Due to Windows file locking,
// it's best to truncate the file before opening it for writing.
func (h *Hostfile) Save() error {
err := os.Truncate(h.Path, 0);
if err != nil {
return err
}
file, err := os.OpenFile(h.Path, os.O_RDWR|os.O_APPEND, 0644)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(h.Format())
return err
} This SO answer explains that Windows locks files, and that it would need to be truncated without an open handle. So the change above does just that. Not sure if it impacts other platforms (we could do a runtime detection if it does) or anything else, and so I'm not submitting as a PR - please let me know if I should go ahead and do that. |
@mikerockett Thanks for looking into this! The locking semantics you linked to seem a bit strange to me. This code worked on Windows 7 so I'm curious what has changed here in 10. I have not had a chance to look into this yet but I will take some time soon. Did the fix you suggested work for you? It seems reasonable that this can work on any OS but if not we can put it behind a platform build flag. If you're not familiar with Go this can be a bit complicated but if you want to take a stab at it there is some information here. |
@cbednarski - You're welcome. The suggested fix does indeed work. However, I think W10 has changed something somewhere because my hosts file wasn't actually working at after hostess converted it to the hostess-format. Where multiple hosts are defined on a single line ( I assume a platform build flag tells the compiler to build using specific code for a specific platform? (May sound silly to ask, but I haven't worked with non-runtime languages in a long time, having moved over to web-dev.) |
Oh also interesting. I may need to add a Windows-specific formatter in that case.
Correct. The Go compiler can be instructed to include a certain file only when compiling a Windows binary (for example). Simple example: The other way to do this is to use a runtime check for the OS name. I do this currently to set the default host file path. If the implementation starts to get messy with an if block that's a good hint that the build flag is a better approach. |
Thanks for the info - handy to know. If I garner some time, it would be a good idea for me to play around with Go - looks like a great language to work with.
I'd naturally think a build-flag is better for this case. Considering the potential complexity here, you'd be far better off than me in doing a platform-specific change here. Having briefly looked at the code, I can imagine that changing the formatter for Windows is perhaps not as simple as a one-line-amendment... |
This worked for me and shouldn't erase the file if the process crashes, assuming truncates actually calls SetEndOfFile, which I can't tell, because I'm only seeing posix calls in go. func (h *Hostfile) Save() error {
file, err := os.OpenFile(h.Path, os.O_RDWR, 0644)
if err != nil {
return err
}
defer file.Close()
err = file.Truncate(0)
if err != nil {
return err
}
_, err = file.Write(h.Format())
return err
} |
I took a slightly different approach and rewrote https://github.com/cbednarski/hostess/compare/atomic-update If you want to try this out yourself, let me know your results!
|
Btw I also looked into this (did some simple editing with Notepad.exe) and multiple hostnames on the same line were picked up OK. I tested with |
I tried the atomic-update branch. When the file is replaced the permissions change and the whole thing breaks. Probably replacing the file breaks the watch on the file. and without the correct permission set, whatever is watching the file doesn't watch the new file. I don't think replacing the file will work because the system has a watcher with an open handle, so even if the permissions are set correctly it will probably still loose the watcher handle until the next flush or cache timeout. Edit |
@tdaniely Thanks for testing and following up! Your feedback is super helpful. The permissions thing is something I had not considered so I will likely need to add some platform-specific code here for Unix vs. Windows. I will try to get to this in the next few days. |
Thanks all for the reports and suggestions. This fix is now live on master and tagged in 0.4.1. Sorry this was open for so long. 😬 |
I've just installed the Windows x64 0.2.0 version of hostess (Windows 10), and it states it can't write to my hosts file, even when using
sudo
or an elevated console.Any ideas as to what could be causing this?
PS: I've created a
scoop
app for this in my bucket.The text was updated successfully, but these errors were encountered: