static const FS_Path sdmc_utf16path(struct _reent *r, const char *path) { ssize_t units; FS_Path fspath; fspath.data = NULL; if(sdmc_fixpath(r, path) == NULL) return fspath; units = utf8_to_utf16(__utf16path, (const uint8_t*)__fixedpath, PATH_MAX); if(units < 0) { r->_errno = EILSEQ; return fspath; } if(units >= PATH_MAX) { r->_errno = ENAMETOOLONG; return fspath; } __utf16path[units] = 0; fspath.type = PATH_UTF16; fspath.size = (units+1)*sizeof(uint16_t); fspath.data = (const u8*)__utf16path; return fspath; }
/*! Open a directory * * @param[in,out] r newlib reentrancy struct * @param[in] dirState Pointer to open directory state * @param[in] path Path of directory to open * * @returns dirState for success * @returns NULL for error */ static DIR_ITER* sdmc_diropen(struct _reent *r, DIR_ITER *dirState, const char *path) { Handle fd; Result rc; const char *pathptr = NULL; pathptr = sdmc_fixpath(path); if(pathptr==NULL) { r->_errno=EINVAL; return NULL; } /* get pointer to our data */ sdmc_dir_t *dir = (sdmc_dir_t*)(dirState->dirStruct); /* open the directory */ rc = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr)); if(rc == 0) { dir->fd = fd; memset(&dir->entry_data, 0, sizeof(dir->entry_data)); return dirState; } r->_errno = rc; return NULL; }
/*! Change current working directory * * @param[in,out] r newlib reentrancy struct * @param[in] name Path to new working directory * * @returns 0 for success * @returns -1 for error */ static int sdmc_chdir(struct _reent *r, const char *name) { Handle fd; Result rc; const char *pathptr = NULL; pathptr = sdmc_fixpath(name); if(pathptr==NULL) { r->_errno=EINVAL; return -1; } rc = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr)); if(rc == 0) { FSDIR_Close(fd); strncpy(__cwd,pathptr,PATH_MAX); } else { r->_errno=EINVAL; return -1; } return 0; }
/*! Create a directory * * @param[in,out] r newlib reentrancy struct * @param[in] path Path of directory to create * @param[in] mode Permissions of created directory * * @returns 0 for success * @returns -1 for error */ static int sdmc_mkdir(struct _reent *r, const char *path, int mode) { Result rc; const char *pathptr = NULL; pathptr = sdmc_fixpath(path); if(pathptr==NULL) { r->_errno=EINVAL; return -1; } /* TODO: Use mode to set directory attributes. */ rc = FSUSER_CreateDirectory(NULL, sdmcArchive, FS_makePath(PATH_CHAR, pathptr)); if(rc == 0) return 0; r->_errno = ENOSYS; return -1; }
/*! Open a file * * @param[in,out] r newlib reentrancy struct * @param[out] fileStruct Pointer to file struct to fill in * @param[in] path Path to open * @param[in] flags Open flags from open(2) * @param[in] mode Permissions to set on create * * @returns 0 for success * @returns -1 for error */ static int sdmc_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { Handle fd; Result rc; u32 sdmc_flags = 0; u32 attributes = FS_ATTRIBUTE_NONE; const char *pathptr = NULL; pathptr = sdmc_fixpath(path); if(pathptr==NULL) { r->_errno=EINVAL; return -1; } /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fileStruct; /* check access mode */ switch(flags & O_ACCMODE) { /* read-only: do not allow O_APPEND */ case O_RDONLY: sdmc_flags |= FS_OPEN_READ; if(flags & O_APPEND) { r->_errno = EINVAL; return -1; } break; /* write-only */ case O_WRONLY: sdmc_flags |= FS_OPEN_WRITE; break; /* read and write */ case O_RDWR: sdmc_flags |= (FS_OPEN_READ | FS_OPEN_WRITE); break; /* an invalid option was supplied */ default: r->_errno = EINVAL; return -1; } /* create file */ if(flags & O_CREAT) sdmc_flags |= FS_OPEN_CREATE; /* TODO: Test O_EXCL. */ /* set attributes */ /*if(!(mode & S_IWUSR)) attributes |= FS_ATTRIBUTE_READONLY;*/ /* open the file */ rc = FSUSER_OpenFile(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr), sdmc_flags, attributes); if(rc == 0) { file->fd = fd; file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC)); file->offset = 0; return 0; } r->_errno = rc; return -1; }