* edit.c (check_file_access): Use non-blocking open() followed
by fstat() to avoid race conditions. Don't ask users to recompile the editor.
Этот коммит содержится в:
родитель
2eb1245290
Коммит
857565ca21
@ -1,5 +1,9 @@
|
|||||||
2002-12-15 Pavel Roskin <proski@gnu.org>
|
2002-12-15 Pavel Roskin <proski@gnu.org>
|
||||||
|
|
||||||
|
* edit.c (check_file_access): Use non-blocking open() followed
|
||||||
|
by fstat() to avoid race conditions. Don't ask users to
|
||||||
|
recompile the editor.
|
||||||
|
|
||||||
* edit.c (edit_reload): Don't initialize edit->macro_i, because
|
* edit.c (edit_reload): Don't initialize edit->macro_i, because
|
||||||
edit_init() takes care of it.
|
edit_init() takes care of it.
|
||||||
* editwidget.c (edit): Likewise.
|
* editwidget.c (edit): Likewise.
|
||||||
|
78
edit/edit.c
78
edit/edit.c
@ -328,38 +328,34 @@ static int
|
|||||||
check_file_access (WEdit *edit, const char *filename, struct stat *st)
|
check_file_access (WEdit *edit, const char *filename, struct stat *st)
|
||||||
{
|
{
|
||||||
int file;
|
int file;
|
||||||
int flags;
|
|
||||||
int stat_ok = 0;
|
|
||||||
|
|
||||||
/* Try stat first to prevent getting stuck on pipes */
|
/* Try opening an existing file */
|
||||||
if (mc_stat ((char *) filename, st) == 0) {
|
file = mc_open (filename, O_NONBLOCK | O_RDONLY | O_BINARY, 0666);
|
||||||
stat_ok = 1;
|
|
||||||
|
if (file < 0) {
|
||||||
|
/*
|
||||||
|
* Try creating the file. O_EXCL prevents following broken links
|
||||||
|
* and opening existing files.
|
||||||
|
*/
|
||||||
|
file =
|
||||||
|
mc_open (filename,
|
||||||
|
O_NONBLOCK | O_RDONLY | O_BINARY | O_CREAT | O_EXCL,
|
||||||
|
0666);
|
||||||
|
if (file < 0) {
|
||||||
|
edit_error_dialog (_("Error"),
|
||||||
|
get_sys_error (catstrs
|
||||||
|
(_
|
||||||
|
(" Cannot open file for reading: "),
|
||||||
|
filename, " ", 0)));
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* New file, delete it if it's not modified or saved */
|
||||||
|
edit->delete_file = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only regular files are allowed */
|
/* Check what we have opened */
|
||||||
if (stat_ok && !S_ISREG (st->st_mode)) {
|
if (mc_fstat (file, st) < 0) {
|
||||||
edit_error_dialog (_("Error"),
|
|
||||||
catstrs (_(" Not an ordinary file: "), filename,
|
|
||||||
" ", 0));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file, create it if (and only if!) needed */
|
|
||||||
flags = O_RDONLY | O_CREAT | O_BINARY;
|
|
||||||
if (!stat_ok)
|
|
||||||
flags |= O_EXCL;
|
|
||||||
|
|
||||||
if ((file = mc_open (filename, flags, 0666)) < 0) {
|
|
||||||
edit_error_dialog (_("Error"),
|
|
||||||
get_sys_error (catstrs
|
|
||||||
(_
|
|
||||||
(" Cannot open file for reading: "),
|
|
||||||
filename, " ", 0)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the file has just been created, we don't have valid stat yet, so do it now */
|
|
||||||
if (!stat_ok && mc_fstat (file, st) < 0) {
|
|
||||||
mc_close (file);
|
mc_close (file);
|
||||||
edit_error_dialog (_("Error"),
|
edit_error_dialog (_("Error"),
|
||||||
get_sys_error (catstrs
|
get_sys_error (catstrs
|
||||||
@ -368,22 +364,34 @@ check_file_access (WEdit *edit, const char *filename, struct stat *st)
|
|||||||
filename, " ", 0)));
|
filename, " ", 0)));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We want to open regular files only */
|
||||||
|
if (!S_ISREG (st->st_mode)) {
|
||||||
|
mc_close (file);
|
||||||
|
edit_error_dialog (_("Error"),
|
||||||
|
catstrs (_(" Not an ordinary file: "), filename,
|
||||||
|
" ", 0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
mc_close (file);
|
mc_close (file);
|
||||||
|
|
||||||
/* If it's a new file, delete it if it's not modified or saved */
|
/*
|
||||||
if (!stat_ok && st->st_size == 0) {
|
* Don't delete non-empty files.
|
||||||
edit->delete_file = 1;
|
* O_EXCL should prevent it, but let's be on the safe side.
|
||||||
|
*/
|
||||||
|
if (st->st_size > 0) {
|
||||||
|
edit->delete_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->st_size >= SIZE_LIMIT) {
|
if (st->st_size >= SIZE_LIMIT) {
|
||||||
/* The file-name is printed after the ':' */
|
mc_close (file);
|
||||||
edit_error_dialog (_("Error"),
|
edit_error_dialog (_("Error"),
|
||||||
catstrs (_(" File is too large: "), filename,
|
catstrs (_(" File is too large: "), filename,
|
||||||
_
|
|
||||||
(" \n Increase edit.h:MAXBUF and recompile the editor. "),
|
|
||||||
0));
|
0));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user