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
Preventing destroying of symbolic/hard links in Windows OS. #1270
Conversation
Preventing destroying of symbolic/hard links to real documents on "document-save" on Windows OS.
@@ -1955,37 +1961,51 @@ static gchar *write_data_to_disk(const gchar *locale_filename, | |||
/* Use POSIX API for unsafe saving (GVFS-unsafe) */ | |||
/* The error handling is taken from glib-2.26.0 gfileutils.c */ | |||
errno = 0; | |||
fp = g_fopen(locale_filename, "wb"); | |||
fp = g_fopen(locale_filename, "w+b"); // we can not destroy symbolic/hard links |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does it need to open for reading and writing to write the file to disk?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if use "w" in case of appcrash will lost entire file.
if use "a" we can not seek to start of file and rewrite it.
if "w+" we can have significant part of file if appcrash, because truncate+write.
(fix) "r+" instead "w+"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both "w" and "w+" truncate the file and discard its contents (see here). If you observe something else, it might be undefined behaviour. Or did I misunderstand?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@biv91 have you checked that remote filesystems like sshfs support this?
If you havn't tested it on Linux and OSX and with a large number of different filesystems I would be happier if this was limited to windows only, not imposed on everybody.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need open for writing without truncation to empty, set write position to start, truncate to dataLength, write data to file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linked document says for "w+":
write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.
And my man pages say:
Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
Both sources seem to agree that the file is truncated for both "w" and "w+". Am I being dense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found good option "r+", for overwriting file from start + truncate to writingDataLength, we got half-safe writing of document.
#if defined(_WIN32) | ||
#elif defined(_WIN64) | ||
#elif defined(__CYGWIN__) | ||
#elif defined(__MSYS__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think _WIN32
is enough to cover all of the above. GLib has one defined though already, it's called G_OS_WIN32
.
@@ -1934,7 +1934,12 @@ static gchar *write_data_to_disk(const gchar *locale_filename, | |||
if (g_file_set_contents(locale_filename, data, len, &error)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does g_file_set_contents() not have the same problem?
I suspect your problem may be that the real path is not being determined correctly rather than how its written. |
I believe the "realpath" code in TagManager predates Windows having symbolic links (Vista/2007), so quite possibly. |
bytes_written = fwrite(data, sizeof(gchar), len, fp); | ||
|
||
if (len != bytes_written) | ||
if(truncate(locale_filename,sizeof(gchar)*len)) // no can change file size error! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glib makes locale_filename UTF8 on windows, you can't pass it to a clib function I don't think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
truncate() is POSIX 2008 and AFAIK not available on Windows
@biv91 The basic file write method is intended to be simple and fast, especially useful for slow remote filesystems. We regularly get complaints about other save methods being too slow. Your changes mean it now writes all zeros and then overwrites with the data, potentially doubling the transfers. Also that change has nothing to do with overwriting links on windows. Please separate the changes. |
This PR should be rejected, unconditionally removing GIO saving on windows removes functionality that is useful to other users. It can already be disabled at runtime with a pref if a user does not want to use it. Note: fixing the travis errors, and separating the links overwriting from the truncate() changes in another PR might make it acceptable. |
realpath() can not determine hard links, current stable Geany destroys them too. This means - all it doing Glib. |
@biv91 what do you mean by "destroys" hard links? |
Create 2 files hard linked. Edit & Save one with Gewany & we have 2 separate files. I means. |
@biv91 on Linux a hardlinked file is updated when either plain file saving or GIO saving is used, and the links split when atomic saving is used. This is what is expected. If there is a different behaviour on windows then:
|
@elextr "This PR should be rejected, unconditionally removing GIO saving" |
@biv91 GIO is already disablable in settings |
@elextr , I am just now founf editor options. Maybe I will uncomment GIO-safe-write, but leave unsafe-write which I was turn into half-safe-writing, because it better. |
@biv91 I say again do not change common code. The simple unsafe saving code suits specific use-cases, and your half safe saving adds overheads that may not be wanted. If you want another saving method, give it an option of its own and make it separate code. If you just found the settings I suggest you read this before you go changing a critical function such as file saving. |
Best solution - turn of Atomic-saving and GIO-unsafe-saving. This works perfect. No need code changes. |
Preventing destroying of symbolic/hard links to real documents on "document-save" in Windows OS.