чување df74d16e29d13286f99667017834d75868f98ef5
родитељ da466ca80e7896ddc77420b17d97d0b35f460a4c
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sat, 25 May 2024 19:24:30 +0200
Bugfix: Skip copy+symlink for new files; properly init backup_filename
Diffstat:
| M | sled.c | | | 68 | +++++++++++++++++++++++++++++++++++++++----------------------------- |
измењених датотека: 1, додавања: 39(+), брисања: 29(-)
diff --git a/sled.c b/sled.c
@@ -960,9 +960,12 @@ save_file(struct DrawState* state)
STRLCPY(actions[ACT_WRITING], state->action, MAXBUFLINE);
redraw_status(state);
-
errno = 0;
+
#ifdef CREATE_BACKUPS
+ if (state->new_file)
+ goto save_skip_backup_copy;
+
#ifdef BACKUP_FAIL_OK
if (state->backup_possible)
{
@@ -990,6 +993,7 @@ save_file(struct DrawState* state)
#endif /* BACKUP_FAIL_OK */
#endif /* CREATE_BACKUPS */
+save_skip_backup_copy:
if (!(output = fopen(state->rfn_len > 0 ? state->real_filename
: state->filename,
"w")))
@@ -999,6 +1003,9 @@ save_file(struct DrawState* state)
}
#ifdef CREATE_BACKUPS
+ if (state->new_file)
+ goto save_skip_backup_symlink;
+
if (lstat(state->rfn_len > 0 ? state->real_filename : state->filename,
&st)
< 0)
@@ -1022,10 +1029,9 @@ save_file(struct DrawState* state)
goto save_file_cleanup;
}
}
- if (!state->new_file)
- chmod(state->rfn_len > 0 ? state->real_filename
- : state->filename,
- st.st_mode);
+ chmod(state->rfn_len > 0 ? state->real_filename
+ : state->filename,
+ st.st_mode);
}
#else /* !BACKUP_FAIL_OK */
if (state->rfn_len > 0)
@@ -1041,13 +1047,12 @@ save_file(struct DrawState* state)
goto save_file_cleanup;
}
}
- if (!state->new_file)
- chmod(state->rfn_len > 0 ? state->real_filename
- : state->filename,
- st.st_mode);
+ chmod(state->rfn_len > 0 ? state->real_filename : state->filename,
+ st.st_mode);
#endif /* BACKUP_FAIL_OK */
#endif /* CREATE_BACKUPS */
+save_skip_backup_symlink:
if (state->rows_count == 1 && state->buffer[0].length == 0)
goto save_file_cleanup;
@@ -1057,6 +1062,8 @@ save_file(struct DrawState* state)
fprintf(output, "%s\n", buf);
}
+ state->new_file = 0;
+
save_file_cleanup:
fclose(output);
free(buf);
@@ -2413,30 +2420,32 @@ main(int argc, char** argv)
if (stat(state.real_filename, &st) == -1)
goto file_error;
}
- if (!(state.backup_filename = calloc(MAXPATH, 1)))
- {
- free(state.real_filename);
- return print_error(1,
- "Allocation failed (out of memory?)");
- }
-
- /* Backup filename is the target file + suffix if the
- * file to write is a symlink, otherwise file + suffix */
- STRLCPY(state.rfn_len > 0 ? state.real_filename : state.filename,
- state.backup_filename, MAXPATH);
- STRLCAT(backup_suffix, state.backup_filename, MAXPATH);
-#ifdef __OpenBSD__
- if (unveil(state.backup_filename, "rwc") < 0)
- {
- perror("sled: unveil");
- exit(1);
- }
-#endif
} /* We don't error out here on ENOENT to account for new files */
else if (errno == ENOENT)
state.new_file = 1;
else
goto file_error;
+
+ if (!(state.backup_filename = calloc(MAXPATH, 1)))
+ {
+ free(state.real_filename);
+ return print_error(1, "Allocation failed (out of memory?)");
+ }
+
+ /* Backup filename is the target file + suffix if the file to write
+ * is not a new file and is a symlink, otherwise file + suffix */
+ STRLCPY(state.new_file ? state.filename
+ : (state.rfn_len > 0 ? state.real_filename
+ : state.filename),
+ state.backup_filename, MAXPATH);
+ STRLCAT(backup_suffix, state.backup_filename, MAXPATH);
+#ifdef __OpenBSD__
+ if (unveil(state.backup_filename, "rwc") < 0)
+ {
+ perror("sled: unveil");
+ exit(1);
+ }
+#endif
#endif /* CREATE_BACKUPS */
if (state.rfn_len > 0)
@@ -2506,7 +2515,8 @@ main(int argc, char** argv)
switch (result)
{
case LOAD_ERR_CANT_ALLOC:
- result = print_error(result, "Allocation failed (out of memory?)");
+ result = print_error(result,
+ "Allocation failed (out of memory?)");
goto general_error;
case LOAD_ERR_CANT_OPEN_FILE:
result = print_error(result, "Cannot open file `%s'", filename);