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:
parent
0bfd995bc9
commit
32e59f57fd
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue