/*! Truncate an open file * * @param[in,out] r newlib reentrancy struct * @param[in] fd Pointer to sdmc_file_t * @param[in] len Length to truncate file to * * @returns 0 for success * @returns -1 for error */ static int sdmc_ftruncate(struct _reent *r, int fd, off_t len) { Result rc; /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fd; /* make sure length is non-negative */ if(len < 0) { r->_errno = EINVAL; return -1; } /* set the new file size */ rc = FSFILE_SetSize(file->fd, len); if(rc == 0) return 0; r->_errno = rc; 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 = 0; FS_Path fs_path; fs_path = sdmc_utf16path(r, path); if(fs_path.data == NULL) 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; /* Test O_EXCL. */ if((flags & O_CREAT) && (flags & O_EXCL)) { rc = FSUSER_CreateFile(sdmcArchive, fs_path, attributes, 0); if(R_FAILED(rc)) { r->_errno = sdmc_translate_error(rc); return -1; } } /* set attributes */ /*if(!(mode & S_IWUSR)) attributes |= FS_ATTRIBUTE_READONLY;*/ /* open the file */ rc = FSUSER_OpenFile(&fd, sdmcArchive, fs_path, sdmc_flags, attributes); if(R_SUCCEEDED(rc)) { if((flags & O_ACCMODE) != O_RDONLY && (flags & O_TRUNC)) { rc = FSFILE_SetSize(fd, 0); if(R_FAILED(rc)) { FSFILE_Close(fd); r->_errno = sdmc_translate_error(rc); return -1; } } file->fd = fd; file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC)); file->offset = 0; return 0; } r->_errno = sdmc_translate_error(rc); return -1; }
static void _vf3dTruncate(struct VFile* vf, size_t size) { struct VFile3DS* vf3d = (struct VFile3DS*) vf; FSFILE_SetSize(vf3d->handle, size); }