mirror of
https://github.com/wiiu-env/libfat.git
synced 2024-11-22 01:49:17 +01:00
add locks for threaded systems.
fix eof conditions https://sourceforge.net/tracker/?func=detail&atid=668553&aid=1970541&group_id=114505
This commit is contained in:
parent
8843a36ea2
commit
8b9d437f76
@ -62,6 +62,7 @@
|
||||
#include "directory.h"
|
||||
#include "bit_ops.h"
|
||||
#include "filetime.h"
|
||||
#include "lock.h"
|
||||
|
||||
|
||||
int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
|
||||
@ -70,9 +71,11 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
|
||||
DIR_ENTRY dirEntry;
|
||||
|
||||
// Get the partition this file is on
|
||||
_FAT_lock();
|
||||
partition = _FAT_partition_getPartitionFromPath (path);
|
||||
|
||||
if (partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
@ -82,12 +85,14 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
|
||||
path = strchr (path, ':') + 1;
|
||||
}
|
||||
if (strchr (path, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search for the file on the disc
|
||||
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@ -95,6 +100,7 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
|
||||
// Fill in the stat struct
|
||||
_FAT_directory_entryStat (partition, &dirEntry, st);
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -112,15 +118,18 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
|
||||
bool errorOccured = false;
|
||||
|
||||
// Get the partition this directory is on
|
||||
_FAT_lock();
|
||||
partition = _FAT_partition_getPartitionFromPath (path);
|
||||
|
||||
if (partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we aren't trying to write to a read-only disc
|
||||
if (partition->readOnly) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
@ -130,12 +139,14 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
|
||||
path = strchr (path, ':') + 1;
|
||||
}
|
||||
if (strchr (path, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search for the file on the disc
|
||||
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@ -150,6 +161,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
|
||||
while (nextEntry) {
|
||||
if (!_FAT_directory_isDot (&dirContents)) {
|
||||
// The directory had something in it that isn't a reference to itself or it's parent
|
||||
_FAT_unlock();
|
||||
r->_errno = EPERM;
|
||||
return -1;
|
||||
}
|
||||
@ -177,6 +189,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
|
||||
errorOccured = true;
|
||||
}
|
||||
|
||||
_FAT_unlock();
|
||||
if (errorOccured) {
|
||||
return -1;
|
||||
} else {
|
||||
@ -188,9 +201,11 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
|
||||
PARTITION* partition = NULL;
|
||||
|
||||
// Get the partition this directory is on
|
||||
_FAT_lock();
|
||||
partition = _FAT_partition_getPartitionFromPath (path);
|
||||
|
||||
if (partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
@ -200,12 +215,14 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
|
||||
path = strchr (path, ':') + 1;
|
||||
}
|
||||
if (strchr (path, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set the default device to match this one
|
||||
if (!_FAT_partition_setDefaultPartition (partition)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@ -213,9 +230,11 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
|
||||
// Try changing directory
|
||||
if (_FAT_directory_chdir (partition, path)) {
|
||||
// Successful
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
} else {
|
||||
// Failed
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
@ -229,21 +248,25 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
|
||||
u32 dirCluster;
|
||||
|
||||
// Get the partition this directory is on
|
||||
_FAT_lock();
|
||||
partition = _FAT_partition_getPartitionFromPath (oldName);
|
||||
|
||||
if (partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure the same partition is used for the old and new names
|
||||
if (partition != _FAT_partition_getPartitionFromPath (newName)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EXDEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we aren't trying to write to a read-only disc
|
||||
if (partition->readOnly) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
@ -253,6 +276,7 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
|
||||
oldName = strchr (oldName, ':') + 1;
|
||||
}
|
||||
if (strchr (oldName, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@ -260,18 +284,21 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
|
||||
newName = strchr (newName, ':') + 1;
|
||||
}
|
||||
if (strchr (newName, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search for the file on the disc
|
||||
if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure there is no existing file / directory with the new name
|
||||
if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
@ -288,6 +315,7 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
|
||||
// Recycling newDirEntry, since it needs to be recreated anyway
|
||||
if (!_FAT_directory_entryFromPath (partition, &newDirEntry, newName, pathEnd) ||
|
||||
!_FAT_directory_isDirectory(&newDirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
@ -304,22 +332,26 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
|
||||
|
||||
// Write the new entry
|
||||
if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Remove the old entry
|
||||
if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Flush any sectors in the disc cache
|
||||
if (!_FAT_cache_flush (partition->cache)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -330,10 +362,12 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
const char* pathEnd;
|
||||
u32 parentCluster, dirCluster;
|
||||
u8 newEntryData[DIR_ENTRY_DATA_SIZE];
|
||||
|
||||
|
||||
_FAT_lock();
|
||||
partition = _FAT_partition_getPartitionFromPath (path);
|
||||
|
||||
if (partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
@ -343,6 +377,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
path = strchr (path, ':') + 1;
|
||||
}
|
||||
if (strchr (path, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@ -352,12 +387,14 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
|
||||
// Make sure it doesn't exist
|
||||
if (fileExists) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (partition->readOnly) {
|
||||
// We can't write to a read-only partition
|
||||
_FAT_unlock();
|
||||
r->_errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
@ -373,6 +410,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
// Recycling dirEntry, since it needs to be recreated anyway
|
||||
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) ||
|
||||
!_FAT_directory_isDirectory(&dirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
@ -396,6 +434,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
dirCluster = _FAT_fat_linkFreeClusterCleared (partition, CLUSTER_FREE);
|
||||
if (!_FAT_fat_isValidCluster(partition, dirCluster)) {
|
||||
// No space left on disc for the cluster
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
@ -404,6 +443,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
|
||||
// Write the new directory's entry to it's parent
|
||||
if (!_FAT_directory_addEntry (partition, &dirEntry, parentCluster)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
@ -432,10 +472,12 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
|
||||
|
||||
// Flush any sectors in the disc cache
|
||||
if (!_FAT_cache_flush(partition->cache)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -445,9 +487,11 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
|
||||
u32 freeClusterCount;
|
||||
|
||||
// Get the partition of the requested path
|
||||
_FAT_lock();
|
||||
partition = _FAT_partition_getPartitionFromPath (path);
|
||||
|
||||
if (partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
@ -476,6 +520,7 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
|
||||
// Maximum filename length.
|
||||
buf->f_namemax = MAX_FILENAME_LENGTH;
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -484,9 +529,11 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
|
||||
DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
|
||||
bool fileExists;
|
||||
|
||||
_FAT_lock();
|
||||
state->partition = _FAT_partition_getPartitionFromPath (path);
|
||||
|
||||
if (state->partition == NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENODEV;
|
||||
return NULL;
|
||||
}
|
||||
@ -496,6 +543,7 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
|
||||
path = strchr (path, ':') + 1;
|
||||
}
|
||||
if (strchr (path, ':') != NULL) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
@ -503,12 +551,14 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
|
||||
fileExists = _FAT_directory_entryFromPath (state->partition, &dirEntry, path, NULL);
|
||||
|
||||
if (!fileExists) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure it is a directory
|
||||
if (! _FAT_directory_isDirectory (&dirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOTDIR;
|
||||
return NULL;
|
||||
}
|
||||
@ -522,6 +572,7 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
|
||||
|
||||
// We are now using this entry
|
||||
state->inUse = true;
|
||||
_FAT_unlock();
|
||||
return (DIR_ITER*) state;
|
||||
}
|
||||
|
||||
@ -529,7 +580,9 @@ int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) {
|
||||
DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
|
||||
|
||||
// Make sure we are still using this entry
|
||||
_FAT_lock();
|
||||
if (!state->inUse) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
@ -538,6 +591,7 @@ int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) {
|
||||
state->validEntry =
|
||||
_FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster);
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -545,13 +599,16 @@ int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
|
||||
DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
|
||||
|
||||
// Make sure we are still using this entry
|
||||
_FAT_lock();
|
||||
if (!state->inUse) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure there is another file to report on
|
||||
if (! state->validEntry) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@ -567,6 +624,7 @@ int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
|
||||
state->validEntry =
|
||||
_FAT_directory_getNextEntry (state->partition, &(state->currentEntry));
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -574,7 +632,9 @@ int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState) {
|
||||
DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
|
||||
|
||||
// We are no longer using this entry
|
||||
_FAT_lock();
|
||||
state->inUse = false;
|
||||
_FAT_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "file_allocation_table.h"
|
||||
#include "bit_ops.h"
|
||||
#include "filetime.h"
|
||||
#include "lock.h"
|
||||
|
||||
int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) {
|
||||
PARTITION* partition = NULL;
|
||||
@ -127,16 +128,19 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
}
|
||||
|
||||
// Search for the file on the disc
|
||||
_FAT_lock();
|
||||
fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL);
|
||||
|
||||
// The file shouldn't exist if we are trying to create it
|
||||
if ((flags & O_CREAT) && (flags & O_EXCL) && fileExists) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// It should not be a directory if we're openning a file,
|
||||
if (fileExists && _FAT_directory_isDirectory(&dirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EISDIR;
|
||||
return -1;
|
||||
}
|
||||
@ -146,6 +150,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
if (flags & O_CREAT) {
|
||||
if (partition->readOnly) {
|
||||
// We can't write to a read-only partition
|
||||
_FAT_unlock();
|
||||
r->_errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
@ -161,6 +166,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
// Recycling dirEntry, since it needs to be recreated anyway
|
||||
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) ||
|
||||
!_FAT_directory_isDirectory(&dirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
@ -178,11 +184,13 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cDate, _FAT_filetime_getDateFromRTC());
|
||||
|
||||
if (!_FAT_directory_addEntry (partition, &dirEntry, dirCluster)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// file doesn't exist, and we aren't creating it
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@ -200,6 +208,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
|
||||
// Make sure we aren't trying to write to a read-only file
|
||||
if (file->write && !_FAT_directory_isWritable(&dirEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
@ -243,6 +252,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
file->inUse = true;
|
||||
|
||||
partition->openFileCount += 1;
|
||||
_FAT_unlock();
|
||||
|
||||
return (int) file;
|
||||
}
|
||||
@ -251,7 +261,9 @@ int _FAT_close_r (struct _reent *r, int fd) {
|
||||
FILE_STRUCT* file = (FILE_STRUCT*) fd;
|
||||
u8 dirEntryData[DIR_ENTRY_DATA_SIZE];
|
||||
|
||||
_FAT_lock();
|
||||
if (!file->inUse) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
@ -283,13 +295,16 @@ int _FAT_close_r (struct _reent *r, int fd) {
|
||||
|
||||
// Flush any sectors in the disc cache
|
||||
if (!_FAT_cache_flush(file->partition->cache)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
file->inUse = false;
|
||||
file->partition->openFileCount -= 1;
|
||||
_FAT_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -310,14 +325,18 @@ int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len) {
|
||||
bool flagNoError = true;
|
||||
|
||||
// Make sure we can actually read from the file
|
||||
_FAT_lock();
|
||||
if ((file == NULL) || !file->inUse || !file->read) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Don't try to read if the read pointer is past the end of file
|
||||
if (file->currentPosition >= file->filesize || file->startCluster == CLUSTER_FREE) {
|
||||
return -1;
|
||||
r->_errno = EOVERFLOW;
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Don't read past end of file
|
||||
@ -328,6 +347,7 @@ int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len) {
|
||||
|
||||
// Short circuit cases where len is 0 (or less)
|
||||
if (len <= 0) {
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -451,6 +471,8 @@ int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len) {
|
||||
// Update file information
|
||||
file->rwPosition = position;
|
||||
file->currentPosition += len;
|
||||
|
||||
_FAT_unlock();
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -468,7 +490,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
||||
u8 zeroBuffer [BYTES_PER_READ] = {0};
|
||||
|
||||
u32 tempNextCluster;
|
||||
|
||||
|
||||
position.byte = file->filesize % BYTES_PER_READ;
|
||||
position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
||||
// It is assumed that there is always a startCluster
|
||||
@ -571,13 +593,16 @@ int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) {
|
||||
bool flagAppending = false;
|
||||
|
||||
// Make sure we can actually write to the file
|
||||
_FAT_lock();
|
||||
if ((file == NULL) || !file->inUse || !file->write) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Short circuit cases where len is 0 (or less)
|
||||
if (len <= 0) {
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -590,6 +615,7 @@ int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) {
|
||||
tempNextCluster = _FAT_fat_linkFreeCluster (partition, CLUSTER_FREE);
|
||||
if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) {
|
||||
// Couldn't get a cluster, so abort immediately
|
||||
_FAT_unlock();
|
||||
r->_errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
@ -612,6 +638,7 @@ int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) {
|
||||
// If the write pointer is past the end of the file, extend the file to that size
|
||||
if (file->currentPosition > file->filesize) {
|
||||
if (!_FAT_file_extend_r (r, file)) {
|
||||
_FAT_unlock();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -777,6 +804,8 @@ int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) {
|
||||
file->filesize = file->currentPosition;
|
||||
}
|
||||
}
|
||||
|
||||
_FAT_unlock();
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -791,8 +820,10 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
|
||||
int clusCount;
|
||||
int position;
|
||||
|
||||
_FAT_lock();
|
||||
if ((file == NULL) || (file->inUse == false)) {
|
||||
// invalid file
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
@ -810,16 +841,19 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
|
||||
position = file->filesize + pos;
|
||||
break;
|
||||
default:
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((pos > 0) && (position < 0)) {
|
||||
r->_errno = EOVERFLOW;
|
||||
_FAT_unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (position < 0) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@ -855,6 +889,7 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
|
||||
file->rwPosition.sector = partition->sectorsPerCluster;
|
||||
file->rwPosition.byte = 0;
|
||||
} else {
|
||||
_FAT_unlock();
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@ -866,6 +901,7 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
|
||||
// Save position
|
||||
file->currentPosition = position;
|
||||
|
||||
_FAT_unlock();
|
||||
return position;
|
||||
}
|
||||
|
||||
@ -878,8 +914,10 @@ int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) {
|
||||
|
||||
DIR_ENTRY fileEntry;
|
||||
|
||||
_FAT_lock();
|
||||
if ((file == NULL) || (file->inUse == false)) {
|
||||
// invalid file
|
||||
_FAT_unlock();
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
@ -891,6 +929,7 @@ int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) {
|
||||
fileEntry.dataEnd = file->dirEntryEnd;
|
||||
|
||||
if (!_FAT_directory_entryFromPosition (partition, &fileEntry)) {
|
||||
_FAT_unlock();
|
||||
r->_errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
@ -902,6 +941,7 @@ int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) {
|
||||
st->st_ino = (ino_t)(file->startCluster); // The file serial number is the start cluster
|
||||
st->st_size = file->filesize; // File size
|
||||
|
||||
_FAT_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "partition.h"
|
||||
#include "fatfile.h"
|
||||
#include "fatdir.h"
|
||||
#include "lock.h"
|
||||
|
||||
#ifdef GBA
|
||||
#define DEFAULT_CACHE_PAGES 2
|
||||
@ -127,6 +128,9 @@ bool fatInit (u32 cacheSize, bool setAsDefaultDevice) {
|
||||
#endif
|
||||
chdir (filePath);
|
||||
}
|
||||
|
||||
_FAT_lock_init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user