static int sd_fat_unlink_r (struct _reent *r, const char *name) { sd_fat_private_t *dev = sd_fat_get_device_data(name); if(!dev) { r->_errno = ENODEV; return -1; } OSLockMutex(dev->pMutex); char *real_path = sd_fat_real_path(name, dev); if(!real_path) { r->_errno = ENOMEM; OSUnlockMutex(dev->pMutex); return -1; } int result = FSRemove(dev->pClient, dev->pCmd, real_path, -1); free(real_path); OSUnlockMutex(dev->pMutex); if(result < 0) { r->_errno = result; return -1; } return 0; }
static ssize_t sd_fat_write_r (struct _reent *r, int fd, const char *ptr, size_t len) { sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; if(!file->dev) { r->_errno = ENODEV; return 0; } if(!file->write) { r->_errno = EACCES; return 0; } OSLockMutex(file->dev->pMutex); size_t len_aligned = FS_ALIGN(len); if(len_aligned > 0x4000) len_aligned = 0x4000; unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); if(!tmpBuf) { r->_errno = ENOMEM; OSUnlockMutex(file->dev->pMutex); return 0; } size_t done = 0; while(done < len) { size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); memcpy(tmpBuf, ptr + done, write_size); int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); #if 0 FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); #endif if(result < 0) { r->_errno = result; break; } else if(result == 0) { if(write_size > 0) done = 0; break; } else { done += result; file->pos += result; } } free(tmpBuf); OSUnlockMutex(file->dev->pMutex); return done; }
static int sd_fat_mkdir_r (struct _reent *r, const char *path, int mode) { sd_fat_private_t *dev = sd_fat_get_device_data(path); if(!dev) { r->_errno = ENODEV; return -1; } OSLockMutex(dev->pMutex); char *real_path = sd_fat_real_path(path, dev); if(!real_path) { r->_errno = ENOMEM; OSUnlockMutex(dev->pMutex); return -1; } int result = FSMakeDir(dev->pClient, dev->pCmd, real_path, -1); free(real_path); OSUnlockMutex(dev->pMutex); if(result < 0) { r->_errno = result; return -1; } return 0; }
static ssize_t sd_fat_read_r (struct _reent *r, int fd, char *ptr, size_t len) { sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; if(!file->dev) { r->_errno = ENODEV; return 0; } if(!file->read) { r->_errno = EACCES; return 0; } OSLockMutex(file->dev->pMutex); size_t len_aligned = FS_ALIGN(len); if(len_aligned > 0x4000) len_aligned = 0x4000; unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); if(!tmpBuf) { r->_errno = ENOMEM; OSUnlockMutex(file->dev->pMutex); return 0; } size_t done = 0; while(done < len) { size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); if(result < 0) { r->_errno = result; done = 0; break; } else if(result == 0) { //! TODO: error on read_size > 0 break; } else { memcpy(ptr + done, tmpBuf, read_size); done += result; file->pos += result; } } free(tmpBuf); OSUnlockMutex(file->dev->pMutex); return done; }
static int sd_fat_stat_r (struct _reent *r, const char *path, struct stat *st) { sd_fat_private_t *dev = sd_fat_get_device_data(path); if(!dev) { r->_errno = ENODEV; return -1; } OSLockMutex(dev->pMutex); // Zero out the stat buffer memset(st, 0, sizeof(struct stat)); char *real_path = sd_fat_real_path(path, dev); if(!real_path) { r->_errno = ENOMEM; OSUnlockMutex(dev->pMutex); return -1; } FSStat__ stats; int result = FSGetStat(dev->pClient, dev->pCmd, real_path, (FSStat*)&stats, -1); free(real_path); if(result < 0) { r->_errno = result; OSUnlockMutex(dev->pMutex); return -1; } // mark root also as directory st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; st->st_nlink = 1; st->st_size = stats.size; st->st_blocks = (stats.size + 511) >> 9; // Fill in the generic entry stats st->st_dev = stats.ent_id; st->st_uid = stats.owner_id; st->st_gid = stats.group_id; st->st_ino = stats.ent_id; st->st_atime = stats.mtime; st->st_ctime = stats.ctime; st->st_mtime = stats.mtime; OSUnlockMutex(dev->pMutex); return 0; }
static int sd_fat_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; if(!dirIter->dev) { r->_errno = ENODEV; return -1; } OSLockMutex(dirIter->dev->pMutex); FSDirEntry * dir_entry = malloc(sizeof(FSDirEntry)); int result = FSReadDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, (FSDirectoryEntry*)dir_entry, -1); if(result < 0) { free(dir_entry); r->_errno = result; OSUnlockMutex(dirIter->dev->pMutex); return -1; } // Fetch the current entry strcpy(filename, dir_entry->name); if(st) { memset(st, 0, sizeof(struct stat)); st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; st->st_nlink = 1; st->st_size = dir_entry->stat.size; st->st_blocks = (dir_entry->stat.size + 511) >> 9; st->st_dev = dir_entry->stat.ent_id; st->st_uid = dir_entry->stat.owner_id; st->st_gid = dir_entry->stat.group_id; st->st_ino = dir_entry->stat.ent_id; st->st_atime = dir_entry->stat.mtime; st->st_ctime = dir_entry->stat.ctime; st->st_mtime = dir_entry->stat.mtime; } free(dir_entry); OSUnlockMutex(dirIter->dev->pMutex); return 0; }
static int sd_fat_dirreset_r (struct _reent *r, DIR_ITER *dirState) { sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; if(!dirIter->dev) { r->_errno = ENODEV; return -1; } OSLockMutex(dirIter->dev->pMutex); int result = FSRewindDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); OSUnlockMutex(dirIter->dev->pMutex); if(result < 0) { r->_errno = result; return -1; } return 0; }
static int sd_fat_fsync_r (struct _reent *r, int fd) { sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; if(!file->dev) { r->_errno = ENODEV; return -1; } OSLockMutex(file->dev->pMutex); int result = FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); OSUnlockMutex(file->dev->pMutex); if(result < 0) { r->_errno = result; return -1; } return 0; }
static DIR_ITER *sd_fat_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) { sd_fat_private_t *dev = sd_fat_get_device_data(path); if(!dev) { r->_errno = ENODEV; return NULL; } sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; OSLockMutex(dev->pMutex); char *real_path = sd_fat_real_path(path, dev); if(!real_path) { r->_errno = ENOMEM; OSUnlockMutex(dev->pMutex); return NULL; } int dirHandle; int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, (FSDirectoryHandle*)&dirHandle, -1); free(real_path); OSUnlockMutex(dev->pMutex); if(result < 0) { r->_errno = result; return NULL; } dirIter->dev = dev; dirIter->dirHandle = dirHandle; return dirState; }
static off_t sd_fat_seek_r (struct _reent *r, int fd, off_t pos, int dir) { sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; if(!file->dev) { r->_errno = ENODEV; return 0; } OSLockMutex(file->dev->pMutex); switch(dir) { case SEEK_SET: file->pos = pos; break; case SEEK_CUR: file->pos += pos; break; case SEEK_END: file->pos = file->len + pos; break; default: r->_errno = EINVAL; return -1; } int result = FSSetPosFile(file->dev->pClient, file->dev->pCmd, file->fd, file->pos, -1); OSUnlockMutex(file->dev->pMutex); if(result == 0) { return file->pos; } return result; }
static int sd_fat_fstat_r (struct _reent *r, int fd, struct stat *st) { sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; if(!file->dev) { r->_errno = ENODEV; return -1; } OSLockMutex(file->dev->pMutex); // Zero out the stat buffer memset(st, 0, sizeof(struct stat)); FSStat__ stats; int result = FSGetStatFile(file->dev->pClient, file->dev->pCmd, file->fd, (FSStat*)&stats, -1); if(result != 0) { r->_errno = result; OSUnlockMutex(file->dev->pMutex); return -1; } st->st_mode = S_IFREG; st->st_size = stats.size; st->st_blocks = (stats.size + 511) >> 9; st->st_nlink = 1; // Fill in the generic entry stats st->st_dev = stats.ent_id; st->st_uid = stats.owner_id; st->st_gid = stats.group_id; st->st_ino = stats.ent_id; st->st_atime = stats.mtime; st->st_ctime = stats.ctime; st->st_mtime = stats.mtime; OSUnlockMutex(file->dev->pMutex); return 0; }
void ghs_flock_file(uint32_t lock) { decaf_check(lock <= GHS_FOPEN_MAX); OSLockMutex(p_iob_mutexes[lock]); }
void ghs_mtx_lock(void *mtx) { auto pmutex = static_cast<be_ptr<OSMutex>*>(mtx); OSLockMutex(*pmutex); }
static int sd_fat_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) { sd_fat_private_t *dev = sd_fat_get_device_data(path); if(!dev) { r->_errno = ENODEV; return -1; } OSLockMutex(dev->pMutex); // Zero out the stat buffer memset(buf, 0, sizeof(struct statvfs)); char *real_path = sd_fat_real_path(path, dev); if(!real_path) { r->_errno = ENOMEM; OSUnlockMutex(dev->pMutex); return -1; } u64 size; int result = FSGetFreeSpaceSize(dev->pClient, dev->pCmd, real_path, &size, -1); free(real_path); if(result < 0) { r->_errno = result; OSUnlockMutex(dev->pMutex); return -1; } // File system block size buf->f_bsize = 512; // Fundamental file system block size buf->f_frsize = 512; // Total number of blocks on file system in units of f_frsize buf->f_blocks = size >> 9; // this is unknown // Free blocks available for all and for non-privileged processes buf->f_bfree = buf->f_bavail = size >> 9; // Number of inodes at this point in time buf->f_files = 0xffffffff; // Free inodes available for all and for non-privileged processes buf->f_ffree = 0xffffffff; // File system id buf->f_fsid = (int)dev; // Bit mask of f_flag values. buf->f_flag = 0; // Maximum length of filenames buf->f_namemax = 255; OSUnlockMutex(dev->pMutex); return 0; }
void OSFastMutex_Lock(OSFastMutex *mutex) { OSLockMutex(reinterpret_cast<OSMutex*>(mutex)); }
void OSFastMutex_Lock(FastMutexHandle handle) { OSLockMutex(handle); }
static int sd_fat_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { sd_fat_private_t *dev = sd_fat_get_device_data(path); if(!dev) { r->_errno = ENODEV; return -1; } sd_fat_file_state_t *file = (sd_fat_file_state_t *)fileStruct; file->dev = dev; // Determine which mode the file is opened for file->flags = flags; const char *mode_str; if ((flags & 0x03) == O_RDONLY) { file->read = true; file->write = false; file->append = false; mode_str = "r"; } else if ((flags & 0x03) == O_WRONLY) { file->read = false; file->write = true; file->append = (flags & O_APPEND); mode_str = file->append ? "a" : "w"; } else if ((flags & 0x03) == O_RDWR) { file->read = true; file->write = true; file->append = (flags & O_APPEND); mode_str = file->append ? "a+" : "r+"; } else { r->_errno = EACCES; return -1; } int fd = -1; OSLockMutex(dev->pMutex); char *real_path = sd_fat_real_path(path, dev); if(!path) { r->_errno = ENOMEM; OSUnlockMutex(dev->pMutex); return -1; } int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, (FSFileHandle*)&fd, -1); free(real_path); if(result == 0) { FSStat stats; result = FSGetStatFile(dev->pClient, dev->pCmd, fd, &stats, -1); if(result != 0) { FSCloseFile(dev->pClient, dev->pCmd, fd, -1); r->_errno = result; OSUnlockMutex(dev->pMutex); return -1; } file->fd = fd; file->pos = 0; file->len = stats.size; OSUnlockMutex(dev->pMutex); return (int)file; } r->_errno = result; OSUnlockMutex(dev->pMutex); return -1; }