Simplified lseek() implementation.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15283 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-12-29 21:02:00 +00:00
parent 0bfd995bc9
commit 32e59f57fd
6 changed files with 121 additions and 38 deletions

View File

@ -162,7 +162,6 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
msg_t ret;
vfs_file_stat_t stat;
off_t finaloff;
if ((whence != SEEK_SET) || (whence == SEEK_CUR) || (whence != SEEK_END)) {
return CH_RET_EINVAL;
@ -183,32 +182,9 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
return CH_RET_ESPIPE;
}
switch (whence) {
case SEEK_SET:
finaloff = offset;
break;
case SEEK_CUR:
{
off_t oldoff = vfsGetFilePosition((struct vfs_file_node *)sbp->io.vfs_nodes[fd]);
CH_RETURN_ON_ERROR(oldoff);
finaloff = oldoff + offset;
}
break;
case SEEK_END:
finaloff = stat.size + offset;
break;
}
if (finaloff < 0) {
return CH_RET_EOVERFLOW;
}
ret = vfsSetFilePosition((struct vfs_file_node *)sbp->io.vfs_nodes[fd],
finaloff);
CH_RETURN_ON_ERROR(ret);
return finaloff;
return vfsSetFilePosition((struct vfs_file_node *)sbp->io.vfs_nodes[fd],
offset,
whence);;
}
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,

View File

@ -79,7 +79,9 @@ static void node_file_release(void *instance);
static BaseSequentialStream *node_file_get_stream(void *instance);
static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n);
static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n);
static msg_t node_file_setpos(void *instance, vfs_offset_t offset);
static msg_t node_file_setpos(void *instance,
vfs_offset_t offset,
vfs_seekmode_t whence);
static vfs_offset_t node_file_getpos(void *instance);
static msg_t node_file_getstat(void *instance, vfs_file_stat_t *fsp);
@ -443,10 +445,89 @@ static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n) {
return (ssize_t)bw;
}
static msg_t node_file_setpos(void *instance, vfs_offset_t offset) {
vfs_fatfs_file_node_c *fffnp = (vfs_fatfs_file_node_c *)instance;
#if 0
off_t sb_posix_lseek(int fd, off_t offset, int whence) {
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
msg_t ret;
vfs_file_stat_t stat;
off_t finaloff;
return translate_error(f_lseek(&fffnp->file, (FSIZE_t)offset));
if ((whence != SEEK_SET) || (whence == SEEK_CUR) || (whence != SEEK_END)) {
return CH_RET_EINVAL;
}
if (!is_valid_descriptor(&sbp->io, fd)) {
return CH_RET_EBADF;
}
if (sbp->io.attributes[fd] != 0) {
return CH_RET_EISDIR;
}
ret = vfsGetFileStat((struct vfs_file_node *)sbp->io.vfs_nodes[fd], &stat);
CH_RETURN_ON_ERROR(ret);
if ((stat.attr & VFS_NODE_ATTR_ISSTREAM) != 0U) {
return CH_RET_ESPIPE;
}
switch (whence) {
case SEEK_SET:
finaloff = offset;
break;
case SEEK_CUR:
{
off_t oldoff = vfsGetFilePosition((struct vfs_file_node *)sbp->io.vfs_nodes[fd]);
CH_RETURN_ON_ERROR(oldoff);
finaloff = oldoff + offset;
}
break;
case SEEK_END:
finaloff = stat.size + offset;
break;
}
if (finaloff < 0) {
return CH_RET_EOVERFLOW;
}
ret = vfsSetFilePosition((struct vfs_file_node *)sbp->io.vfs_nodes[fd],
finaloff);
CH_RETURN_ON_ERROR(ret);
return finaloff;
}
#endif
static msg_t node_file_setpos(void *instance,
vfs_offset_t offset,
vfs_seekmode_t whence) {
vfs_fatfs_file_node_c *fffnp = (vfs_fatfs_file_node_c *)instance;
vfs_offset_t finaloff;
chDbgCheck((whence == SEEK_SET) ||
(whence == SEEK_CUR) ||
(whence == SEEK_END));
switch (whence) {
case VFS_SEEK_CUR:
finaloff = offset + (vfs_offset_t)fffnp->file.fptr;
break;
case VFS_SEEK_END:
finaloff = offset + (vfs_offset_t)fffnp->file.obj.objsize;
break;
case VFS_SEEK_SET:
default:
finaloff = offset;
break;
}
if (finaloff < 0) {
return CH_RET_EOVERFLOW;
}
return translate_error(f_lseek(&fffnp->file, (FSIZE_t)finaloff));
}
static vfs_offset_t node_file_getpos(void *instance) {

View File

@ -79,7 +79,9 @@ static void node_file_release(void *instance);
static BaseSequentialStream *node_file_get_stream(void *instance);
static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n);
static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n);
static msg_t node_file_setpos(void *instance, vfs_offset_t offset);
static msg_t node_file_setpos(void *instance,
vfs_offset_t offset,
vfs_seekmode_t whence);
static vfs_offset_t node_file_getpos(void *instance);
static msg_t node_file_getstat(void *instance, vfs_file_stat_t *fsp);
@ -305,10 +307,13 @@ static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n) {
return streamWrite(sfnp->stream, buf, n);
}
static msg_t node_file_setpos(void *instance, vfs_offset_t offset) {
static msg_t node_file_setpos(void *instance,
vfs_offset_t offset,
vfs_seekmode_t whence) {
(void)instance;
(void)offset;
(void)whence;
return CH_RET_ENOSYS;
}

View File

@ -143,7 +143,9 @@ extern "C" {
void vfsCloseFile(vfs_file_node_c *vfnp);
ssize_t vfsReadFile(vfs_file_node_c *vfnp, uint8_t *buf, size_t n);
ssize_t vfsWriteFile(vfs_file_node_c *vfnp, const uint8_t *buf, size_t n);
msg_t vfsSetFilePosition(vfs_file_node_c *vfnp, vfs_offset_t offset);
msg_t vfsSetFilePosition(vfs_file_node_c *vfnp,
vfs_offset_t offset,
vfs_seekmode_t whence);
vfs_offset_t vfsGetFilePosition(vfs_file_node_c *vfnp);
msg_t vfsGetFileStat(vfs_file_node_c *vfnp, vfs_file_stat_t *fsp);
BaseSequentialStream *vfsGetFileStream(vfs_file_node_c *vfnp);

View File

@ -44,6 +44,15 @@
#define VFS_NODE_ATTR_ISSTREAM 256U
/** @} */
/**
* @name Seek modes.
* @{
*/
#define VFS_SEEK_SET SEEK_SET
#define VFS_SEEK_CUR SEEK_CUR
#define VFS_SEEK_END SEEK_END
/** @} */
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
@ -62,7 +71,12 @@ typedef struct vfs_driver vfs_driver_c;
/**
* @brief Type of a file offset.
*/
typedef off_t vfs_offset_t;
typedef int32_t vfs_offset_t;
/**
* @brief Type of a seek mode.
*/
typedef int vfs_seekmode_t;
/**
* @brief Type of a node attributes.
@ -189,7 +203,9 @@ typedef struct vfs_file_node vfs_file_node_c;
BaseSequentialStream *(*file_get_stream)(void *instance); \
ssize_t (*file_read)(void *instance, uint8_t *buf, size_t n); \
ssize_t (*file_write)(void *instance, const uint8_t *buf, size_t n); \
msg_t (*file_setpos)(void *instance, vfs_offset_t offset); \
msg_t (*file_setpos)(void *instance, \
vfs_offset_t offset, \
vfs_seekmode_t whence); \
vfs_offset_t (*file_getpos)(void *instance); \
msg_t (*file_getstat)(void *instance, vfs_file_stat_t *fsp);

View File

@ -242,15 +242,18 @@ ssize_t vfsWriteFile(vfs_file_node_c *vfnp, const uint8_t *buf, size_t n) {
*
* @param[in] vfnp Pointer to the @p vfs_file_node_c object.
* @param[in] offset New absolute position.
* @param[in] whence Seek mode to be used.
* @return The operation result.
*
* @api
*/
msg_t vfsSetFilePosition(vfs_file_node_c *vfnp, vfs_offset_t offset) {
msg_t vfsSetFilePosition(vfs_file_node_c *vfnp,
vfs_offset_t offset,
vfs_seekmode_t whence) {
chDbgAssert(vfnp->references > 0U, "zero count");
return vfnp->vmt->file_setpos((void *)vfnp, offset);
return vfnp->vmt->file_setpos((void *)vfnp, offset, whence);
}
/**