Closes #640. You can view, comment on, or merge this pull request online at:
https://github.com/geany/geany/pull/2769
-- Commit Summary --
* SaveActions: Add configurable target directory for instantly saved files
-- File Changes --
M plugins/saveactions.c (96)
-- Patch Links --
https://github.com/geany/geany/pull/2769.patch https://github.com/geany/geany/pull/2769.diff
@eht16 pushed 2 commits.
f96a84dbecdec6fae9d4536448aaad05f52d7fc4 SaveActions: Add configurable target directory for instantly saved files ead067be9153871713813c501439b0200ccf9af9 SaveActions: Fix trailing dot on InstantSave filenames for filetype None
@elextr commented on this pull request.
One new bug and two things I noticed in the original.
{
gchar *tmp;
+ if (target == NULL) + { + SETPTR(*target, NULL);
`*target` is guaranteed to dereference a NULL?????
gchar *new_filename;
gint fd; GeanyFiletype *ft = doc->file_type;
- fd = g_file_open_tmp("gis_XXXXXX", &new_filename, NULL); + directory = !EMPTY(instantsave_target_dir) ? instantsave_target_dir : g_get_tmp_dir(); + new_filename = g_build_filename(directory, "gis_XXXXXX", NULL); + fd = g_mkstemp(new_filename); if (fd != -1) close(fd); /* close the returned file descriptor as we only need the filename */
If g_mkstemp() returns -1 is the filename valid and usable?
gchar *new_filename;
gint fd; GeanyFiletype *ft = doc->file_type;
- fd = g_file_open_tmp("gis_XXXXXX", &new_filename, NULL); + directory = !EMPTY(instantsave_target_dir) ? instantsave_target_dir : g_get_tmp_dir(); + new_filename = g_build_filename(directory, "gis_XXXXXX", NULL); + fd = g_mkstemp(new_filename); if (fd != -1) close(fd); /* close the returned file descriptor as we only need the filename */
Also since g_mkstemp() makes a file the now non-temporary file directory gets two files, for example `gis_setv00` and `gis_setv_00.c`.
Not part of this PR, but related, how is it possible to create a new file with no filename but a filetype that is not none? Using `New (with template)` gives the new file a name `untitled.ext` so it doesn't instant save, is that intended?.
@eht16 pushed 2 commits.
e74d71c1a8e0e4a97f0c816ae90c351f2b448042 SaveActions: Fix resetting Instant Save target directory b4cedb37ee5ac9c3f88b09547e0aaad0a5c2a347 SaveActions: Handle g_mkstemp() errors and prevent duplicate files
@eht16 commented on this pull request.
{
gchar *tmp;
+ if (target == NULL) + { + SETPTR(*target, NULL);
This didn't make sense. Thanks for the pointer. I rewrote the code to return `FALSE` as it should no valid case when the target variable is `NULL`.
@eht16 pushed 1 commit.
0c4a35692cf9fdbfa300df0570cfa2426e3be391 SaveActions: Handle g_mkstemp() errors and prevent duplicate files
@eht16 commented on this pull request.
gchar *new_filename;
gint fd; GeanyFiletype *ft = doc->file_type;
- fd = g_file_open_tmp("gis_XXXXXX", &new_filename, NULL); + directory = !EMPTY(instantsave_target_dir) ? instantsave_target_dir : g_get_tmp_dir(); + new_filename = g_build_filename(directory, "gis_XXXXXX", NULL); + fd = g_mkstemp(new_filename); if (fd != -1) close(fd); /* close the returned file descriptor as we only need the filename */
If g_mkstemp() returns -1 is the filename valid and usable?
As per docs, no. So we handle now errors by showing them to the user and cancelling Instant Save.
Also since g_mkstemp() makes a file the now non-temporary file directory gets two files, for example `gis_setv00` and `gis_setv00.c`.
Good catch! Fixed by first constructing the final filename and then call `g_mkstemp()` to have the file created.
Not part of this PR, but related, how is it possible to create a new file with no filename but a filetype that is not none? Using `New (with template)` gives the new file a name `untitled.ext` so it doesn't instant save, is that intended?.
I don't remember all cases where new files with a filetype set are created, there were many combinations.
@elextr commented on this pull request.
SETPTR(new_filename, g_strconcat(new_filename, ".", ft->extension, NULL));
+ /* create new file */ + fd = g_mkstemp(new_filename); + if (fd == -1) + { + gchar *message = g_strdup_printf( + _("Instant Save filename could not be generated (%s)."), g_strerror(errno)); + ui_set_statusbar(TRUE, "%s", message); + g_warning("%s", message); + g_free(message); + return;
leaks `new_filename`
if (ft == NULL || ft->id == GEANY_FILETYPES_NONE)
/* ft is NULL when a new file without template was opened, so use the * configured default file type */ ft = filetypes_lookup_by_name(instantsave_default_ft);
- if (ft != NULL) - /* add the filetype's default extension to the new filename */ + /* construct filename */ + directory = !EMPTY(instantsave_target_dir) ? instantsave_target_dir : g_get_tmp_dir(); + new_filename = g_build_filename(directory, "gis_XXXXXX", NULL); + if (ft != NULL && !EMPTY(ft->extension)) SETPTR(new_filename, g_strconcat(new_filename, ".", ft->extension, NULL));
`ft == NULL` means `doc->file_type` is NULL, but its not set before being dereferenced at **here** below
SETPTR(new_filename, g_strconcat(new_filename, ".", ft->extension, NULL));
+ /* create new file */ + fd = g_mkstemp(new_filename); + if (fd == -1) + { + gchar *message = g_strdup_printf( + _("Instant Save filename could not be generated (%s)."), g_strerror(errno)); + ui_set_statusbar(TRUE, "%s", message); + g_warning("%s", message); + g_free(message); + return; + } + + close(fd); /* close the returned file descriptor as we only need the filename */ + doc->file_name = new_filename;
if (doc->file_type->id == GEANY_FILETYPES_NONE)
**here**
@eht16 pushed 1 commit.
f64374ec57c9e704b0f1d588d24edce2194da249 SaveActions: Fix memory leak and possible invalid access
@eht16 commented on this pull request.
SETPTR(new_filename, g_strconcat(new_filename, ".", ft->extension, NULL));
+ /* create new file */ + fd = g_mkstemp(new_filename); + if (fd == -1) + { + gchar *message = g_strdup_printf( + _("Instant Save filename could not be generated (%s)."), g_strerror(errno)); + ui_set_statusbar(TRUE, "%s", message); + g_warning("%s", message); + g_free(message); + return;
Fixed, thanks for spotting.
@eht16 commented on this pull request.
if (ft == NULL || ft->id == GEANY_FILETYPES_NONE)
/* ft is NULL when a new file without template was opened, so use the * configured default file type */ ft = filetypes_lookup_by_name(instantsave_default_ft);
- if (ft != NULL) - /* add the filetype's default extension to the new filename */ + /* construct filename */ + directory = !EMPTY(instantsave_target_dir) ? instantsave_target_dir : g_get_tmp_dir(); + new_filename = g_build_filename(directory, "gis_XXXXXX", NULL); + if (ft != NULL && !EMPTY(ft->extension)) SETPTR(new_filename, g_strconcat(new_filename, ".", ft->extension, NULL));
Great, you are uncovering very old bugs :). Should be fixed.
@eht16 pushed 1 commit.
e024932856886f8beca486434fbc244d97217eb8 Use "ft" variable consistently
@elextr anything left?
Pinging again @elextr or anyone else. I think it would be cool to have this in 1.38.
LGBI, its a plugin, so can be disabled if it goes horribly wrong, so fine by me.
Merged #2769 into master.
github-comments@lists.geany.org