Implementing an access method in practice

Implementing a new access method is really not difficult at all. This section explains how this is done.


Using shared libraries

Every module must be compiled as a shared library (i.e. a .so file).

The current way for accessing the right module for the right method is very simple, and is based on file names. In practice, a module implementing access method named foo must be named libfoo.so. For example, the module implementing the ftp: access method is called libftp.so, the module implementing #gzip access is called libgzip.so and so on.

This might change in the future.


The initialization/shutdown functions

Every shared library module must provide two functions:


GnomeVFSMethod *vfs_module_init (void);
void vfs_module_shutdown (GnomeVFSMethod *method);

These are the only functions that the VFS library will access directly. All the other symbols (i.e. functions and variables) in the module should be made static.

vfs_module_init() is called as soon as the module is loaded in memory. It will have to return a pointer to a GnomeVFSMethod object that will contain the pointers to the method's implementation functions. We will describe this later.

vfs_module_shutdown, instead, is called before the module is unloaded or the program that uses it dies. This functions should:


The GnomeVFSMethod object

This object is contains pointers to the module implementation functions.


GnomeVFSResult (* open)              (GnomeVFSMethodHandle **method_handle_return,
                                      GnomeVFSURI *uri,
                                      GnomeVFSOpenMode mode
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* create)            (GnomeVFSMethodHandle **method_handle_return,
                                      GnomeVFSURI *uri,
                                      GnomeVFSOpenMode mode,
                                      gboolean exclusive,
                                      guint perm
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* close)             (GnomeVFSMethodHandle *method_handle
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* read)              (GnomeVFSMethodHandle *method_handle,
                                      gpointer buffer,
                                      GnomeVFSFileSize num_bytes,
                                      GnomeVFSFileSize *bytes_read_return
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* write)             (GnomeVFSMethodHandle *method_handle,
                                      gconstpointer buffer,
                                      GnomeVFSFileSize num_bytes,
                                      GnomeVFSFileSize *bytes_written_return
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* seek)              (GnomeVFSMethodHandle *method_handle,
                                      GnomeVFSSeekPosition  whence,
                                      GnomeVFSFileOffset    offset
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* tell)              (GnomeVFSMethodHandle *method_handle,
                                      GnomeVFSFileOffset *offset_return);

GnomeVFSResult (* truncate)          (GnomeVFSMethodHandle *method_handle,
                                      GnomeVFSFileSize where
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* open_directory)    (GnomeVFSMethodHandle **method_handle,
                                      GnomeVFSURI *uri,
                                      GnomeVFSFileInfoOptions options,
                                      const GList *meta_keys,
                                      const GnomeVFSDirectoryFilter *filter
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* close_directory)   (GnomeVFSMethodHandle *method_handle
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* read_directory)    (GnomeVFSMethodHandle *method_handle,
                                      GnomeVFSFileInfo *file_info
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* get_file_info)     (GnomeVFSURI *uri,
                                      GnomeVFSFileInfo *file_info,
                                      GnomeVFSFileInfoOptions options,
                                      const GList *meta_keys
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* get_file_info_from_handle)
                                     (GnomeVFSMethodHandle *method_handle,
                                      GnomeVFSFileInfo *file_info,
                                      GnomeVFSFileInfoOptions options,
                                      const GList *meta_keys
                                      GnomeVFSCancellation *cancellation);

gboolean       (* is_local)          (const GnomeVFSURI *uri
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* rename)            (GnomeVFSURI *uri, const gchar *new_name
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* make_directory)    (GnomeVFSURI *uri, guint perm
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* remove_directory)  (GnomeVFSURI *uri
                                      GnomeVFSCancellation *cancellation);

GnomeVFSResult (* unlink)            (GnomeVFSURI *uri
                                      GnomeVFSCancellation *cancellation);