Changes between Initial Version and Version 1 of FilesystemAPITutorial


Ignore:
Timestamp:
2017-04-08T15:09:29Z (8 years ago)
Author:
Jakub Jermář
Comment:

Start the Filesystem API Tutorial

Legend:

Unmodified
Added
Removed
Modified
  • FilesystemAPITutorial

    v1 v1  
     1= Filesystem API Tutorial =
     2[[PageOutline(2-3)]]
     3
     4This tutorial will guide you through the steps that are necessary to work with files on the standard HelenOS API level in an idiomatic way.
     5
     6== Preparing to use the API ==
     7
     8HelenOS filesystem API is implemented in the standard library, so there is no need to link against any additional library in order to access files. HelenOS requires you to only include `vfs/vfs.h` in order to get declarations of all filesystem APIs:
     9
     10{{{
     11#include <vfs/vfs.h>
     12}}}
     13
     14== Paths and File handles ==
     15
     16The API is designed to use file handles as a primary way to refer to files. One may obtain a file handle by looking up a filesytem path, creating a new file or directory or attaching a new filesystem into the filesystem hierarchy.
     17
     18== Reading an existing file ==
     19
     20Suppose we want to read the contents of file `/foo/bar`. We first need to lookup the file and convert it to a file handle:
     21
     22{{{
     23int file = vfs_lookup("/foo/bar", WALK_REGULAR);
     24if (file < 0)
     25        return file;
     26}}}
     27
     28This will only succeed if the file exists and is a regular file, i.e. not a directory, in which case `vfs_lookup()` receives a file handle. Otherwise we receive a negative error code and bail out.
     29
     30Because our intention is to perform a read operation on `file`, we must first open it for reading:
     31
     32{{{
     33int rc = vfs_open(file, MODE_READ);
     34if (rc != EOK) {
     35        vfs_put(file);
     36        return rc;
     37}
     38}}}
     39
     40Note that `vfs_open()` does not take a path as an argument and does not return a file handle. Instead it takes a pre-existing file handle as an argument, internally marks the file as open for reading and returns a result code, which is EOK on success and negative on error. Also note that in case of error, the file handle we are using needs to be returned to the system before bailing out.
     41
     42We are now ready to do a couple of synchronous read from the file. Let's say we first want to read a 4KiB-buffer from offset 0x1000:
     43
     44{{{
     45uint8_t buffer[4096];
     46aoff64_t pos = 0x1000;
     47
     48ssize_t size = vfs_read(file, &pos, buffer, sizeof(buffer));
     49if (size < 0) {
     50        vfs_put(file);
     51        return size;
     52}
     53if (size == 0) {
     54        /* handle EOF */
     55}
     56
     57/* buffer is now guaranteed to contain the desired data */
     58...
     59}}}
     60
     61The position to read from was passed to `vfs_read()` explicitly. Moreover, `pos` was updated by `vfs_read()` to reflect the updated position. We are now ready to read an additional 4KiB-buffer from offset 0x2000:
     62
     63{{{
     64size = vfs_read(file, &pos, buffer, sizeof(buffer));
     65if (size < 0) {
     66        vfs_put(file);
     67        return size;
     68}
     69if (size == 0) {
     70        /* handle EOF */
     71}
     72
     73/* buffer is now guaranteed to contain the desired data */
     74...
     75}}}
     76
     77Finally, if we wanted to continue reading at offset 0x4000, we could simply do:
     78
     79{{{
     80pos = 0x4000;
     81size = vfs_read(file, &pos, buffer, sizeof(buffer));
     82...
     83}}}