summaryrefslogtreecommitdiff
path: root/ACE/ace/MQX_Filesystem.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/MQX_Filesystem.h')
-rw-r--r--ACE/ace/MQX_Filesystem.h260
1 files changed, 260 insertions, 0 deletions
diff --git a/ACE/ace/MQX_Filesystem.h b/ACE/ace/MQX_Filesystem.h
new file mode 100644
index 00000000000..2bc32cb24a4
--- /dev/null
+++ b/ACE/ace/MQX_Filesystem.h
@@ -0,0 +1,260 @@
+/**
+ * @file MQX_Filesystem.h
+ *
+ * @author Frederick Hornsey <hornseyf@objectcomputing.com>
+ */
+
+#ifndef MQX_FILESYSTEM_HEADER
+#define MQX_FILESYSTEM_HEADER
+
+#include "ace/config-all.h"
+
+#ifdef ACE_MQX
+
+#include <mqx.h>
+#include <fio.h>
+
+#if !defined (FOPEN_MAX)
+# define FOPEN_MAX 20
+#endif
+
+#if !defined (ACE_MQX_DLIB_FULL)
+# undef read
+# undef write
+#endif
+
+struct stat;
+typedef struct stat ACE_stat;
+
+#define ACE_MQX_ABS_PATH_SIZE (IOCFG_FS_MAX_DEVLEN + FS_FILENAME_SIZE - 1)
+
+/**
+ * Since MQX has an unusual filesystem API, this class is provided to try to
+ * normalize it by managing the current working directory on a global context
+ * instead of a device by device context provided by MQX. It also tries to make
+ * these functions act more like their UNIX counterparts to some extent.
+ *
+ * This class is also the interface between the DLib IO functions and MQX file
+ * IO. It does this by implementing the classic UNIX IO functions below.
+ *
+ * WARNING: This is already being done in the ACE_TMAIN macro, but
+ * complete_initialization() should be called before using DLib or ACE file IO
+ * functions, but after MQX has been initialized. Either way, standard streams
+ * will not work properly, or some other behavior depending on the what
+ * functions are called in what order.
+ */
+class MQX_Filesystem {
+public:
+ /// Get the singleton instance of the class
+ inline static MQX_Filesystem &inst() {
+ return instance_;
+ }
+
+ /**
+ * Initialize the Standard Streams and the Current Filesystem
+ *
+ * This must be done after MQX has been initialized. See warning in class
+ * documenting comment.
+ */
+ void complete_initialization ();
+
+ /**
+ * Attempt to reset the cwd state by asking MQX for the first valid filesystem
+ * and "cd-ing" into the root of it.
+ */
+ bool reset_state ();
+
+ /**
+ * @name Unix-like File Functions
+ *
+ * Classic UNIX-like Operations Implemented for for DLib
+ */
+ ///@{
+ /**
+ * Open a file and return the file descriptor.
+ *
+ * Returns the file descriptor if successful, -1 otherwise.
+ *
+ * Known Limitations:
+ * - Mode is being converted from DLib Unix-like mode to MQX cstdlib mode.
+ * This is not perfected yet and is limited by the common denominator of
+ * what is supported by both systems.
+ */
+ int open (const char *path, int mode);
+ int close (int fd);
+ size_t read (int fd, unsigned char *buffer, size_t size);
+ size_t write (int fd, const unsigned char *buffer, size_t size);
+ long lseek (int fd, long offset, int whence);
+ ///@}
+
+ /**
+ * @name Unix-like Filesystem Functions
+ */
+ ///@{
+ /**
+ * Put the current directory path in buf of size.
+ *
+ * Returns NULL if an error occurred, otherwise buf.
+ */
+ char *getcwd (char *buf, size_t size);
+
+ /**
+ * Create a directory at path.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ */
+ int mkdir (const char *path);
+
+ /**
+ * Change to the directory at path.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ */
+ int chdir (const char *path);
+
+ /**
+ * Remove the empty directory at path.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ */
+ int rmdir (const char *path);
+
+ /**
+ * Unlink the file at path.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ */
+ int unlink (const char *path);
+
+ /**
+ * Rename or move the file or rename the directory from newpath to oldpath.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ *
+ * As standard rename does, this sets errno to EXDEV if you try to move a
+ * file across filesystems. It also overwrites regular files that occupy the
+ * new path.
+ *
+ * Known Limitations:
+ * - Can only rename directories, will refuse to move them. This is MFS's
+ * IO_IOCTL_RENAME_FILE refusing to do this. This could be implemented by
+ * the function, but would involve either manually copying the file tree
+ * or refusing to move nonempty directories.
+ */
+ int rename (const char *oldpath, const char *newpath);
+
+ /**
+ * Get status of file given by path.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ *
+ * Known Limitations:
+ * - st_mtime is currently not implemented and is set to 0.
+ * - st_mode is limited to
+ * - S_IFDIR: file is a directory
+ * - S_IFREG: file is a regular file
+ */
+ int stat (const char * path, ACE_stat *statbuf);
+
+ /**
+ * Get status of file given by file descriptor.
+ *
+ * Returns -1 if an error occurred, otherwise 0.
+ *
+ * Known Limitations:
+ * - st_mtime is currently not implemented and returns 0
+ * - In MFS there seems to be no direct way to get st_msize from a MQX file
+ * alone. The only way to get a file size using the documented API seems
+ * to be IO_IOCTL_FIND_FIRST_FILE, which requires the path. For now this
+ * will be set to 0.
+ * - st_mode is limited to
+ * - S_IFDIR: file is a directory
+ * - S_IFREG: file is a regular file
+ * - S_IFCHR: file is a special character device file, (e.g. ACE_STDOUT)
+ */
+ int fstat (int fd, ACE_stat *statbuf);
+ ///@}
+
+private:
+ /// The singleton instance of the class
+ static MQX_Filesystem instance_;
+
+ MQX_Filesystem();
+
+ /**
+ * @name Current Filesystem for resolving relative paths.
+ */
+ ///@{
+ MQX_FILE_PTR current_fs_;
+ char current_fs_name_[IOCFG_FS_MAX_DEVLEN];
+ unsigned current_fs_name_len_;
+ ///@}
+
+ /**
+ * @name Manage open files using file descriptors.
+ */
+ ///@{
+ struct File {
+ /// DLib File Descriptor. Invalid if -1.
+ int fd;
+ /// MQX File
+ MQX_FILE_PTR mqx_file;
+ /// Mark this as special character device file (Standard Streams)
+ bool chardev_file;
+ };
+ File files_[FOPEN_MAX];
+
+ /**
+ * Last file descriptor created.
+ */
+ int last_fd_;
+
+ /**
+ * Max VALUE for File Descriptors.
+ *
+ * NOTE: Max open file count is FOPEN_MAX, defined by DLib. This creates a
+ * limit on the number of unique file descriptor values.
+ */
+ int max_fd_;
+
+ /**
+ * Get a File struct for the file descriptor.
+ *
+ * Returns NULL and sets EBADF if no such file exists
+ */
+ File *get_file (int fd);
+
+ /**
+ * Get a File struct pointer to use for a new file.
+ *
+ * Returns NULL and sets ENFILE if exceeded max number of open files.
+ */
+ File *get_new_file ();
+ ///@}
+
+ /**
+ * Check to see if the current filesystem is valid, if not reset it.
+ *
+ * Returns true if reseting failed, otherwise false. Failure would probably
+ * mean no filesystems are mounted.
+ */
+ bool check_state ();
+
+ /**
+ * Set the supplied pointer as the filesystem of the current working
+ * directory.
+ */
+ void update_fs (MQX_FILE_PTR fs);
+
+ /**
+ * Resolve the filesystem of the supplied path and return it.
+ *
+ * This will be the filesystem of the current working directory if the path
+ * is relative. Sets the fs_name_len to the length of the device name in the
+ * path. This would be 0 if the path is relative.
+ */
+ MQX_FILE_PTR resolve_fs (const char *path, int *fs_name_len);
+};
+
+#endif // ACE_MQX
+#endif // MQX_FILESYSTEM_HEADER