summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-03-03 19:23:53 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-03-09 17:26:54 +0100
commit0161b93d50d6915116c4ca9d1cad42ef89a4ad9e (patch)
tree92519deb9ceecf46fa298e94c5ae6dc11672bf01 /cpukit/libfs/src
parentimfs: Simplify code generation (diff)
downloadrtems-0161b93d50d6915116c4ca9d1cad42ef89a4ad9e.tar.bz2
imfs: Replace devfs with an IMFS specialization
Add a simplified path evaluation function IMFS_eval_path_devfs() for a device only IMFS configuration. The code size can be further reduced by the application if it disables the support for legacy IO drivers via: #define CONFIGURE_IMFS_DISABLE_MKNOD #define CONFIGURE_IMFS_DISABLE_MKNOD_DEVICE Obsolete CONFIGURE_MAXIMUM_DEVICES. Remove BSP_MAXIMUM_DEVICES. Update #3894. Update #3898.
Diffstat (limited to 'cpukit/libfs/src')
-rw-r--r--cpukit/libfs/src/devfs/devclose.c29
-rw-r--r--cpukit/libfs/src/devfs/devfs_eval.c95
-rw-r--r--cpukit/libfs/src/devfs/devfs_init.c79
-rw-r--r--cpukit/libfs/src/devfs/devfs_mknod.c63
-rw-r--r--cpukit/libfs/src/devfs/devfs_show.c51
-rw-r--r--cpukit/libfs/src/devfs/devioctl.c31
-rw-r--r--cpukit/libfs/src/devfs/devopen.c39
-rw-r--r--cpukit/libfs/src/devfs/devread.c31
-rw-r--r--cpukit/libfs/src/devfs/devstat.c36
-rw-r--r--cpukit/libfs/src/devfs/devwrite.c31
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval_devfs.c163
11 files changed, 163 insertions, 485 deletions
diff --git a/cpukit/libfs/src/devfs/devclose.c b/cpukit/libfs/src/devfs/devclose.c
deleted file mode 100644
index e3ca969988..0000000000
--- a/cpukit/libfs/src/devfs/devclose.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file
- *
- * @brief Maps Close Operation to rtems_io_close
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-#include <rtems/deviceio.h>
-
-int devFS_close(
- rtems_libio_t *iop
-)
-{
- const devFS_node *np = iop->pathinfo.node_access;
-
- return rtems_deviceio_close( iop, np->major, np->minor );
-}
diff --git a/cpukit/libfs/src/devfs/devfs_eval.c b/cpukit/libfs/src/devfs/devfs_eval.c
deleted file mode 100644
index ba8e36fad0..0000000000
--- a/cpukit/libfs/src/devfs/devfs_eval.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file
- *
- * @brief Evaluate Patch
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <string.h>
-
-#include <rtems/devfs.h>
-
-static devFS_node *devFS_search_node(
- const devFS_data *data,
- const char *path,
- size_t pathlen,
- devFS_node **free_node_ptr
-)
-{
- size_t i = 0;
- size_t n = data->count;
- devFS_node *nodes = data->nodes;
- devFS_node *node = NULL;
- devFS_node *free_node = NULL;
-
- for (i = 0; (free_node == NULL || node == NULL) && i < n; ++i) {
- devFS_node *current = nodes + i;
-
- if (current->name != NULL) {
- if (
- current->namelen == pathlen
- && memcmp(current->name, path, pathlen) == 0
- ) {
- node = current;
- }
- } else {
- free_node = current;
- }
- }
-
- *free_node_ptr = free_node;
-
- return node;
-}
-
-void devFS_eval_path(
- rtems_filesystem_eval_path_context_t *ctx
-)
-{
- rtems_filesystem_location_info_t *currentloc =
- rtems_filesystem_eval_path_get_currentloc(ctx);
- devFS_node *free_node;
- devFS_node *node = devFS_search_node(
- devFS_get_data(currentloc),
- rtems_filesystem_eval_path_get_path(ctx),
- rtems_filesystem_eval_path_get_pathlen(ctx),
- &free_node
- );
- int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
-
- if (node != NULL) {
- if ((eval_flags & RTEMS_FS_EXCLUSIVE) == 0) {
- currentloc->node_access = node;
- rtems_filesystem_eval_path_clear_path(ctx);
- } else {
- rtems_filesystem_eval_path_error(ctx, EEXIST);
- }
- } else {
- if ((eval_flags & RTEMS_FS_MAKE) != 0) {
- if (free_node != NULL) {
- free_node->mode = S_IRWXU | S_IRWXG | S_IRWXO;
- currentloc->node_access = free_node;
- rtems_filesystem_eval_path_set_token(
- ctx,
- rtems_filesystem_eval_path_get_path(ctx),
- rtems_filesystem_eval_path_get_pathlen(ctx)
- );
- rtems_filesystem_eval_path_clear_path(ctx);
- } else {
- rtems_filesystem_eval_path_error(ctx, ENOSPC);
- }
- } else {
- rtems_filesystem_eval_path_error(ctx, ENOENT);
- }
- }
-}
diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c
deleted file mode 100644
index e8ad761f29..0000000000
--- a/cpukit/libfs/src/devfs/devfs_init.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file
- *
- * @brief Creates the Main Device Table
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-const rtems_filesystem_operations_table devFS_ops = {
- .lock_h = rtems_filesystem_default_lock,
- .unlock_h = rtems_filesystem_default_unlock,
- .eval_path_h = devFS_eval_path,
- .link_h = rtems_filesystem_default_link,
- .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
- .mknod_h = devFS_mknod,
- .rmnod_h = rtems_filesystem_default_rmnod,
- .fchmod_h = rtems_filesystem_default_fchmod,
- .chown_h = rtems_filesystem_default_chown,
- .clonenod_h = rtems_filesystem_default_clonenode,
- .freenod_h = rtems_filesystem_default_freenode,
- .mount_h = rtems_filesystem_default_mount,
- .unmount_h = rtems_filesystem_default_unmount,
- .fsunmount_me_h = rtems_filesystem_default_fsunmount,
- .utime_h = rtems_filesystem_default_utime,
- .symlink_h = rtems_filesystem_default_symlink,
- .readlink_h = rtems_filesystem_default_readlink,
- .rename_h = rtems_filesystem_default_rename,
- .statvfs_h = rtems_filesystem_default_statvfs
-};
-
-const rtems_filesystem_file_handlers_r devFS_file_handlers = {
- .open_h = devFS_open,
- .close_h = devFS_close,
- .read_h = devFS_read,
- .write_h = devFS_write,
- .ioctl_h = devFS_ioctl,
- .lseek_h = rtems_filesystem_default_lseek_file,
- .fstat_h = devFS_stat,
- .ftruncate_h = rtems_filesystem_default_ftruncate,
- .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
- .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .kqfilter_h = rtems_filesystem_default_kqfilter,
- .mmap_h = rtems_filesystem_default_mmap,
- .poll_h = rtems_filesystem_default_poll,
- .readv_h = rtems_filesystem_default_readv,
- .writev_h = rtems_filesystem_default_writev
-};
-
-int devFS_initialize(
- rtems_filesystem_mount_table_entry_t *mt_entry,
- const void *data
-)
-{
- int rv = 0;
-
- if (data != NULL) {
- mt_entry->ops = &devFS_ops;
- mt_entry->immutable_fs_info = data;
- mt_entry->mt_fs_root->location.handlers = &devFS_file_handlers;
- } else {
- errno = EINVAL;
- rv = -1;
- }
-
- return rv;
-}
-
diff --git a/cpukit/libfs/src/devfs/devfs_mknod.c b/cpukit/libfs/src/devfs/devfs_mknod.c
deleted file mode 100644
index 3b86d8c192..0000000000
--- a/cpukit/libfs/src/devfs/devfs_mknod.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file
- *
- * @brief Creates an item in the main device table.
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rtems/devfs.h>
-
-int devFS_mknod(
- const rtems_filesystem_location_info_t *parentloc,
- const char *name,
- size_t namelen,
- mode_t mode,
- dev_t dev
-)
-{
- int rv = 0;
-
- if (namelen != 3 || name [0] != 'd' || name [1] != 'e' || name [2] != 'v') {
- if (S_ISBLK(mode) || S_ISCHR(mode)) {
- char *dupname = malloc(namelen);
-
- if (dupname != NULL) {
- devFS_node *node = parentloc->node_access;
-
- node->name = dupname;
- node->namelen = namelen;
- node->major = rtems_filesystem_dev_major_t(dev);
- node->minor = rtems_filesystem_dev_minor_t(dev);
- node->mode = mode;
- memcpy(dupname, name, namelen);
- } else {
- errno = ENOMEM;
- rv = -1;
- }
- } else {
- errno = ENOTSUP;
- rv = -1;
- }
- } else {
- if (!S_ISDIR(mode)) {
- errno = ENOTSUP;
- rv = -1;
- }
- }
-
- return rv;
-}
diff --git a/cpukit/libfs/src/devfs/devfs_show.c b/cpukit/libfs/src/devfs/devfs_show.c
deleted file mode 100644
index 07e67c6f51..0000000000
--- a/cpukit/libfs/src/devfs/devfs_show.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file
- *
- * @brief Retrieves and Prints all the Device Registered in System
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-#include <rtems/bspIo.h>
-
-void devFS_Show(void)
-{
- rtems_filesystem_location_info_t *rootloc = &rtems_filesystem_root->location;
-
- if (rootloc->mt_entry->ops == &devFS_ops) {
- const devFS_data *data = devFS_get_data(rootloc);
- size_t i = 0;
- size_t n = data->count;
- devFS_node *nodes = data->nodes;
-
- for (i = 0; i < n; ++i) {
- devFS_node *current = nodes + i;
-
- if (current->name != NULL) {
- size_t j = 0;
- size_t m = current->namelen;
-
- printk("/");
- for (j = 0; j < m; ++j) {
- printk("%c", current->name [j]);
- }
- printk(
- " %lu %lu\n",
- (unsigned long) current->major,
- (unsigned long) current->minor
- );
- }
- }
- }
-}
diff --git a/cpukit/libfs/src/devfs/devioctl.c b/cpukit/libfs/src/devfs/devioctl.c
deleted file mode 100644
index 693d30e825..0000000000
--- a/cpukit/libfs/src/devfs/devioctl.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @file
- *
- * @brief Maps ioctl Operation to rtems_io_ioctl
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-#include <rtems/deviceio.h>
-
-int devFS_ioctl(
- rtems_libio_t *iop,
- ioctl_command_t command,
- void *buffer
-)
-{
- const devFS_node *np = iop->pathinfo.node_access;
-
- return rtems_deviceio_control( iop, command, buffer, np->major, np->minor );
-}
diff --git a/cpukit/libfs/src/devfs/devopen.c b/cpukit/libfs/src/devfs/devopen.c
deleted file mode 100644
index d6d5c8062d..0000000000
--- a/cpukit/libfs/src/devfs/devopen.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file
- *
- * @brief Maps Open Operation to rtems_io_open
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-#include <rtems/deviceio.h>
-
-int devFS_open(
- rtems_libio_t *iop,
- const char *pathname,
- int oflag,
- mode_t mode
-)
-{
- const devFS_node *np = iop->pathinfo.node_access;
-
- return rtems_deviceio_open(
- iop,
- pathname,
- oflag,
- mode,
- np->major,
- np->minor
- );
-}
diff --git a/cpukit/libfs/src/devfs/devread.c b/cpukit/libfs/src/devfs/devread.c
deleted file mode 100644
index 8ae3e84b65..0000000000
--- a/cpukit/libfs/src/devfs/devread.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @file
- *
- * @brief DevFS Read
- * @ingroup Read Operation to rtems_io_read
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-#include <rtems/deviceio.h>
-
-ssize_t devFS_read(
- rtems_libio_t *iop,
- void *buffer,
- size_t count
-)
-{
- const devFS_node *np = iop->pathinfo.node_access;
-
- return rtems_deviceio_read( iop, buffer, count, np->major, np->minor );
-}
diff --git a/cpukit/libfs/src/devfs/devstat.c b/cpukit/libfs/src/devfs/devstat.c
deleted file mode 100644
index c88f729924..0000000000
--- a/cpukit/libfs/src/devfs/devstat.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @file
- *
- * @brief Gets the Device File Information
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-int devFS_stat(
- const rtems_filesystem_location_info_t *loc,
- struct stat *buf
-)
-{
- int rv = 0;
- const devFS_node *the_dev = loc->node_access;
-
- if (the_dev != NULL) {
- buf->st_rdev = rtems_filesystem_make_dev_t( the_dev->major, the_dev->minor );
- buf->st_mode = the_dev->mode;
- } else {
- rv = rtems_filesystem_default_fstat(loc, buf);
- }
-
- return rv;
-}
diff --git a/cpukit/libfs/src/devfs/devwrite.c b/cpukit/libfs/src/devfs/devwrite.c
deleted file mode 100644
index 7fd8006776..0000000000
--- a/cpukit/libfs/src/devfs/devwrite.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @file
- *
- * @brief Writes Operation to rtems_io_write
- * @ingroup DevFsDeviceTable Define Device Table Type
- */
-
-/*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <rtems/devfs.h>
-
-#include <rtems/deviceio.h>
-
-ssize_t devFS_write(
- rtems_libio_t *iop,
- const void *buffer,
- size_t count
-)
-{
- const devFS_node *np = iop->pathinfo.node_access;
-
- return rtems_deviceio_write( iop, buffer, count, np->major, np->minor );
-}
diff --git a/cpukit/libfs/src/imfs/imfs_eval_devfs.c b/cpukit/libfs/src/imfs/imfs_eval_devfs.c
new file mode 100644
index 0000000000..d25e4ff8e2
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_eval_devfs.c
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ClassicIO
+ *
+ * @brief Implementation of IMFS_eval_path_devfs().
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/imfs.h>
+
+#include <string.h>
+
+typedef struct {
+ uint8_t len;
+ char name[3];
+} IMFS_devfs_dir;
+
+static const IMFS_devfs_dir IMFS_devfs_dirs[] = {
+ { .len = 1, .name = { '/' } },
+ { .len = 1, .name = { '.' } },
+ { .len = 2, .name = { '.', '.' } },
+ { .len = 3, .name = { 'd', 'e', 'v' } }
+};
+
+static IMFS_jnode_t *IMFS_devfs_is_dir(
+ rtems_filesystem_eval_path_context_t *ctx,
+ IMFS_directory_t *dir
+)
+{
+ const char *path;
+ size_t pathlen;
+ size_t i;
+
+ path = rtems_filesystem_eval_path_get_path( ctx );
+ pathlen = rtems_filesystem_eval_path_get_pathlen( ctx );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( IMFS_devfs_dirs ); ++i ) {
+ bool match;
+
+ match = IMFS_devfs_dirs[ i ].len == pathlen
+ && memcmp( IMFS_devfs_dirs[ i ].name, path, pathlen ) == 0;
+
+ if ( match ) {
+ int eval_flags;
+
+ eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
+ eval_flags &= ~RTEMS_FS_EXCLUSIVE;
+ rtems_filesystem_eval_path_set_flags( ctx, eval_flags );
+ rtems_filesystem_eval_path_clear_path( ctx );
+ return &dir->Node;
+ }
+ }
+
+ return NULL;
+}
+
+static IMFS_jnode_t *IMFS_devfs_search(
+ rtems_filesystem_eval_path_context_t *ctx,
+ IMFS_directory_t *dir
+)
+{
+ const char *path;
+ size_t pathlen;
+ rtems_chain_control *entries;
+ rtems_chain_node *current;
+ rtems_chain_node *tail;
+
+ path = rtems_filesystem_eval_path_get_path( ctx );
+ pathlen = rtems_filesystem_eval_path_get_pathlen( ctx );
+ entries = &dir->Entries;
+ current = rtems_chain_first( entries );
+ tail = rtems_chain_tail( entries );
+
+ while ( current != tail ) {
+ IMFS_jnode_t *entry;
+ bool match;
+
+ entry = (IMFS_jnode_t *) current;
+ match = entry->namelen == pathlen
+ && memcmp( entry->name, path, pathlen ) == 0;
+
+ if ( match ) {
+ return entry;
+ }
+
+ current = rtems_chain_next( current );
+ }
+
+ return NULL;
+}
+
+void IMFS_eval_path_devfs( rtems_filesystem_eval_path_context_t *ctx )
+{
+ rtems_filesystem_location_info_t *currentloc;
+ IMFS_directory_t *dir;
+ IMFS_jnode_t *entry;
+
+ currentloc = rtems_filesystem_eval_path_get_currentloc( ctx );
+ dir = currentloc->node_access;
+
+ entry = IMFS_devfs_is_dir( ctx, dir );
+
+ if ( entry != NULL ) {
+ return;
+ }
+
+ entry = IMFS_devfs_search( ctx, dir );
+
+ if ( entry != NULL ) {
+ int eval_flags;
+
+ eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
+
+ if ( ( eval_flags & RTEMS_FS_EXCLUSIVE ) == 0 ) {
+ --dir->Node.reference_count;
+ ++entry->reference_count;
+ currentloc->node_access = entry;
+ currentloc->node_access_2 = IMFS_generic_get_context_by_node( entry );
+ IMFS_Set_handlers( currentloc );
+ rtems_filesystem_eval_path_clear_path( ctx );
+ } else {
+ rtems_filesystem_eval_path_error( ctx, EEXIST );
+ }
+ } else {
+ rtems_filesystem_eval_path_set_token(
+ ctx,
+ rtems_filesystem_eval_path_get_path( ctx ),
+ rtems_filesystem_eval_path_get_pathlen( ctx )
+ );
+ rtems_filesystem_eval_path_clear_path( ctx );
+ }
+}