чување 1ddcefc73d99604370a99398e82f41697068a102
родитељ 040cdf5de41ee96e5b71d06a9f66580860cbd1b2
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sun, 4 Jul 2021 22:38:58 +0200
Bugfix: rename can't move files across devices (from /tmp); changed to make temporary file in dirname()
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
измењених датотека: 6, додавања: 21(+), брисања: 8(-)
diff --git a/draw.c b/draw.c
@@ -32,7 +32,8 @@ const char* errors[] = {
[ERR_DLG_OPEN_QUIT] = "Press Esc to close dialog",
[ERR_EMPTY_FILE] = "No msgids to edit",
[ERR_CANT_ALLOC] = "Memory allocation failed - exit advised",
- [ERR_CANT_SAVE] = "File is not writeable"
+ [ERR_CANT_SAVE] = "File is not writeable",
+ [ERR_CANT_MOVE] = "Cannot move temporary file"
};
const char* flag_strings[] = {
[FL_C_FORMAT] = "c-format",
diff --git a/po.c b/po.c
@@ -1,3 +1,4 @@
+#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -375,7 +376,10 @@ save_file(const struct PoEntry* entries, const size_t msgid_count,
size_t len = strlen(filename);
FILE* output = NULL;
char* backup_filename = calloc(len+2, 1);
- char* tmp_filename = "/tmp/poe.tmp";
+ char tmp_filename[MAXPATH];
+ strcpy(tmp_filename, filename);
+ dirname(tmp_filename);
+ strncat(tmp_filename, "/poe.tmp", MAXPATH-1);
if (!(output = fopen(tmp_filename, "wt")))
return SAVE_ERR_CANT_OPEN_FILE;
@@ -635,8 +639,10 @@ save_file(const struct PoEntry* entries, const size_t msgid_count,
}
fclose(output);
- rename(filename, backup_filename);
- rename(tmp_filename, filename);
+ if (rename(filename, backup_filename) == -1)
+ return SAVE_ERR_CANT_MOVE_FILE;
+ if (rename(tmp_filename, filename) == -1)
+ return SAVE_ERR_CANT_MOVE_FILE;
free(backup_filename);
return SAVE_ERR_NONE;
diff --git a/po.h b/po.h
@@ -31,7 +31,8 @@ enum {
enum {
SAVE_ERR_NONE = 0,
SAVE_ERR_CANT_ALLOC = 1,
- SAVE_ERR_CANT_OPEN_FILE = 2
+ SAVE_ERR_CANT_OPEN_FILE = 2,
+ SAVE_ERR_CANT_MOVE_FILE = 3
};
typedef enum {
diff --git a/poe.1.in b/poe.1.in
@@ -133,8 +133,8 @@ Only one file can be edited at a time, and no additional files can be loaded at
runtime. This is a design decision.
.
.IP \(bu
-The directory \fC/tmp\fP must be writeable by the user in order to write the
-changes to the file. This is due to creating backups in order to avoid the
+The directory of the edited file must be writeable by the user in order to write
+the changes to the file. This is due to creating backups in order to avoid the
potential data loss under specific circumstances (loss of power during write).
.
.SH BUGS
diff --git a/poe.c b/poe.c
@@ -1124,6 +1124,10 @@ handle_key_event(struct tb_event* ev, struct DrawState* state)
case SAVE_ERR_CANT_OPEN_FILE:
strcpy(state->error, errors[ERR_CANT_SAVE]);
break;
+ case SAVE_ERR_CANT_MOVE_FILE:
+ strcpy(state->error, strerror(errno));
+ break;
+ case SAVE_ERR_NONE:
default:
state->error[0] = 0;
}
diff --git a/util.h b/util.h
@@ -11,7 +11,8 @@ enum {
ERR_DLG_OPEN_QUIT,
ERR_EMPTY_FILE,
ERR_CANT_ALLOC,
- ERR_CANT_SAVE
+ ERR_CANT_SAVE,
+ ERR_CANT_MOVE
};
#define MAXBUFLINE 4096