mirror of
https://github.com/wiiu-env/libfat.git
synced 2024-11-22 18:09: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 "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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user