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

Preventing destroying of symbolic/hard links in Windows OS. #1270

Closed
wants to merge 5 commits into from
Closed

Preventing destroying of symbolic/hard links in Windows OS. #1270

wants to merge 5 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Oct 21, 2016

Preventing destroying of symbolic/hard links to real documents on "document-save" in Windows OS.

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
Copy link
Member

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?

Copy link
Author

@ghost ghost Oct 22, 2016

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+"

Copy link
Member

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?

Copy link
Member

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.

Copy link
Author

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.

Copy link
Member

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?

Copy link
Author

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__)
Copy link
Member

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))
Copy link
Member

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?

@elextr
Copy link
Member

elextr commented Oct 22, 2016

I suspect your problem may be that the real path is not being determined correctly rather than how its written.

@codebrainz
Copy link
Member

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!
Copy link
Member

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.

Copy link
Member

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

@elextr
Copy link
Member

elextr commented Oct 22, 2016

@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.

@elextr elextr added the windows label Oct 22, 2016
@elextr
Copy link
Member

elextr commented Oct 22, 2016

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.

@ghost
Copy link
Author

ghost commented Oct 22, 2016

realpath() can not determine hard links, current stable Geany destroys them too. This means - all it doing Glib.

@elextr
Copy link
Member

elextr commented Oct 22, 2016

@biv91 what do you mean by "destroys" hard links?

@ghost
Copy link
Author

ghost commented Oct 22, 2016

Create 2 files hard linked. Edit & Save one with Gewany & we have 2 separate files. I means.

@elextr
Copy link
Member

elextr commented Oct 22, 2016

@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:

  1. describe it clearly, describing the behaviour in all the saving settings
  2. if you wish to make a change for windows please make code that is specific to windows, do not make untested changes to code that is common to all systems.
  3. Do not compile out options that can be disabled at runtime (GIO saving)

@ghost
Copy link
Author

ghost commented Oct 22, 2016

@elextr "This PR should be rejected, unconditionally removing GIO saving"
Good idvise, I will do it in settings.

@elextr
Copy link
Member

elextr commented Oct 22, 2016

@biv91 GIO is already disablable in settings

@ghost
Copy link
Author

ghost commented Oct 22, 2016

@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.

@elextr
Copy link
Member

elextr commented Oct 22, 2016

@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.

@ghost
Copy link
Author

ghost commented Oct 22, 2016

Best solution - turn of Atomic-saving and GIO-unsafe-saving. This works perfect. No need code changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants