Skip to content

Commit b18cad1

Browse files
cfriedtnashif
authored andcommitted
posix: fd_mgmt: implement dup(), dup2(), fseeko(), and ftello()
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 <[email protected]>
1 parent b10f1ca commit b18cad1

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

lib/os/fdtable.c

+40
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,46 @@ int zvfs_fileno(FILE *file)
424424
return (struct fd_entry *)file - fdtable;
425425
}
426426

427+
int zvfs_dup(int fd, int *newfd)
428+
{
429+
int ret;
430+
431+
if (_check_fd(fd) < 0) {
432+
return -1;
433+
}
434+
435+
(void)k_mutex_lock(&fdtable_lock, K_FOREVER);
436+
437+
if (newfd == NULL) {
438+
/* dup() - just find lowest-numbered fd */
439+
ret = _find_fd_entry();
440+
} else {
441+
/* dup2() - check if newfd is valid */
442+
if (_check_fd(*newfd) < 0) {
443+
ret = -1;
444+
} else {
445+
if (fdtable[fd].vtable->close) {
446+
(void)fdtable[fd].vtable->close(fdtable[fd].obj);
447+
}
448+
ret = *newfd;
449+
}
450+
}
451+
452+
if (ret >= 0) {
453+
/* Mark entry as used and initialize fields */
454+
if (newfd == NULL) {
455+
(void)z_fd_ref(ret);
456+
}
457+
fdtable[ret] = fdtable[fd];
458+
k_mutex_init(&fdtable[ret].lock);
459+
k_condvar_init(&fdtable[ret].cond);
460+
}
461+
462+
k_mutex_unlock(&fdtable_lock);
463+
464+
return ret;
465+
}
466+
427467
int zvfs_fstat(int fd, struct stat *buf)
428468
{
429469
if (_check_fd(fd) < 0) {

lib/posix/options/Kconfig.fd_mgmt

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
menuconfig POSIX_FD_MGMT
66
bool "POSIX file descriptor management [EXPERIMENTAL]"
77
select EXPERIMENTAL
8+
select FDTABLE
9+
select REQUIRES_FULL_LIBC
810
help
911
Select 'y' here and Zephyr will provide implementations for the POSIX_FD_MGMT Option Group.
1012
This includes support for dup(), dup2(), fcntl(), fseeko(), ftello(), ftruncate(),

lib/posix/options/fd_mgmt.c

+37
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,30 @@
77
#include <stdarg.h>
88
#include <stddef.h>
99
#include <stdint.h>
10+
#include <stdio.h>
1011

1112
#include <zephyr/posix/unistd.h>
1213
#include <zephyr/posix/sys/select.h>
1314
#include <zephyr/posix/sys/socket.h>
1415
#include <zephyr/sys/fdtable.h>
1516

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

24+
int dup(int fd)
25+
{
26+
return zvfs_dup(fd, NULL);
27+
}
28+
29+
int dup2(int oldfd, int newfd)
30+
{
31+
return zvfs_dup(oldfd, &newfd);
32+
}
33+
2134
int fcntl(int fd, int cmd, ...)
2235
{
2336
int ret;
@@ -33,6 +46,30 @@ int fcntl(int fd, int cmd, ...)
3346
FUNC_ALIAS(fcntl, _fcntl, int);
3447
#endif /* CONFIG_POSIX_FD_MGMT_ALIAS_FCNTL */
3548

49+
int fseeko(FILE *file, off_t offset, int whence)
50+
{
51+
int fd;
52+
53+
fd = zvfs_fileno(file);
54+
if (fd < 0) {
55+
return -1;
56+
}
57+
58+
return zvfs_lseek(fd, offset, whence);
59+
}
60+
61+
off_t ftello(FILE *file)
62+
{
63+
int fd;
64+
65+
fd = zvfs_fileno(file);
66+
if (fd < 0) {
67+
return -1;
68+
}
69+
70+
return zvfs_lseek(fd, 0, SEEK_CUR);
71+
}
72+
3673
int ftruncate(int fd, off_t length)
3774
{
3875
return zvfs_ftruncate(fd, length);

0 commit comments

Comments
 (0)