summaryrefslogtreecommitdiffstats
path: root/cpukit/libdl/rtl-find-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libdl/rtl-find-file.c')
-rw-r--r--cpukit/libdl/rtl-find-file.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/cpukit/libdl/rtl-find-file.c b/cpukit/libdl/rtl-find-file.c
new file mode 100644
index 0000000000..589be40a10
--- /dev/null
+++ b/cpukit/libdl/rtl-find-file.c
@@ -0,0 +1,110 @@
+/*
+ * COPYRIGHT (c) 2012-2013 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-find-file.h"
+#include "rtl-error.h"
+#include "rtl-string.h"
+#include "rtl-trace.h"
+
+#if WAF_BUILD
+#define rtems_filesystem_is_delimiter rtems_filesystem_is_separator
+#endif
+
+bool
+rtems_rtl_find_file (const char* name,
+ const char* paths,
+ const char** file_name,
+ size_t* size)
+{
+ struct stat sb;
+
+ *file_name = NULL;
+ *size = 0;
+
+ if (rtems_filesystem_is_delimiter (name[0]) || (name[0] == '.'))
+ {
+ if (stat (name, &sb) == 0)
+ *file_name = rtems_rtl_strdup (name);
+ }
+ else if (paths)
+ {
+ const char* start;
+ const char* end;
+ int len;
+ char* fname;
+
+ start = paths;
+ end = start + strlen (paths);
+ len = strlen (name);
+
+ while (!*file_name && (start != end))
+ {
+ const char* delimiter = strchr (start, ':');
+
+ if (delimiter == NULL)
+ delimiter = end;
+
+ /*
+ * Allocate the path fragment, separator, name, terminating nul. Form the
+ * path then see if the stat call works.
+ */
+
+ fname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+ (delimiter - start) + 1 + len + 1, true);
+ if (!fname)
+ {
+ rtems_rtl_set_error (ENOMEM, "no memory searching for file");
+ return false;
+ }
+
+ memcpy (fname, start, delimiter - start);
+ fname[delimiter - start] = '/';
+ memcpy (fname + (delimiter - start) + 1, name, len);
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+ printf ("rtl: find-file: path: %s\n", fname);
+
+ if (stat (fname, &sb) < 0)
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname);
+ else
+ *file_name = fname;
+
+ start = delimiter;
+ if (start != end)
+ ++start;
+ }
+ }
+
+ if (!*file_name)
+ return false;
+
+ *size = sb.st_size;
+
+ return true;
+}