Merge pull request #10973 from hpvb/fix-file-access-unix
Make UNIX file access more correct
This commit is contained in:
commit
27feafbe12
1 changed files with 65 additions and 23 deletions
|
@ -36,12 +36,17 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined(UNIX_ENABLED)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ANDROID_ENABLED
|
#ifndef ANDROID_ENABLED
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MSVC
|
#ifdef MSVC
|
||||||
#define S_ISREG(m) ((m)&_S_IFREG)
|
#define S_ISREG(m) ((m)&_S_IFREG)
|
||||||
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef S_ISREG
|
#ifndef S_ISREG
|
||||||
#define S_ISREG(m) ((m)&S_IFREG)
|
#define S_ISREG(m) ((m)&S_IFREG)
|
||||||
|
@ -85,13 +90,19 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
|
||||||
|
|
||||||
//printf("opening %s as %s\n", p_path.utf8().get_data(), path.utf8().get_data());
|
//printf("opening %s as %s\n", p_path.utf8().get_data(), path.utf8().get_data());
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path.utf8().get_data(), &st) == 0) {
|
int err = stat(path.utf8().get_data(), &st);
|
||||||
|
if (err)
|
||||||
if (!S_ISREG(st.st_mode))
|
|
||||||
return ERR_FILE_CANT_OPEN;
|
return ERR_FILE_CANT_OPEN;
|
||||||
};
|
|
||||||
|
|
||||||
if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) {
|
switch (st.st_mode & S_IFMT) {
|
||||||
|
case S_IFLNK:
|
||||||
|
case S_IFREG:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ERR_FILE_CANT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_backup_save_enabled() && (p_mode_flags & WRITE) && !(p_mode_flags & READ)) {
|
||||||
save_path = path;
|
save_path = path;
|
||||||
path = path + ".tmp";
|
path = path + ".tmp";
|
||||||
//print_line("saving instead to "+path);
|
//print_line("saving instead to "+path);
|
||||||
|
@ -108,15 +119,19 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccessUnix::close() {
|
void FileAccessUnix::close() {
|
||||||
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
f = NULL;
|
f = NULL;
|
||||||
|
|
||||||
if (close_notification_func) {
|
if (close_notification_func) {
|
||||||
close_notification_func(path, flags);
|
close_notification_func(path, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (save_path != "") {
|
if (save_path != "") {
|
||||||
|
|
||||||
//unlink(save_path.utf8().get_data());
|
//unlink(save_path.utf8().get_data());
|
||||||
|
@ -131,10 +146,12 @@ void FileAccessUnix::close() {
|
||||||
ERR_FAIL_COND(rename_error != 0);
|
ERR_FAIL_COND(rename_error != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileAccessUnix::is_open() const {
|
bool FileAccessUnix::is_open() const {
|
||||||
|
|
||||||
return (f != NULL);
|
return (f != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccessUnix::seek(size_t p_position) {
|
void FileAccessUnix::seek(size_t p_position) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
|
@ -143,29 +160,39 @@ void FileAccessUnix::seek(size_t p_position) {
|
||||||
if (fseek(f, p_position, SEEK_SET))
|
if (fseek(f, p_position, SEEK_SET))
|
||||||
check_errors();
|
check_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccessUnix::seek_end(int64_t p_position) {
|
void FileAccessUnix::seek_end(int64_t p_position) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
|
|
||||||
|
last_error = OK;
|
||||||
if (fseek(f, p_position, SEEK_END))
|
if (fseek(f, p_position, SEEK_END))
|
||||||
check_errors();
|
check_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FileAccessUnix::get_pos() const {
|
size_t FileAccessUnix::get_pos() const {
|
||||||
|
|
||||||
size_t aux_position = 0;
|
ERR_FAIL_COND_V(!f, 0);
|
||||||
if (!(aux_position = ftell(f))) {
|
|
||||||
|
last_error = OK;
|
||||||
|
int pos = ftell(f);
|
||||||
|
if (pos < 0) {
|
||||||
check_errors();
|
check_errors();
|
||||||
};
|
ERR_FAIL_V(0);
|
||||||
return aux_position;
|
}
|
||||||
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FileAccessUnix::get_len() const {
|
size_t FileAccessUnix::get_len() const {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!f, 0);
|
ERR_FAIL_COND_V(!f, 0);
|
||||||
|
|
||||||
FileAccessUnix *fau = const_cast<FileAccessUnix *>(this);
|
int pos = ftell(f);
|
||||||
int pos = fau->get_pos();
|
ERR_FAIL_COND_V(pos < 0, 0);
|
||||||
fau->seek_end();
|
ERR_FAIL_COND_V(fseek(f, 0, SEEK_END), 0);
|
||||||
int size = fau->get_pos();
|
int size = ftell(f);
|
||||||
fau->seek(pos);
|
ERR_FAIL_COND_V(size < 0, 0);
|
||||||
|
ERR_FAIL_COND_V(fseek(f, pos, SEEK_SET), 0);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -202,22 +229,36 @@ Error FileAccessUnix::get_error() const {
|
||||||
void FileAccessUnix::store_8(uint8_t p_dest) {
|
void FileAccessUnix::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
fwrite(&p_dest, 1, 1, f);
|
ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileAccessUnix::file_exists(const String &p_path) {
|
bool FileAccessUnix::file_exists(const String &p_path) {
|
||||||
|
|
||||||
FILE *g;
|
int err;
|
||||||
//printf("opening file %s\n", p_fname.c_str());
|
struct stat st;
|
||||||
String filename = fix_path(p_path);
|
String filename = fix_path(p_path);
|
||||||
g = fopen(filename.utf8().get_data(), "rb");
|
|
||||||
if (g == NULL) {
|
|
||||||
|
|
||||||
|
// Does the name exist at all?
|
||||||
|
err = stat(filename.utf8().get_data(), &st);
|
||||||
|
if (err)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
|
|
||||||
fclose(g);
|
#ifdef UNIX_ENABLED
|
||||||
|
// See if we have access to the file
|
||||||
|
if (access(filename.utf8().get_data(), F_OK))
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
if (_access(filename.utf8().get_data(), 4) == -1)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// See if this is a regular file
|
||||||
|
switch (st.st_mode & S_IFMT) {
|
||||||
|
case S_IFLNK:
|
||||||
|
case S_IFREG:
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +266,9 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
|
||||||
|
|
||||||
String file = fix_path(p_file);
|
String file = fix_path(p_file);
|
||||||
struct stat flags;
|
struct stat flags;
|
||||||
bool success = (stat(file.utf8().get_data(), &flags) == 0);
|
int err = stat(file.utf8().get_data(), &flags);
|
||||||
|
|
||||||
if (success) {
|
if (!err) {
|
||||||
return flags.st_mtime;
|
return flags.st_mtime;
|
||||||
} else {
|
} else {
|
||||||
print_line("ERROR IN: " + p_file);
|
print_line("ERROR IN: " + p_file);
|
||||||
|
@ -249,6 +290,7 @@ FileAccessUnix::FileAccessUnix() {
|
||||||
flags = 0;
|
flags = 0;
|
||||||
last_error = OK;
|
last_error = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileAccessUnix::~FileAccessUnix() {
|
FileAccessUnix::~FileAccessUnix() {
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
Loading…
Reference in a new issue