KallistiOS  2.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
fs.h
Go to the documentation of this file.
1 /* KallistiOS 2.0.0
2 
3  kos/fs.h
4  Copyright (C) 2000, 2001, 2002, 2003 Dan Potter
5  Copyright (C) 2012, 2013 Lawrence Sebald
6 
7 */
8 
9 #ifndef __KOS_FS_H
10 #define __KOS_FS_H
11 
12 #include <sys/cdefs.h>
13 __BEGIN_DECLS
14 
15 #include <sys/types.h>
16 #include <kos/limits.h>
17 #include <time.h>
18 #include <sys/queue.h>
19 #include <stdarg.h>
20 
21 #include <kos/nmmgr.h>
22 
23 /** \file kos/fs.h
24  \brief Virtual filesystem support.
25 
26  This file contains the interface to the virtual filesystem (VFS) of KOS. The
27  functions defined in this file make up the base of the filesystem operations
28  that can be performed by programs. The functions in here are abstracted by
29  various other layers in libc, and shouldn't be necessarily used (for
30  portability reasons). However, if you want only to interact with KOS in your
31  programs, feel free to use them to your heart's content!
32 
33  \author Dan Potter
34  \author Lawrence Sebald
35 */
36 
37 /** \brief Directory entry.
38 
39  All VFS handlers must conform to this interface in their directory entries.
40 
41  \headerfile kos/fs.h
42 */
43 typedef struct kos_dirent {
44  int size; /**< \brief Size of the file in bytes. */
45  char name[MAX_FN_LEN]; /**< \brief Name of the file. */
46  time_t time; /**< \brief Last access/mod/change time (depends on VFS) */
47  uint32 attr; /**< \brief Attributes of the file. */
48 } dirent_t;
49 
50 /* Forward declaration */
51 struct vfs_handler;
52 
53 /** \brief File status information.
54 
55  This structure, while different from the standard POSIX stat structure,
56  provides much of the same information. We limit it to only what is relevant
57  for KOS.
58 
59  \headerfile kos/fs.h.
60 */
61 typedef struct {
62  struct vfs_handler *dev; /**< \brief The VFS handler for this file/dir */
63  uint32 unique; /**< \brief A unique identifier on the VFS for this file/dir */
64  uint32 type; /**< \brief File/Dir type */
65  uint32 attr; /**< \brief Attributes */
66  off_t size; /**< \brief Total file size, if applicable */
67  time_t time; /**< \brief Last access/mod/change time (depends on VFS) */
68 } stat_t;
69 
70 /* stat_t.unique */
71 /**< \brief stat_t.unique: Constant to use denoting the file has no unique ID */
72 #define STAT_UNIQUE_NONE 0
73 
74 /* stat_t.type */
75 /** \brief stat_t.type: Unknown / undefined / not relevant */
76 #define STAT_TYPE_NONE 0
77 
78 /** \brief stat_t.type: Standard file */
79 #define STAT_TYPE_FILE 1
80 
81 /** \brief stat_t.type: Standard directory */
82 #define STAT_TYPE_DIR 2
83 
84 /** \brief stat_t.type: A virtual device of some sort (pipe, socket, etc) */
85 #define STAT_TYPE_PIPE 3
86 
87 /** \brief stat_t.type: Meta data */
88 #define STAT_TYPE_META 4
89 
90 /** \brief stat_t.type: Symbolic link */
91 #define STAT_TYPE_SYMLINK 5
92 
93 /* stat_t.attr */
94 #define STAT_ATTR_NONE 0x00 /**< \brief stat_t.attr: No attributes */
95 #define STAT_ATTR_R 0x01 /**< \brief stat_t.attr: Read-capable */
96 #define STAT_ATTR_W 0x02 /**< \brief stat_t.attr: Write-capable */
97 
98 /** \brief stat_t.attr: Read/Write capable */
99 #define STAT_ATTR_RW (STAT_ATTR_R | STAT_ATTR_W)
100 
101 /** \brief File descriptor type */
102 typedef int file_t;
103 
104 /** \brief Invalid file handle constant (for open failure, etc) */
105 #define FILEHND_INVALID ((file_t)-1)
106 
107 /** \brief VFS handler interface.
108 
109  All VFS handlers must implement this interface.
110 
111  \headerfile kos/fs.h
112 */
113 typedef struct vfs_handler {
114  /** \brief Name manager handler header */
116 
117  /* Some VFS-specific pieces */
118  /** \brief Allow VFS cacheing; 0=no, 1=yes */
119  int cache;
120  /** \brief Pointer to private data for the handler */
121  void *privdata;
122 
123  /** \brief Open a file on the given VFS; return a unique identifier */
124  void *(*open)(struct vfs_handler *vfs, const char *fn, int mode);
125 
126  /** \brief Close a previously opened file */
127  int (*close)(void *hnd);
128 
129  /** \brief Read from a previously opened file */
130  ssize_t (*read)(void *hnd, void *buffer, size_t cnt);
131 
132  /** \brief Write to a previously opened file */
133  ssize_t (*write)(void *hnd, const void *buffer, size_t cnt);
134 
135  /** \brief Seek in a previously opened file */
136  off_t(*seek)(void *hnd, off_t offset, int whence);
137 
138  /** \brief Return the current position in a previously opened file */
139  off_t(*tell)(void *hnd);
140 
141  /** \brief Return the total size of a previously opened file */
142  size_t (*total)(void *hnd);
143 
144  /** \brief Read the next directory entry in a directory opened with O_DIR */
145  dirent_t *(*readdir)(void *hnd);
146 
147  /** \brief Execute a device-specific call on a previously opened file */
148  int (*ioctl)(void *hnd, void *data, size_t size);
149 
150  /** \brief Rename/move a file on the given VFS */
151  int (*rename)(struct vfs_handler *vfs, const char *fn1, const char *fn2);
152 
153  /** \brief Delete a file from the given VFS */
154  int (*unlink)(struct vfs_handler *vfs, const char *fn);
155 
156  /** \brief "Memory map" a previously opened file */
157  void *(*mmap)(void *fd);
158 
159  /** \brief Perform an I/O completion (async I/O) for a previously opened
160  file */
161  int (*complete)(void *fd, ssize_t *rv);
162 
163  /** \brief Get status information on a file on the given VFS */
164  int (*stat)(struct vfs_handler *vfs, const char *fn, stat_t *rv);
165 
166  /** \brief Make a directory on the given VFS */
167  int (*mkdir)(struct vfs_handler *vfs, const char *fn);
168 
169  /** \brief Remove a directory from the given VFS */
170  int (*rmdir)(struct vfs_handler *vfs, const char *fn);
171 
172  /** \brief Manipulate file control flags on the given file */
173  int (*fcntl)(void *fd, int cmd, va_list ap);
174 
175  /** \brief Check if an event is pending on the given file */
176  short (*poll)(void *fd, short events);
177 
178  /** \brief Create a hard link */
179  int (*link)(struct vfs_handler *vfs, const char *path1, const char *path2);
180 
181  /** \brief Create a symbolic link */
182  int (*symlink)(struct vfs_handler *vfs, const char *path1,
183  const char *path2);
184 
185  /* 64-bit file access functions. Generally, you should only define one of
186  the 64-bit or 32-bit versions of these functions. */
187 
188  /** \brief Seek in a previously opened file (64-bit offsets) */
189  _off64_t (*seek64)(void *hnd, _off64_t offset, int whence);
190 
191  /** \brief Return the current position in an opened file (64-bit offset) */
192  _off64_t (*tell64)(void *hnd);
193 
194  /** \brief Return the size of an opened file as a 64-bit integer */
195  uint64 (*total64)(void *hnd);
196 } vfs_handler_t;
197 
198 /** \brief The number of distinct file descriptors that can be in use at a
199  time.
200 */
201 #define FD_SETSIZE 1024
202 
203 /** \cond */
204 /* This is the private struct that will be used as raw file handles
205  underlying descriptors. */
206 struct fs_hnd;
207 
208 /* The kernel-wide file descriptor table. These will reference to open files. */
209 extern struct fs_hnd *fd_table[FD_SETSIZE];
210 /** \endcond */
211 
212 /* Open modes */
213 #include <sys/fcntl.h>
214 /** \defgroup open_modes File open modes
215 
216  @{
217 */
218 #define O_MODE_MASK 0x0f /**< \brief Mask for mode numbers */
219 //#define O_TRUNC 0x0100 /* Truncate */
220 #define O_ASYNC 0x0200 /**< \brief Open for asynchronous I/O */
221 //#define O_NONBLOCK 0x0400 /* Open for non-blocking I/O */
222 #define O_DIR 0x1000 /**< \brief Open as directory */
223 #define O_META 0x2000 /**< \brief Open as metadata */
224 /** @} */
225 
226 /** \defgroup seek_modes Seek modes
227 
228  These are the values you can pass for the whence parameter to fs_seek().
229 
230  @{
231 */
232 #define SEEK_SET 0 /**< \brief Set position to offset. */
233 #define SEEK_CUR 1 /**< \brief Seek from current position. */
234 #define SEEK_END 2 /**< \brief Seek from end of file. */
235 /** @} */
236 
237 /* Standard file descriptor functions */
238 /** \brief Open a file on the VFS.
239 
240  This function opens the specified file, returning a new file descriptor to
241  access the file.
242 
243  \param fn The path to open.
244  \param mode The mode to use with opening the file. This may
245  include the standard open modes (O_RDONLY, O_WRONLY,
246  etc), as well as values from the \ref open_modes
247  list. Multiple values can be ORed together.
248  \return The new file descriptor on success, -1 on error.
249 */
250 file_t fs_open(const char *fn, int mode);
251 
252 /** \brief Close an opened file.
253 
254  This function closes the specified file descriptor, releasing all resources
255  associated with the descriptor.
256 
257  \param hnd The file descriptor to close.
258  \return 0 for success, -1 for error
259 */
260 int fs_close(file_t hnd);
261 
262 /** \brief Read from an opened file.
263 
264  This function reads into the specified buffer from the file at its current
265  file pointer.
266 
267  \param hnd The file descriptor to read from.
268  \param buffer The buffer to read into.
269  \param cnt The size of the buffer (or the number of bytes
270  requested).
271  \return The number of bytes read, or -1 on error. Note that
272  this may not be the full number of bytes requested.
273 */
274 ssize_t fs_read(file_t hnd, void *buffer, size_t cnt);
275 
276 /** \brief Write to an opened file.
277 
278  This function writes the specfied buffer into the file at the current file
279  pointer.
280 
281  \param hnd The file descriptor to write into.
282  \param buffer The data to write into the file.
283  \param cnt The size of the buffer, in bytes.
284  \return The number of bytes written, or -1 on failure. Note
285  that the number of bytes written may be less than
286  what was requested.
287 */
288 ssize_t fs_write(file_t hnd, const void *buffer, size_t cnt);
289 
290 /** \brief Seek to a new position within a file.
291 
292  This function moves the file pointer to the specified position within the
293  file (the base of this position is determined by the whence parameter).
294 
295  \param hnd The file descriptor to move the pointer for.
296  \param offset The offset in bytes from the specified base.
297  \param whence The base of the pointer move. This should be one of
298  the \ref seek_modes values.
299  \return The new position of the file pointer.
300 */
301 off_t fs_seek(file_t hnd, off_t offset, int whence);
302 
303 /** \brief Seek to a new position within a file (64-bit offsets).
304 
305  This function moves the file pointer to the specified position within the
306  file (the base of this position is determined by the whence parameter).
307 
308  \param hnd The file descriptor to move the pointer for.
309  \param offset The offset in bytes from the specified base.
310  \param whence The base of the pointer move. This should be one of
311  the \ref seek_modes values.
312  \return The new position of the file pointer.
313 */
314 _off64_t fs_seek64(file_t hnd, _off64_t offset, int whence);
315 
316 /** \brief Retrieve the position of the pointer within a file.
317 
318  This function retrieves the current location of the file pointer within an
319  opened file. This is an offset in bytes from the start of the file.
320 
321  \param hnd The file descriptor to retrieve the pointer from.
322  \return The offset within the file for the pointer.
323 */
324 off_t fs_tell(file_t hnd);
325 
326 /** \brief Retrieve the position of the 64-bit pointer within a file.
327 
328  This function retrieves the current location of the file pointer within an
329  opened file. This is an offset in bytes from the start of the file.
330 
331  \param hnd The file descriptor to retrieve the pointer from.
332  \return The offset within the file for the pointer.
333 */
335 
336 /** \brief Retrieve the length of an opened file.
337 
338  This file retrieves the length of the file associated with the given file
339  descriptor.
340 
341  \param hnd The file descriptor to retrieve the size from.
342  \return The length of the file on success, -1 on failure.
343 */
344 size_t fs_total(file_t hnd);
345 
346 /** \brief Retrieve the length of an opened file as a 64-bit integer.
347 
348  This file retrieves the length of the file associated with the given file
349  descriptor.
350 
351  \param hnd The file descriptor to retrieve the size from.
352  \return The length of the file on success, -1 on failure.
353 */
355 
356 
357 /** \brief Read an entry from an opened directory.
358 
359  This function reads the next entry from the directory specified by the given
360  file descriptor.
361 
362  \param hnd The opened directory's file descriptor.
363  \return The next entry, or NULL on failure.
364 */
366 
367 /** \brief Execute a device-specific command on a file descriptor.
368 
369  The types and formats of the commands are device/filesystem specific, and
370  are not documented here. Each filesystem may define any commands that are
371  specific to it with its implementation of this function.
372 
373  \param hnd The file descriptor to operate on.
374  \param data The command to send.
375  \param size The size of the command, in bytes.
376  \return -1 on failure.
377 */
378 int fs_ioctl(file_t hnd, void *data, size_t size);
379 
380 /** \brief Rename the specified file to the given filename.
381 
382  This function renames the file specified by the first argument to the second
383  argument. The two paths should be on the same filesystem.
384 
385  \param fn1 The existing file to rename.
386  \param fn2 The new filename to rename to.
387  \return 0 on success, -1 on failure.
388 */
389 int fs_rename(const char *fn1, const char *fn2);
390 
391 /** \brief Delete the specified file.
392 
393  This function deletes the specified file from the filesystem. This should
394  only be used for files, not for directories. For directories, use fs_rmdir()
395  instead of this function.
396 
397  \param fn The path to remove.
398  \return 0 on success, -1 on failure.
399 */
400 int fs_unlink(const char *fn);
401 
402 /** \brief Change the current working directory of the current thread.
403 
404  This function changes the current working directory for the current thread.
405  Any relative paths passed into file-related functions will be relative to
406  the path that is changed to.
407 
408  \param fn The path to set as the current working directory.
409  \return 0 on success, -1 on failure.
410 */
411 int fs_chdir(const char *fn);
412 
413 /** \brief Memory-map a previously opened file.
414 
415  This file "maps" the opened file into memory, reading the whole file into a
416  buffer, and returning that buffer. The returned buffer should not be freed,
417  as it will be freed when the file is closed. Bytes written into the buffer,
418  up to the original length of the file, will be written back to the file when
419  it is closed, assuming that the file is opened for writing.
420 
421  Note that some of the filesystems in KallistiOS do not support this
422  operation.
423 
424  \param hnd The descriptor to memory map.
425  \return The memory mapped buffer, or NULL on failure.
426 */
427 void *fs_mmap(file_t hnd);
428 
429 /** \brief Perform an I/O completion on the given file descriptor.
430 
431  This function is used with asynchronous I/O to perform an I/O completion on
432  the given file descriptor. Most filesystems do not support this operation
433  on KallistiOS.
434 
435  \param fd The descriptor to complete I/O on.
436  \param rv A buffer to store the size of the I/O in.
437  \return 0 on success, -1 on failure.
438 */
439 int fs_complete(file_t fd, ssize_t *rv);
440 
441 /** \brief Retrieve information about the specified path.
442 
443  This function retrieves the stat_t structure for the given path on the VFS.
444  This function is similar to the standard POSIX function stat(), but provides
445  slightly different data than it does.
446 
447  \param fn The path to retrieve information about.
448  \param rv The buffer to store stat information in.
449  \return 0 on success, -1 on failure.
450 */
451 int fs_stat(const char *fn, stat_t *rv);
452 
453 /** \brief Create a directory.
454 
455  This function creates the specified directory, if possible.
456 
457  \param fn The path of the directory to create.
458  \return 0 on success, -1 on failure.
459 */
460 int fs_mkdir(const char *fn);
461 
462 /** \brief Remove a directory by name.
463 
464  This function removes the specified directory. The directory shall only be
465  removed if it is empty.
466 
467  \param fn The path of the directory to remove.
468  \return 0 on success, -1 on failure.
469 */
470 int fs_rmdir(const char *fn);
471 
472 /** \brief Manipulate file control flags.
473 
474  This function implements the standard C fcntl function.
475 
476  \param fd The file descriptor to use.
477  \param cmd The command to run.
478  \param ... Arguments for the command specified.
479  \return -1 on error (generally).
480 */
481 int fs_fcntl(file_t fd, int cmd, ...);
482 
483 /** \brief Create a hard link.
484 
485  This function implements the POSIX function link(), which creates a hard
486  link for an existing file.
487 
488  \param path1 An existing file to create a new link to.
489  \param path2 The pathname of the new link to be created.
490  \return 0 on success, -1 on failure.
491 
492  \note Most filesystems in KallistiOS do not support hard
493  links. Unlike most other VFS functions, this one
494  does not set errno to ENOSYS in that case, but
495  rather to EMLINK to preserve existing the original
496  behavior in KOS.
497 */
498 int fs_link(const char *path1, const char *path2);
499 
500 /** \brief Create a symbolic link.
501 
502  This function implements the POSIX function symlink(), which creates a
503  symbolic link on the filesystem. Symbolic links are not required to point to
504  an existing file (per POSIX) and may result in circular links if care is not
505  taken. For now, symbolic links cannot cross filesystem boundaries in KOS.
506 
507  \param path1 The content of the link (i.e, what to point at).
508  \param path2 The pathname of the new link to be created.
509  \return 0 on success, -1 on failure.
510 
511  \note Most filesystems in KallistiOS do not support
512  symbolic links. Filesystems that do not support
513  symlinks will simply set errno to ENOSYS.
514 */
515 int fs_symlink(const char *path1, const char *path2);
516 
517 /** \brief Duplicate a file descriptor.
518 
519  This function duplicates the specified file descriptor, returning a new file
520  descriptor that can be used to access the file. This is equivalent to the
521  standard POSIX function dup().
522 
523  \param oldfd The old file descriptor to duplicate.
524  \return The new file descriptor on success, -1 on failure.
525 */
526 file_t fs_dup(file_t oldfd);
527 
528 /** \brief Duplicate a file descriptor onto the specified descriptor.
529 
530  This function duplicates the specified file descriptor onto the other file
531  descriptor provided. If the newfd parameter represents an open file, that
532  file will be closed before the old descriptor is duplicated onto it. This is
533  equivalent to the standard POSIX function dup2().
534 
535  \param oldfd The old file descriptor to duplicate.
536  \param newfd The descriptor to copy into.
537  \return The new file descriptor on success, -1 on failure.
538 */
539 file_t fs_dup2(file_t oldfd, file_t newfd);
540 
541 /** \brief Create a "transient" file descriptor.
542 
543  This function creates and opens a new file descriptor that isn't associated
544  directly with a file on the filesystem. This is used internally to actually
545  open files, and should (in general) not be called by user code. Effectively,
546  if you're trying to implement your own filesystem handler in your code, you
547  may need this function, otherwise you should just ignore it.
548 
549  \param vfs The VFS handler structure to use for the file.
550  \param hnd Internal handle data for the file.
551  \return The opened descriptor on success, -1 on failure.
552 */
553 file_t fs_open_handle(vfs_handler_t *vfs, void *hnd);
554 
555 /** \brief Retrieve the VFS Handler for a file descriptor.
556 
557  This function retrieves the Handler structure for the VFS of the specified
558  file descriptor. There is generally no reason to call this function in user
559  code, as it is meant for use internally.
560 
561  \param fd The file descriptor to retrieve the handler for.
562  \return The VFS' handler structure.
563 */
565 
566 /** \brief Retrieve the internal handle for a file descriptor.
567 
568  This function retrieves the internal file handle data of the specified file
569  descriptor. There is generally no reason to call this function in user code,
570  as it is meant for use internally.
571 
572  \param fd The file descriptor to retrieve the handler for.
573  \return The internal handle for the file descriptor.
574 */
575 void *fs_get_handle(file_t fd);
576 
577 /** \brief Get the current working directory of the running thread.
578  \return The current working directory.
579 */
580 const char *fs_getwd();
581 
582 /* Couple of util functions */
583 
584 /** \brief Copy a file.
585 
586  This function copies the file at src to dst on the filesystem.
587 
588  \param src The filename to copy from.
589  \param dst The filename to copy to.
590  \return The number of bytes copied successfully.
591 */
592 ssize_t fs_copy(const char *src, const char *dst);
593 
594 /** \brief Open and read a whole file into RAM.
595 
596  This function opens the specified file, reads it into memory (allocating the
597  necessary space with malloc), and closes the file. The caller is responsible
598  for freeing the memory when they are done with it.
599 
600  \param src The filename to open and read.
601  \param out_ptr A pointer to the buffer on success, NULL otherwise.
602  \return The size of the file on success, -1 otherwise.
603 */
604 ssize_t fs_load(const char *src, void **out_ptr);
605 
606 /** \brief Initialize the virtual filesystem.
607 
608  This is normally done for you by default when KOS starts. In general, there
609  should be no reason for you to call this function.
610 
611  \retval 0 On success.
612 */
613 int fs_init();
614 
615 /** \brief Shut down the virtual filesystem.
616 
617  This is done for you by the normal shutdown procedure of KOS. There should
618  not really be any reason for you to call this function yourself.
619 */
620 void fs_shutdown();
621 
622 __END_DECLS
623 
624 #endif /* __KOS_FS_H */