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:
Dave Murphy 2008-05-23 19:37:46 +00:00
parent 8843a36ea2
commit 8b9d437f76
3 changed files with 107 additions and 3 deletions

View File

@ -62,6 +62,7 @@
#include "directory.h" #include "directory.h"
#include "bit_ops.h" #include "bit_ops.h"
#include "filetime.h" #include "filetime.h"
#include "lock.h"
int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) { 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; DIR_ENTRY dirEntry;
// Get the partition this file is on // Get the partition this file is on
_FAT_lock();
partition = _FAT_partition_getPartitionFromPath (path); partition = _FAT_partition_getPartitionFromPath (path);
if (partition == NULL) { if (partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
@ -82,12 +85,14 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
path = strchr (path, ':') + 1; path = strchr (path, ':') + 1;
} }
if (strchr (path, ':') != NULL) { if (strchr (path, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
// Search for the file on the disc // Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) { if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) {
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return -1; return -1;
} }
@ -95,6 +100,7 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
// Fill in the stat struct // Fill in the stat struct
_FAT_directory_entryStat (partition, &dirEntry, st); _FAT_directory_entryStat (partition, &dirEntry, st);
_FAT_unlock();
return 0; return 0;
} }
@ -112,15 +118,18 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
bool errorOccured = false; bool errorOccured = false;
// Get the partition this directory is on // Get the partition this directory is on
_FAT_lock();
partition = _FAT_partition_getPartitionFromPath (path); partition = _FAT_partition_getPartitionFromPath (path);
if (partition == NULL) { if (partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
// Make sure we aren't trying to write to a read-only disc // Make sure we aren't trying to write to a read-only disc
if (partition->readOnly) { if (partition->readOnly) {
_FAT_unlock();
r->_errno = EROFS; r->_errno = EROFS;
return -1; return -1;
} }
@ -130,12 +139,14 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
path = strchr (path, ':') + 1; path = strchr (path, ':') + 1;
} }
if (strchr (path, ':') != NULL) { if (strchr (path, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
// Search for the file on the disc // Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) { if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) {
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return -1; return -1;
} }
@ -150,6 +161,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
while (nextEntry) { while (nextEntry) {
if (!_FAT_directory_isDot (&dirContents)) { if (!_FAT_directory_isDot (&dirContents)) {
// The directory had something in it that isn't a reference to itself or it's parent // The directory had something in it that isn't a reference to itself or it's parent
_FAT_unlock();
r->_errno = EPERM; r->_errno = EPERM;
return -1; return -1;
} }
@ -177,6 +189,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
errorOccured = true; errorOccured = true;
} }
_FAT_unlock();
if (errorOccured) { if (errorOccured) {
return -1; return -1;
} else { } else {
@ -188,9 +201,11 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
PARTITION* partition = NULL; PARTITION* partition = NULL;
// Get the partition this directory is on // Get the partition this directory is on
_FAT_lock();
partition = _FAT_partition_getPartitionFromPath (path); partition = _FAT_partition_getPartitionFromPath (path);
if (partition == NULL) { if (partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
@ -200,12 +215,14 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
path = strchr (path, ':') + 1; path = strchr (path, ':') + 1;
} }
if (strchr (path, ':') != NULL) { if (strchr (path, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
// Set the default device to match this one // Set the default device to match this one
if (!_FAT_partition_setDefaultPartition (partition)) { if (!_FAT_partition_setDefaultPartition (partition)) {
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return -1; return -1;
} }
@ -213,9 +230,11 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
// Try changing directory // Try changing directory
if (_FAT_directory_chdir (partition, path)) { if (_FAT_directory_chdir (partition, path)) {
// Successful // Successful
_FAT_unlock();
return 0; return 0;
} else { } else {
// Failed // Failed
_FAT_unlock();
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return -1; return -1;
} }
@ -229,21 +248,25 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
u32 dirCluster; u32 dirCluster;
// Get the partition this directory is on // Get the partition this directory is on
_FAT_lock();
partition = _FAT_partition_getPartitionFromPath (oldName); partition = _FAT_partition_getPartitionFromPath (oldName);
if (partition == NULL) { if (partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
// Make sure the same partition is used for the old and new names // Make sure the same partition is used for the old and new names
if (partition != _FAT_partition_getPartitionFromPath (newName)) { if (partition != _FAT_partition_getPartitionFromPath (newName)) {
_FAT_unlock();
r->_errno = EXDEV; r->_errno = EXDEV;
return -1; return -1;
} }
// Make sure we aren't trying to write to a read-only disc // Make sure we aren't trying to write to a read-only disc
if (partition->readOnly) { if (partition->readOnly) {
_FAT_unlock();
r->_errno = EROFS; r->_errno = EROFS;
return -1; return -1;
} }
@ -253,6 +276,7 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
oldName = strchr (oldName, ':') + 1; oldName = strchr (oldName, ':') + 1;
} }
if (strchr (oldName, ':') != NULL) { if (strchr (oldName, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
@ -260,18 +284,21 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
newName = strchr (newName, ':') + 1; newName = strchr (newName, ':') + 1;
} }
if (strchr (newName, ':') != NULL) { if (strchr (newName, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
// Search for the file on the disc // Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) { if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) {
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return -1; return -1;
} }
// Make sure there is no existing file / directory with the new name // Make sure there is no existing file / directory with the new name
if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) { if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) {
_FAT_unlock();
r->_errno = EEXIST; r->_errno = EEXIST;
return -1; 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 // Recycling newDirEntry, since it needs to be recreated anyway
if (!_FAT_directory_entryFromPath (partition, &newDirEntry, newName, pathEnd) || if (!_FAT_directory_entryFromPath (partition, &newDirEntry, newName, pathEnd) ||
!_FAT_directory_isDirectory(&newDirEntry)) { !_FAT_directory_isDirectory(&newDirEntry)) {
_FAT_unlock();
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return -1; return -1;
} }
@ -304,22 +332,26 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
// Write the new entry // Write the new entry
if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) { if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) {
_FAT_unlock();
r->_errno = ENOSPC; r->_errno = ENOSPC;
return -1; return -1;
} }
// Remove the old entry // Remove the old entry
if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) { if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) {
_FAT_unlock();
r->_errno = EIO; r->_errno = EIO;
return -1; return -1;
} }
// Flush any sectors in the disc cache // Flush any sectors in the disc cache
if (!_FAT_cache_flush (partition->cache)) { if (!_FAT_cache_flush (partition->cache)) {
_FAT_unlock();
r->_errno = EIO; r->_errno = EIO;
return -1; return -1;
} }
_FAT_unlock();
return 0; return 0;
} }
@ -331,9 +363,11 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
u32 parentCluster, dirCluster; u32 parentCluster, dirCluster;
u8 newEntryData[DIR_ENTRY_DATA_SIZE]; u8 newEntryData[DIR_ENTRY_DATA_SIZE];
_FAT_lock();
partition = _FAT_partition_getPartitionFromPath (path); partition = _FAT_partition_getPartitionFromPath (path);
if (partition == NULL) { if (partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
@ -343,6 +377,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
path = strchr (path, ':') + 1; path = strchr (path, ':') + 1;
} }
if (strchr (path, ':') != NULL) { if (strchr (path, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
@ -352,12 +387,14 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
// Make sure it doesn't exist // Make sure it doesn't exist
if (fileExists) { if (fileExists) {
_FAT_unlock();
r->_errno = EEXIST; r->_errno = EEXIST;
return -1; return -1;
} }
if (partition->readOnly) { if (partition->readOnly) {
// We can't write to a read-only partition // We can't write to a read-only partition
_FAT_unlock();
r->_errno = EROFS; r->_errno = EROFS;
return -1; 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 // Recycling dirEntry, since it needs to be recreated anyway
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) || if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) ||
!_FAT_directory_isDirectory(&dirEntry)) { !_FAT_directory_isDirectory(&dirEntry)) {
_FAT_unlock();
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return -1; 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); dirCluster = _FAT_fat_linkFreeClusterCleared (partition, CLUSTER_FREE);
if (!_FAT_fat_isValidCluster(partition, dirCluster)) { if (!_FAT_fat_isValidCluster(partition, dirCluster)) {
// No space left on disc for the cluster // No space left on disc for the cluster
_FAT_unlock();
r->_errno = ENOSPC; r->_errno = ENOSPC;
return -1; 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 // Write the new directory's entry to it's parent
if (!_FAT_directory_addEntry (partition, &dirEntry, parentCluster)) { if (!_FAT_directory_addEntry (partition, &dirEntry, parentCluster)) {
_FAT_unlock();
r->_errno = ENOSPC; r->_errno = ENOSPC;
return -1; 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 // Flush any sectors in the disc cache
if (!_FAT_cache_flush(partition->cache)) { if (!_FAT_cache_flush(partition->cache)) {
_FAT_unlock();
r->_errno = EIO; r->_errno = EIO;
return -1; return -1;
} }
_FAT_unlock();
return 0; return 0;
} }
@ -445,9 +487,11 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
u32 freeClusterCount; u32 freeClusterCount;
// Get the partition of the requested path // Get the partition of the requested path
_FAT_lock();
partition = _FAT_partition_getPartitionFromPath (path); partition = _FAT_partition_getPartitionFromPath (path);
if (partition == NULL) { if (partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
@ -476,6 +520,7 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
// Maximum filename length. // Maximum filename length.
buf->f_namemax = MAX_FILENAME_LENGTH; buf->f_namemax = MAX_FILENAME_LENGTH;
_FAT_unlock();
return 0; 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); DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
bool fileExists; bool fileExists;
_FAT_lock();
state->partition = _FAT_partition_getPartitionFromPath (path); state->partition = _FAT_partition_getPartitionFromPath (path);
if (state->partition == NULL) { if (state->partition == NULL) {
_FAT_unlock();
r->_errno = ENODEV; r->_errno = ENODEV;
return NULL; return NULL;
} }
@ -496,6 +543,7 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
path = strchr (path, ':') + 1; path = strchr (path, ':') + 1;
} }
if (strchr (path, ':') != NULL) { if (strchr (path, ':') != NULL) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return NULL; 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); fileExists = _FAT_directory_entryFromPath (state->partition, &dirEntry, path, NULL);
if (!fileExists) { if (!fileExists) {
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return NULL; return NULL;
} }
// Make sure it is a directory // Make sure it is a directory
if (! _FAT_directory_isDirectory (&dirEntry)) { if (! _FAT_directory_isDirectory (&dirEntry)) {
_FAT_unlock();
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return NULL; 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 // We are now using this entry
state->inUse = true; state->inUse = true;
_FAT_unlock();
return (DIR_ITER*) state; 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); DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
// Make sure we are still using this entry // Make sure we are still using this entry
_FAT_lock();
if (!state->inUse) { if (!state->inUse) {
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
@ -538,6 +591,7 @@ int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) {
state->validEntry = state->validEntry =
_FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster); _FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster);
_FAT_unlock();
return 0; 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); DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
// Make sure we are still using this entry // Make sure we are still using this entry
_FAT_lock();
if (!state->inUse) { if (!state->inUse) {
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
// Make sure there is another file to report on // Make sure there is another file to report on
if (! state->validEntry) { if (! state->validEntry) {
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return -1; return -1;
} }
@ -567,6 +624,7 @@ int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
state->validEntry = state->validEntry =
_FAT_directory_getNextEntry (state->partition, &(state->currentEntry)); _FAT_directory_getNextEntry (state->partition, &(state->currentEntry));
_FAT_unlock();
return 0; 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); DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
// We are no longer using this entry // We are no longer using this entry
_FAT_lock();
state->inUse = false; state->inUse = false;
_FAT_unlock();
return 0; return 0;
} }

View File

@ -75,6 +75,7 @@
#include "file_allocation_table.h" #include "file_allocation_table.h"
#include "bit_ops.h" #include "bit_ops.h"
#include "filetime.h" #include "filetime.h"
#include "lock.h"
int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) {
PARTITION* partition = NULL; 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 // Search for the file on the disc
_FAT_lock();
fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL); fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL);
// The file shouldn't exist if we are trying to create it // The file shouldn't exist if we are trying to create it
if ((flags & O_CREAT) && (flags & O_EXCL) && fileExists) { if ((flags & O_CREAT) && (flags & O_EXCL) && fileExists) {
_FAT_unlock();
r->_errno = EEXIST; r->_errno = EEXIST;
return -1; return -1;
} }
// It should not be a directory if we're openning a file, // It should not be a directory if we're openning a file,
if (fileExists && _FAT_directory_isDirectory(&dirEntry)) { if (fileExists && _FAT_directory_isDirectory(&dirEntry)) {
_FAT_unlock();
r->_errno = EISDIR; r->_errno = EISDIR;
return -1; 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 (flags & O_CREAT) {
if (partition->readOnly) { if (partition->readOnly) {
// We can't write to a read-only partition // We can't write to a read-only partition
_FAT_unlock();
r->_errno = EROFS; r->_errno = EROFS;
return -1; 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 // Recycling dirEntry, since it needs to be recreated anyway
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) || if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) ||
!_FAT_directory_isDirectory(&dirEntry)) { !_FAT_directory_isDirectory(&dirEntry)) {
_FAT_unlock();
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return -1; 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()); u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cDate, _FAT_filetime_getDateFromRTC());
if (!_FAT_directory_addEntry (partition, &dirEntry, dirCluster)) { if (!_FAT_directory_addEntry (partition, &dirEntry, dirCluster)) {
_FAT_unlock();
r->_errno = ENOSPC; r->_errno = ENOSPC;
return -1; return -1;
} }
} else { } else {
// file doesn't exist, and we aren't creating it // file doesn't exist, and we aren't creating it
_FAT_unlock();
r->_errno = ENOENT; r->_errno = ENOENT;
return -1; 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 // Make sure we aren't trying to write to a read-only file
if (file->write && !_FAT_directory_isWritable(&dirEntry)) { if (file->write && !_FAT_directory_isWritable(&dirEntry)) {
_FAT_unlock();
r->_errno = EROFS; r->_errno = EROFS;
return -1; return -1;
} }
@ -243,6 +252,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
file->inUse = true; file->inUse = true;
partition->openFileCount += 1; partition->openFileCount += 1;
_FAT_unlock();
return (int) file; return (int) file;
} }
@ -251,7 +261,9 @@ int _FAT_close_r (struct _reent *r, int fd) {
FILE_STRUCT* file = (FILE_STRUCT*) fd; FILE_STRUCT* file = (FILE_STRUCT*) fd;
u8 dirEntryData[DIR_ENTRY_DATA_SIZE]; u8 dirEntryData[DIR_ENTRY_DATA_SIZE];
_FAT_lock();
if (!file->inUse) { if (!file->inUse) {
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
@ -283,13 +295,16 @@ int _FAT_close_r (struct _reent *r, int fd) {
// Flush any sectors in the disc cache // Flush any sectors in the disc cache
if (!_FAT_cache_flush(file->partition->cache)) { if (!_FAT_cache_flush(file->partition->cache)) {
_FAT_unlock();
r->_errno = EIO; r->_errno = EIO;
return -1; return -1;
} }
} }
file->inUse = false; file->inUse = false;
file->partition->openFileCount -= 1; file->partition->openFileCount -= 1;
_FAT_unlock();
return 0; return 0;
} }
@ -310,14 +325,18 @@ int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len) {
bool flagNoError = true; bool flagNoError = true;
// Make sure we can actually read from the file // Make sure we can actually read from the file
_FAT_lock();
if ((file == NULL) || !file->inUse || !file->read) { if ((file == NULL) || !file->inUse || !file->read) {
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
// Don't try to read if the read pointer is past the end of file // Don't try to read if the read pointer is past the end of file
if (file->currentPosition >= file->filesize || file->startCluster == CLUSTER_FREE) { 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 // 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) // Short circuit cases where len is 0 (or less)
if (len <= 0) { if (len <= 0) {
_FAT_unlock();
return 0; return 0;
} }
@ -451,6 +471,8 @@ int _FAT_read_r (struct _reent *r, int fd, char *ptr, int len) {
// Update file information // Update file information
file->rwPosition = position; file->rwPosition = position;
file->currentPosition += len; file->currentPosition += len;
_FAT_unlock();
return len; return len;
} }
@ -571,13 +593,16 @@ int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) {
bool flagAppending = false; bool flagAppending = false;
// Make sure we can actually write to the file // Make sure we can actually write to the file
_FAT_lock();
if ((file == NULL) || !file->inUse || !file->write) { if ((file == NULL) || !file->inUse || !file->write) {
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
// Short circuit cases where len is 0 (or less) // Short circuit cases where len is 0 (or less)
if (len <= 0) { if (len <= 0) {
_FAT_unlock();
return 0; 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); tempNextCluster = _FAT_fat_linkFreeCluster (partition, CLUSTER_FREE);
if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) {
// Couldn't get a cluster, so abort immediately // Couldn't get a cluster, so abort immediately
_FAT_unlock();
r->_errno = ENOSPC; r->_errno = ENOSPC;
return -1; 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 the write pointer is past the end of the file, extend the file to that size
if (file->currentPosition > file->filesize) { if (file->currentPosition > file->filesize) {
if (!_FAT_file_extend_r (r, file)) { if (!_FAT_file_extend_r (r, file)) {
_FAT_unlock();
return -1; return -1;
} }
} }
@ -778,6 +805,8 @@ int _FAT_write_r (struct _reent *r,int fd, const char *ptr, int len) {
} }
} }
_FAT_unlock();
return len; return len;
} }
@ -791,8 +820,10 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
int clusCount; int clusCount;
int position; int position;
_FAT_lock();
if ((file == NULL) || (file->inUse == false)) { if ((file == NULL) || (file->inUse == false)) {
// invalid file // invalid file
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
@ -810,16 +841,19 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
position = file->filesize + pos; position = file->filesize + pos;
break; break;
default: default:
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
if ((pos > 0) && (position < 0)) { if ((pos > 0) && (position < 0)) {
r->_errno = EOVERFLOW; r->_errno = EOVERFLOW;
_FAT_unlock();
return -1; return -1;
} }
if (position < 0) { if (position < 0) {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; 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.sector = partition->sectorsPerCluster;
file->rwPosition.byte = 0; file->rwPosition.byte = 0;
} else { } else {
_FAT_unlock();
r->_errno = EINVAL; r->_errno = EINVAL;
return -1; return -1;
} }
@ -866,6 +901,7 @@ int _FAT_seek_r (struct _reent *r, int fd, int pos, int dir) {
// Save position // Save position
file->currentPosition = position; file->currentPosition = position;
_FAT_unlock();
return position; return position;
} }
@ -878,8 +914,10 @@ int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) {
DIR_ENTRY fileEntry; DIR_ENTRY fileEntry;
_FAT_lock();
if ((file == NULL) || (file->inUse == false)) { if ((file == NULL) || (file->inUse == false)) {
// invalid file // invalid file
_FAT_unlock();
r->_errno = EBADF; r->_errno = EBADF;
return -1; return -1;
} }
@ -891,6 +929,7 @@ int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) {
fileEntry.dataEnd = file->dirEntryEnd; fileEntry.dataEnd = file->dirEntryEnd;
if (!_FAT_directory_entryFromPosition (partition, &fileEntry)) { if (!_FAT_directory_entryFromPosition (partition, &fileEntry)) {
_FAT_unlock();
r->_errno = EIO; r->_errno = EIO;
return -1; 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_ino = (ino_t)(file->startCluster); // The file serial number is the start cluster
st->st_size = file->filesize; // File size st->st_size = file->filesize; // File size
_FAT_unlock();
return 0; return 0;
} }

View File

@ -52,6 +52,7 @@
#include "partition.h" #include "partition.h"
#include "fatfile.h" #include "fatfile.h"
#include "fatdir.h" #include "fatdir.h"
#include "lock.h"
#ifdef GBA #ifdef GBA
#define DEFAULT_CACHE_PAGES 2 #define DEFAULT_CACHE_PAGES 2
@ -127,6 +128,9 @@ bool fatInit (u32 cacheSize, bool setAsDefaultDevice) {
#endif #endif
chdir (filePath); chdir (filePath);
} }
_FAT_lock_init();
return true; return true;
} }