2 * @file MQX_Filesystem.h
4 * @author Frederick Hornsey <hornseyf@objectcomputing.com>
7 #ifndef MQX_FILESYSTEM_HEADER
8 #define MQX_FILESYSTEM_HEADER
10 #include "ace/config-all.h"
17 #if !defined (FOPEN_MAX)
21 #if !defined (ACE_MQX_DLIB_FULL)
27 typedef struct stat ACE_stat
;
29 #define ACE_MQX_ABS_PATH_SIZE (IOCFG_FS_MAX_DEVLEN + FS_FILENAME_SIZE - 1)
32 * Since MQX has an unusual filesystem API, this class is provided to try to
33 * normalize it by managing the current working directory on a global context
34 * instead of a device by device context provided by MQX. It also tries to make
35 * these functions act more like their UNIX counterparts to some extent.
37 * This class is also the interface between the DLib IO functions and MQX file
38 * IO. It does this by implementing the classic UNIX IO functions below.
40 * WARNING: This is already being done in the ACE_TMAIN macro, but
41 * complete_initialization() should be called before using DLib or ACE file IO
42 * functions, but after MQX has been initialized. Either way, standard streams
43 * will not work properly, or some other behavior depending on the what
44 * functions are called in what order.
46 class MQX_Filesystem
{
48 /// Get the singleton instance of the class
49 inline static MQX_Filesystem
&inst() {
54 * Initialize the Standard Streams and the Current Filesystem
56 * This must be done after MQX has been initialized. See warning in class
57 * documenting comment.
59 void complete_initialization ();
62 * Attempt to reset the cwd state by asking MQX for the first valid filesystem
63 * and "cd-ing" into the root of it.
68 * @name Unix-like File Functions
70 * Classic UNIX-like Operations Implemented for for DLib
74 * Open a file and return the file descriptor.
76 * Returns the file descriptor if successful, -1 otherwise.
79 * - Mode is being converted from DLib Unix-like mode to MQX cstdlib mode.
80 * This is not perfected yet and is limited by the common denominator of
81 * what is supported by both systems.
83 int open (const char *path
, int mode
);
85 size_t read (int fd
, unsigned char *buffer
, size_t size
);
86 size_t write (int fd
, const unsigned char *buffer
, size_t size
);
87 long lseek (int fd
, long offset
, int whence
);
91 * @name Unix-like Filesystem Functions
95 * Put the current directory path in buf of size.
97 * Returns NULL if an error occurred, otherwise buf.
99 char *getcwd (char *buf
, size_t size
);
102 * Create a directory at path.
104 * Returns -1 if an error occurred, otherwise 0.
106 int mkdir (const char *path
);
109 * Change to the directory at path.
111 * Returns -1 if an error occurred, otherwise 0.
113 int chdir (const char *path
);
116 * Remove the empty directory at path.
118 * Returns -1 if an error occurred, otherwise 0.
120 int rmdir (const char *path
);
123 * Unlink the file at path.
125 * Returns -1 if an error occurred, otherwise 0.
127 int unlink (const char *path
);
130 * Rename or move the file or rename the directory from newpath to oldpath.
132 * Returns -1 if an error occurred, otherwise 0.
134 * As standard rename does, this sets errno to EXDEV if you try to move a
135 * file across filesystems. It also overwrites regular files that occupy the
139 * - Can only rename directories, will refuse to move them. This is MFS's
140 * IO_IOCTL_RENAME_FILE refusing to do this. This could be implemented by
141 * the function, but would involve either manually copying the file tree
142 * or refusing to move nonempty directories.
144 int rename (const char *oldpath
, const char *newpath
);
147 * Get status of file given by path.
149 * Returns -1 if an error occurred, otherwise 0.
152 * - st_mtime is currently not implemented and is set to 0.
153 * - st_mode is limited to
154 * - S_IFDIR: file is a directory
155 * - S_IFREG: file is a regular file
157 int stat (const char * path
, ACE_stat
*statbuf
);
160 * Get status of file given by file descriptor.
162 * Returns -1 if an error occurred, otherwise 0.
165 * - st_mtime is currently not implemented and returns 0
166 * - In MFS there seems to be no direct way to get st_msize from a MQX file
167 * alone. The only way to get a file size using the documented API seems
168 * to be IO_IOCTL_FIND_FIRST_FILE, which requires the path. For now this
170 * - st_mode is limited to
171 * - S_IFDIR: file is a directory
172 * - S_IFREG: file is a regular file
173 * - S_IFCHR: file is a special character device file, (e.g. ACE_STDOUT)
175 int fstat (int fd
, ACE_stat
*statbuf
);
179 /// The singleton instance of the class
180 static MQX_Filesystem instance_
;
185 * @name Current Filesystem for resolving relative paths.
188 MQX_FILE_PTR current_fs_
;
189 char current_fs_name_
[IOCFG_FS_MAX_DEVLEN
];
190 unsigned current_fs_name_len_
;
194 * @name Manage open files using file descriptors.
198 /// DLib File Descriptor. Invalid if -1.
201 MQX_FILE_PTR mqx_file
;
202 /// Mark this as special character device file (Standard Streams)
205 File files_
[FOPEN_MAX
];
208 * Last file descriptor created.
213 * Max VALUE for File Descriptors.
215 * NOTE: Max open file count is FOPEN_MAX, defined by DLib. This creates a
216 * limit on the number of unique file descriptor values.
221 * Get a File struct for the file descriptor.
223 * Returns NULL and sets EBADF if no such file exists
225 File
*get_file (int fd
);
228 * Get a File struct pointer to use for a new file.
230 * Returns NULL and sets ENFILE if exceeded max number of open files.
232 File
*get_new_file ();
236 * Check to see if the current filesystem is valid, if not reset it.
238 * Returns true if reseting failed, otherwise false. Failure would probably
239 * mean no filesystems are mounted.
244 * Set the supplied pointer as the filesystem of the current working
247 void update_fs (MQX_FILE_PTR fs
);
250 * Resolve the filesystem of the supplied path and return it.
252 * This will be the filesystem of the current working directory if the path
253 * is relative. Sets the fs_name_len to the length of the device name in the
254 * path. This would be 0 if the path is relative.
256 MQX_FILE_PTR
resolve_fs (const char *path
, int *fs_name_len
);
260 #endif // MQX_FILESYSTEM_HEADER