Skip to content

posix: fd_mgmt: implement dup(), dup2(), fseeko(), and ftello() #74096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/services/portability/posix/aep/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The *Realtime Controller System Profile* (PSE52) includes all features from PSE5
:widths: 50, 10, 50

:ref:`POSIX_C_LANG_MATH <posix_option_group_c_lang_math>`, yes,
:ref:`POSIX_FD_MGMT <posix_option_group_fd_mgmt>`,, :kconfig:option:`CONFIG_POSIX_FD_MGMT`
:ref:`POSIX_FD_MGMT <posix_option_group_fd_mgmt>`, yes, :kconfig:option:`CONFIG_POSIX_FD_MGMT`
:ref:`POSIX_FILE_SYSTEM <posix_option_group_file_system>`,, :kconfig:option:`CONFIG_POSIX_FILE_SYSTEM`

.. csv-table:: PSE52 Option Requirements
Expand Down
28 changes: 15 additions & 13 deletions doc/services/portability/posix/option_groups/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -538,24 +538,26 @@ POSIX_TIMERS
POSIX_FD_MGMT
=============

This table lists service support status in Zephyr for `POSIX_FD_MGMT`:
.. note::
When using Newlib, Picolibc, or other C libraries conforming to the ISO C Standard, the
C89 components of the ``POSIX_FD_MGMT`` Option Group are considered supported.

.. csv-table:: POSIX_FD_MGMT
:header: API, Supported
:widths: 50,10

dup(),
dup2(),
fcntl(),
fgetpos(),
fseek(),
fseeko(),
fsetpos(),
ftell(),
ftello(),
ftruncate(),yes
lseek(),
rewind(),
dup(), yes
dup2(), yes
fcntl(), yes
fgetpos(), yes
fseek(), yes
fseeko(), yes
fsetpos(), yes
ftell(), yes
ftello(), yes
ftruncate(), yes
lseek(), yes
rewind(), yes

.. _posix_option_group_file_locking:

Expand Down
40 changes: 40 additions & 0 deletions lib/os/fdtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,46 @@ int zvfs_fileno(FILE *file)
return (struct fd_entry *)file - fdtable;
}

int zvfs_dup(int fd, int *newfd)
{
int ret;

if (_check_fd(fd) < 0) {
return -1;
}

(void)k_mutex_lock(&fdtable_lock, K_FOREVER);

if (newfd == NULL) {
/* dup() - just find lowest-numbered fd */
ret = _find_fd_entry();
} else {
/* dup2() - check if newfd is valid */
if (_check_fd(*newfd) < 0) {
ret = -1;
} else {
if (fdtable[fd].vtable->close) {
(void)fdtable[fd].vtable->close(fdtable[fd].obj);
}
ret = *newfd;
}
}

if (ret >= 0) {
/* Mark entry as used and initialize fields */
if (newfd == NULL) {
(void)z_fd_ref(ret);
}
fdtable[ret] = fdtable[fd];
k_mutex_init(&fdtable[ret].lock);
k_condvar_init(&fdtable[ret].cond);
}

k_mutex_unlock(&fdtable_lock);

return ret;
}

int zvfs_fstat(int fd, struct stat *buf)
{
if (_check_fd(fd) < 0) {
Expand Down
2 changes: 2 additions & 0 deletions lib/posix/options/Kconfig.fd_mgmt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
menuconfig POSIX_FD_MGMT
bool "POSIX file descriptor management [EXPERIMENTAL]"
select EXPERIMENTAL
select FDTABLE
select REQUIRES_FULL_LIBC
help
Select 'y' here and Zephyr will provide implementations for the POSIX_FD_MGMT Option Group.
This includes support for dup(), dup2(), fcntl(), fseeko(), ftello(), ftruncate(),
Expand Down
37 changes: 37 additions & 0 deletions lib/posix/options/fd_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,30 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#include <zephyr/posix/unistd.h>
#include <zephyr/posix/sys/select.h>
#include <zephyr/posix/sys/socket.h>
#include <zephyr/sys/fdtable.h>

/* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */
int zvfs_dup(int fd, int *newfd);
int zvfs_fcntl(int fd, int cmd, va_list arg);
int zvfs_fileno(FILE *file);
int zvfs_ftruncate(int fd, off_t length);
off_t zvfs_lseek(int fd, off_t offset, int whence);

int dup(int fd)
{
return zvfs_dup(fd, NULL);
}

int dup2(int oldfd, int newfd)
{
return zvfs_dup(oldfd, &newfd);
}

int fcntl(int fd, int cmd, ...)
{
int ret;
Expand All @@ -33,6 +46,30 @@ int fcntl(int fd, int cmd, ...)
FUNC_ALIAS(fcntl, _fcntl, int);
#endif /* CONFIG_POSIX_FD_MGMT_ALIAS_FCNTL */

int fseeko(FILE *file, off_t offset, int whence)
{
int fd;

fd = zvfs_fileno(file);
if (fd < 0) {
return -1;
}

return zvfs_lseek(fd, offset, whence);
}

off_t ftello(FILE *file)
{
int fd;

fd = zvfs_fileno(file);
if (fd < 0) {
return -1;
}

return zvfs_lseek(fd, 0, SEEK_CUR);
}

int ftruncate(int fd, off_t length)
{
return zvfs_ftruncate(fd, length);
Expand Down
Loading