Skip to content

Commit

Permalink
posix: fd_mgmt: implement dup(), dup2(), fseeko(), and ftello()
Browse files Browse the repository at this point in the history
Implement the remaining functions from the POSIX_FD_MGMT Option
Group that are part of POSIX, and add the
CONFIG_REQUIRES_FULL_LIBC dependency to CONFIG_POSIX_FD_MGMT, to
pull in the remaining C89 functions.

The POSIX_FD_MGMT Option Group is required for PSE52, PSE53, and
PSE54 Subprofiling Option Groups.

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
  • Loading branch information
cfriedt authored and nashif committed Jun 27, 2024
1 parent b10f1ca commit b18cad1
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
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

0 comments on commit b18cad1

Please sign in to comment.