@@ -308,34 +308,62 @@ int zvfs_alloc_fd(void *obj, const struct fd_op_vtable *vtable)
308
308
return fd ;
309
309
}
310
310
311
- static ssize_t zvfs_rw ( int fd , void * buf , size_t sz , bool is_write )
311
+ static bool supports_pread_pwrite ( uint32_t mode )
312
312
{
313
+ switch (mode & ZVFS_MODE_IFMT ) {
314
+ case ZVFS_MODE_IFSHM :
315
+ return true;
316
+ default :
317
+ return false;
318
+ }
319
+ }
320
+
321
+ static ssize_t zvfs_rw (int fd , void * buf , size_t sz , bool is_write , const size_t * from_offset )
322
+ {
323
+ bool prw ;
313
324
ssize_t res ;
325
+ const size_t * off ;
314
326
315
327
if (_check_fd (fd ) < 0 ) {
316
328
return -1 ;
317
329
}
318
330
319
331
(void )k_mutex_lock (& fdtable [fd ].lock , K_FOREVER );
320
332
333
+ prw = supports_pread_pwrite (fdtable [fd ].mode );
334
+ if (from_offset != NULL && !prw ) {
335
+ /*
336
+ * Seekable file types should support pread() / pwrite() and per-fd offset passing.
337
+ * Otherwise, it's a bug.
338
+ */
339
+ errno = ENOTSUP ;
340
+ res = -1 ;
341
+ goto unlock ;
342
+ }
343
+
344
+ /* If there is no specified from_offset, then use the current offset of the fd */
345
+ off = (from_offset == NULL ) ? & fdtable [fd ].offset : from_offset ;
346
+
321
347
if (is_write ) {
322
- if (fdtable [fd ].vtable -> write_offset == NULL ) {
348
+ if (fdtable [fd ].vtable -> write_offs == NULL ) {
323
349
res = -1 ;
324
350
errno = EIO ;
325
351
} else {
326
- res = fdtable [fd ].vtable -> write_offset (fdtable [fd ].obj , buf , sz ,
327
- fdtable [fd ].offset );
352
+ res = fdtable [fd ].vtable -> write_offs (fdtable [fd ].obj , buf , sz , * off );
328
353
}
329
354
} else {
330
- if (fdtable [fd ].vtable -> read == NULL ) {
355
+ if (fdtable [fd ].vtable -> read_offs == NULL ) {
331
356
res = -1 ;
332
357
errno = EIO ;
333
358
} else {
334
- res = fdtable [fd ].vtable -> read_offset (fdtable [fd ].obj , buf , sz ,
335
- fdtable [fd ].offset );
359
+ res = fdtable [fd ].vtable -> read_offs (fdtable [fd ].obj , buf , sz , * off );
336
360
}
337
361
}
338
- if (res > 0 ) {
362
+ if (res > 0 && prw && from_offset == NULL ) {
363
+ /*
364
+ * only update the fd offset when from_offset is not specified
365
+ * See pread() / pwrite()
366
+ */
339
367
fdtable [fd ].offset += res ;
340
368
}
341
369
@@ -345,14 +373,14 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write)
345
373
return res ;
346
374
}
347
375
348
- ssize_t zvfs_read (int fd , void * buf , size_t sz )
376
+ ssize_t zvfs_read (int fd , void * buf , size_t sz , const size_t * from_offset )
349
377
{
350
- return zvfs_rw (fd , buf , sz , false);
378
+ return zvfs_rw (fd , buf , sz , false, from_offset );
351
379
}
352
380
353
- ssize_t zvfs_write (int fd , const void * buf , size_t sz )
381
+ ssize_t zvfs_write (int fd , const void * buf , size_t sz , const size_t * from_offset )
354
382
{
355
- return zvfs_rw (fd , (void * )buf , sz , true);
383
+ return zvfs_rw (fd , (void * )buf , sz , true, from_offset );
356
384
}
357
385
358
386
int zvfs_close (int fd )
@@ -494,7 +522,7 @@ static ssize_t stdinout_read_vmeth(void *obj, void *buffer, size_t count)
494
522
static ssize_t stdinout_write_vmeth (void * obj , const void * buffer , size_t count )
495
523
{
496
524
#if defined(CONFIG_BOARD_NATIVE_POSIX )
497
- return zvfs_write (1 , buffer , count );
525
+ return zvfs_write (1 , buffer , count , NULL );
498
526
#elif defined(CONFIG_NEWLIB_LIBC ) || defined(CONFIG_ARCMWDT_LIBC )
499
527
return z_impl_zephyr_write_stdout (buffer , count );
500
528
#else
0 commit comments