Skip to content
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

Posix: Add Support for posix fstat #22

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions lib/posix/options/Kconfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ menuconfig POSIX_FILE_SYSTEM

if POSIX_FILE_SYSTEM

config POSIX_FILE_SYSTEM_FSTAT
bool "POSIX fstat() API support"
default n
help
Select 'y' here to provide POSIX fstat() functionality.

config POSIX_FILE_SYSTEM_ALIAS_FSTAT
bool
depends on POSIX_FILE_SYSTEM_FSTAT
help
Select 'y' here and Zephyr will provide an alias for fstat() as _fstat().

Expand Down
23 changes: 23 additions & 0 deletions lib/posix/options/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <limits.h>
#include <zephyr/posix/unistd.h>
#include <zephyr/posix/dirent.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/sys/fdtable.h>
#include <zephyr/posix/sys/stat.h>
Expand All @@ -28,6 +29,9 @@ struct posix_fs_desc {
};
bool is_dir;
bool used;
#if defined(CONFIG_POSIX_FILE_SYSTEM_FSTAT)
char path[MAX_FILE_NAME];
#endif
};

static struct posix_fs_desc desc_array[CONFIG_POSIX_OPEN_MAX];
Expand Down Expand Up @@ -120,6 +124,11 @@ int zvfs_open(const char *name, int flags)

zvfs_finalize_fd(fd, ptr, &fs_fd_op_vtable);

#if defined(CONFIG_POSIX_FILE_SYSTEM_FSTAT)
memset(ptr->path, 0, MAX_FILE_NAME);
snprintf(ptr->path, MAX_FILE_NAME, "%s", name);
#endif

return fd;
}

Expand Down Expand Up @@ -157,6 +166,15 @@ static int fs_ioctl_vmeth(void *obj, unsigned int request, va_list args)
}
break;
}
#if defined(CONFIG_POSIX_FILE_SYSTEM_FSTAT)
case ZFD_IOCTL_STAT: {
struct stat *buf = NULL;

buf = va_arg(args, struct stat *);
rc = stat(ptr->path, buf);
break;
}
#endif
case ZFD_IOCTL_TRUNCATE: {
off_t length;

Expand Down Expand Up @@ -460,6 +478,11 @@ int mkdir(const char *path, mode_t mode)

int fstat(int fildes, struct stat *buf)
{
if (!IS_ENABLED(CONFIG_POSIX_FILE_SYSTEM_FSTAT)) {
errno = ENOTSUP;
return -1;
}

return zvfs_fstat(fildes, buf);
}
#ifdef CONFIG_POSIX_FILE_SYSTEM_ALIAS_FSTAT
Expand Down
4 changes: 4 additions & 0 deletions tests/posix/fs/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ CONFIG_POSIX_FILE_SYSTEM=y
CONFIG_ZTEST=y
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_EVENTFD=n
CONFIG_FS_FATFS_LFN=y
CONFIG_FS_FATFS_MAX_LFN=32
CONFIG_FILE_SYSTEM_MAX_FILE_NAME=32
CONFIG_POSIX_FILE_SYSTEM_FSTAT=y
81 changes: 81 additions & 0 deletions tests/posix/fs/src/test_fs_fstat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2024 Linumiz
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <errno.h>
#include <zephyr/posix/fcntl.h>
#include <zephyr/posix/unistd.h>
#include <zephyr/posix/sys/stat.h>
#include "test_fs.h"

#define FILL_SIZE 128
#define TEST_FILE_SIZE 80
#define APPEND_DATA "hello_world"

static void create_file(const char *filename, uint32_t size)
{
int fh;

fh = open(filename, O_CREAT | O_WRONLY);
zassert(fh >= 0, "Failed creating test file");

uint8_t filling[FILL_SIZE];

while (size > FILL_SIZE) {
zassert_equal(FILL_SIZE, write(fh, filling, FILL_SIZE));
size -= FILL_SIZE;
}

zassert_equal(size, write(fh, filling, size));

zassert_ok(close(fh));
}

static void before_fn(void *unused)
{
ARG_UNUSED(unused);

create_file(TEST_FILE, TEST_FILE_SIZE);
}

static void after_fn(void *unused)
{
ARG_UNUSED(unused);

zassert_ok(unlink(TEST_FILE));
}
ZTEST_SUITE(posix_fs_fstat_test, NULL, test_mount, before_fn, after_fn, test_unmount);

/**
* @brief Test fstat command on file
*
*/
ZTEST(posix_fs_fstat_test, test_fs_fstat_file)
{
int fd = -1;
struct stat buf = {0};

fd = open(TEST_FILE, O_APPEND | O_WRONLY);
zassert(fd >= 0, "Failed creating test file");

zassert_equal(0, fstat(fd, &buf));
zassert_equal(TEST_FILE_SIZE, buf.st_size);
zassert_equal(S_IFREG, buf.st_mode);
zassert_not_equal(-1, write(fd, APPEND_DATA, strlen(APPEND_DATA)));

/* In Zephyr fs_stat, File info are updated only after close */
zassert_ok(close(fd));
fd = open(TEST_FILE, O_RDWR);
zassert(fd >= 0, "Failed creating test file");

zassert_equal(0, fstat(fd, &buf));
zassert_equal(TEST_FILE_SIZE + strlen(APPEND_DATA), buf.st_size);
zassert_equal(S_IFREG, buf.st_mode);

zassert_equal(-1, fstat(-1, &buf));
zassert_equal(EBADF, errno);

zassert_ok(close(fd));
}
Loading