mirror of
https://github.com/devkitPro/wut.git
synced 2026-04-24 15:37:18 -05:00
wutdevoptab: Add time and mode information for stat and fstat (#218)
* wutdevoptab: Add time and mode information for stat and fstat * wutdevoptab: rename __wut_translate_mode to __wut_fs_translate_mode
This commit is contained in:
parent
535e6d575b
commit
f0da3d7236
|
|
@ -81,3 +81,5 @@ int __wut_fs_rmdir(struct _reent *r, const char *name);
|
|||
// devoptab_fs_utils.c
|
||||
char * __wut_fs_fixpath(struct _reent *r, const char *path);
|
||||
int __wut_fs_translate_error(FSStatus error);
|
||||
time_t __wut_fs_translate_time(FSTime timeValue);
|
||||
mode_t __wut_fs_translate_mode(FSStat fileStat);
|
||||
|
|
|
|||
|
|
@ -25,10 +25,14 @@ __wut_fs_fstat(struct _reent *r,
|
|||
}
|
||||
|
||||
memset(st, 0, sizeof(struct stat));
|
||||
st->st_size = fsStat.size;
|
||||
st->st_uid = fsStat.owner;
|
||||
st->st_gid = fsStat.group;
|
||||
st->st_size = fsStat.size;
|
||||
st->st_uid = fsStat.owner;
|
||||
st->st_gid = fsStat.group;
|
||||
st->st_nlink = 1;
|
||||
st->st_mode = fsStat.mode | S_IFREG;
|
||||
st->st_mode = __wut_fs_translate_mode(fsStat);
|
||||
st->st_atime = __wut_fs_translate_time(fsStat.modified);
|
||||
st->st_ctime = __wut_fs_translate_time(fsStat.created);
|
||||
st->st_mtime = __wut_fs_translate_time(fsStat.modified);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
int
|
||||
__wut_fs_stat(struct _reent *r,
|
||||
const char *path,
|
||||
struct stat *st)
|
||||
{
|
||||
int fd;
|
||||
struct stat *st) {
|
||||
FSStatus status;
|
||||
FSCmdBlock cmd;
|
||||
FSStat fsStat;
|
||||
|
||||
if (!path || !st) {
|
||||
r->_errno = EINVAL;
|
||||
|
|
@ -15,35 +14,34 @@ __wut_fs_stat(struct _reent *r,
|
|||
}
|
||||
|
||||
char *fixedPath = __wut_fs_fixpath(r, path);
|
||||
if (!fixedPath) {
|
||||
if (!fixedPath) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FSInitCmdBlock(&cmd);
|
||||
|
||||
// First try open as file
|
||||
status = FSOpenFile(__wut_devoptab_fs_client, &cmd, fixedPath, "r",
|
||||
(FSFileHandle*)&fd, FS_ERROR_FLAG_ALL);
|
||||
if (status >= 0) {
|
||||
__wut_fs_file_t tmpfd = { .fd = fd };
|
||||
status = __wut_fs_fstat(r, &tmpfd, st);
|
||||
FSCloseFile(__wut_devoptab_fs_client, &cmd, fd, FS_ERROR_FLAG_ALL);
|
||||
free(fixedPath);
|
||||
return status;
|
||||
}
|
||||
|
||||
// File failed, so lets try open as directory
|
||||
status = FSOpenDir(__wut_devoptab_fs_client, &cmd, fixedPath,
|
||||
(FSDirectoryHandle*)&fd, FS_ERROR_FLAG_ALL);
|
||||
free(fixedPath);
|
||||
status = FSGetStat(__wut_devoptab_fs_client, &cmd, fixedPath, &fsStat, FS_ERROR_FLAG_ALL);
|
||||
if (status < 0) {
|
||||
free(fixedPath);
|
||||
r->_errno = __wut_fs_translate_error(status);
|
||||
return -1;
|
||||
}
|
||||
free(fixedPath);
|
||||
|
||||
memset(st, 0, sizeof(struct stat));
|
||||
|
||||
st->st_nlink = 1;
|
||||
st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
FSCloseDir(__wut_devoptab_fs_client, &cmd, fd, FS_ERROR_FLAG_ALL);
|
||||
st->st_atime = __wut_fs_translate_time(fsStat.modified);
|
||||
st->st_ctime = __wut_fs_translate_time(fsStat.created);
|
||||
st->st_mtime = __wut_fs_translate_time(fsStat.modified);
|
||||
st->st_mode = __wut_fs_translate_mode(fsStat);
|
||||
|
||||
if (!(fsStat.flags & FS_STAT_DIRECTORY)) {
|
||||
st->st_size = fsStat.size;
|
||||
st->st_uid = fsStat.owner;
|
||||
st->st_gid = fsStat.group;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
char *
|
||||
__wut_fs_fixpath(struct _reent *r,
|
||||
const char *path)
|
||||
{
|
||||
const char *path) {
|
||||
char *p;
|
||||
char *fixedPath;
|
||||
|
||||
|
|
@ -14,7 +13,7 @@ __wut_fs_fixpath(struct _reent *r,
|
|||
|
||||
p = strchr(path, ':') + 1;
|
||||
if (!strchr(path, ':')) {
|
||||
p = (char*)path;
|
||||
p = (char *) path;
|
||||
}
|
||||
|
||||
if (strlen(p) > PATH_MAX) {
|
||||
|
|
@ -33,44 +32,77 @@ __wut_fs_fixpath(struct _reent *r,
|
|||
return fixedPath;
|
||||
}
|
||||
|
||||
int
|
||||
__wut_fs_translate_error(FSStatus error)
|
||||
{
|
||||
switch ((int)error) {
|
||||
case FS_STATUS_END:
|
||||
return ENOENT;
|
||||
case FS_STATUS_CANCELLED:
|
||||
return ECANCELED;
|
||||
case FS_STATUS_EXISTS:
|
||||
return EEXIST;
|
||||
case FS_STATUS_MEDIA_ERROR:
|
||||
return EIO;
|
||||
case FS_STATUS_NOT_FOUND:
|
||||
return ENOENT;
|
||||
case FS_STATUS_PERMISSION_ERROR:
|
||||
return EPERM;
|
||||
case FS_STATUS_STORAGE_FULL:
|
||||
return ENOSPC;
|
||||
case FS_STATUS_FILE_TOO_BIG:
|
||||
return EFBIG;
|
||||
case FS_STATUS_NOT_DIR:
|
||||
return ENOTDIR;
|
||||
case FS_STATUS_NOT_FILE:
|
||||
return EISDIR;
|
||||
case FS_STATUS_MAX:
|
||||
return ENFILE;
|
||||
case FS_STATUS_ACCESS_ERROR:
|
||||
return EACCES;
|
||||
case FS_STATUS_JOURNAL_FULL:
|
||||
return ENOSPC;
|
||||
case FS_STATUS_UNSUPPORTED_CMD:
|
||||
return ENOTSUP;
|
||||
case FS_STATUS_MEDIA_NOT_READY:
|
||||
return EOWNERDEAD;
|
||||
case FS_STATUS_ALREADY_OPEN:
|
||||
case FS_STATUS_CORRUPTED:
|
||||
case FS_STATUS_FATAL_ERROR:
|
||||
return EIO;
|
||||
mode_t __wut_fs_translate_mode(FSStat fileStat) {
|
||||
mode_t retMode = 0;
|
||||
|
||||
if ((fileStat.flags & FS_STAT_LINK) == FS_STAT_LINK) {
|
||||
retMode |= S_IFLNK;
|
||||
} else if ((fileStat.flags & FS_STAT_DIRECTORY) == FS_STAT_DIRECTORY) {
|
||||
retMode |= S_IFDIR;
|
||||
} else if ((fileStat.flags & FS_STAT_FILE) == FS_STAT_FILE) {
|
||||
retMode |= S_IFREG;
|
||||
}
|
||||
return (int)error;
|
||||
|
||||
mode_t ownerFlags = (fileStat.mode & (FS_MODE_READ_OWNER | FS_MODE_WRITE_OWNER | FS_MODE_EXEC_OWNER)) >> 2;
|
||||
mode_t groupFlags = (fileStat.mode & (FS_MODE_READ_GROUP | FS_MODE_WRITE_GROUP | FS_MODE_EXEC_GROUP)) >> 1;
|
||||
mode_t userFlags = (fileStat.mode & (FS_MODE_READ_OTHER | FS_MODE_WRITE_OTHER | FS_MODE_EXEC_OTHER));
|
||||
|
||||
return retMode | ownerFlags | groupFlags | userFlags;
|
||||
}
|
||||
|
||||
|
||||
time_t __wut_fs_translate_time(FSTime timeValue) {
|
||||
OSCalendarTime fileTime;
|
||||
FSTimeToCalendarTime(timeValue, &fileTime);
|
||||
struct tm posixTime = {0};
|
||||
posixTime.tm_year = fileTime.tm_year - 1900;
|
||||
posixTime.tm_mon = fileTime.tm_mon;
|
||||
posixTime.tm_mday = fileTime.tm_mday;
|
||||
posixTime.tm_hour = fileTime.tm_hour;
|
||||
posixTime.tm_min = fileTime.tm_min;
|
||||
posixTime.tm_sec = fileTime.tm_sec;
|
||||
posixTime.tm_yday = fileTime.tm_yday;
|
||||
posixTime.tm_wday = fileTime.tm_wday;
|
||||
return mktime(&posixTime);
|
||||
}
|
||||
|
||||
int
|
||||
__wut_fs_translate_error(FSStatus error) {
|
||||
switch ((int) error) {
|
||||
case FS_STATUS_END:
|
||||
return ENOENT;
|
||||
case FS_STATUS_CANCELLED:
|
||||
return ECANCELED;
|
||||
case FS_STATUS_EXISTS:
|
||||
return EEXIST;
|
||||
case FS_STATUS_MEDIA_ERROR:
|
||||
return EIO;
|
||||
case FS_STATUS_NOT_FOUND:
|
||||
return ENOENT;
|
||||
case FS_STATUS_PERMISSION_ERROR:
|
||||
return EPERM;
|
||||
case FS_STATUS_STORAGE_FULL:
|
||||
return ENOSPC;
|
||||
case FS_STATUS_FILE_TOO_BIG:
|
||||
return EFBIG;
|
||||
case FS_STATUS_NOT_DIR:
|
||||
return ENOTDIR;
|
||||
case FS_STATUS_NOT_FILE:
|
||||
return EISDIR;
|
||||
case FS_STATUS_MAX:
|
||||
return ENFILE;
|
||||
case FS_STATUS_ACCESS_ERROR:
|
||||
return EACCES;
|
||||
case FS_STATUS_JOURNAL_FULL:
|
||||
return ENOSPC;
|
||||
case FS_STATUS_UNSUPPORTED_CMD:
|
||||
return ENOTSUP;
|
||||
case FS_STATUS_MEDIA_NOT_READY:
|
||||
return EOWNERDEAD;
|
||||
case FS_STATUS_ALREADY_OPEN:
|
||||
case FS_STATUS_CORRUPTED:
|
||||
case FS_STATUS_FATAL_ERROR:
|
||||
return EIO;
|
||||
}
|
||||
return (int) error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user