The easiest way to interact with GnomeVFS is with synchronous access. After obtaining a file descriptor by opening a file, you can read, write, and seek. During synchronous access, read and write data is passed in an allocated buffer, and function calls return only when they have finished their work, blocking the rest of the program.
The Unix stream system is the model for synchronous mode in GnomeVFS, and the function calls are similar, as shown here.
Unix Function | GnomeVFS Equivalent |
---|---|
open () | gnome_vfs_open*() |
creat () | gnome_vfs_create*() |
close() | gnome_vfs_close() |
read() | gnome_vfs_read() |
write() | gnome_vfs_write() |
lseek () | gnome_vfs_seek() |
ftell () | gnome_vfs_tell() |
truncate() | gnome_vfs_truncate*() |
unlink() | gnome_vfs_unlink*() |
symlink () | gnome_vfs_create_symbolic_link() |
stat(), lstat () | gnome_vfs_get_file_info*() |
rename(), chown(), chmod() | gnome_vfs_set_file_info() |
mkdir() | gnome_vfs_make_directory*() |
rmdir() | gnome_vfs_remove_directory*() |
Before you see the long, drawn-out description of these GnomeVFS functions, you should see them in use. The program's initial section includes a small utility function to print an appropriate error message when there is a problem with file access:
/* -*-coding: utf-8;-*- */ /* vfsdemo.c -- synchronous operations */ #include <string.h> #include <libgnome/libgnome.h> #include <libgnomevfs/gnome-vfs.h> /* print a VFS error code, its description, and the problem URI */ int print_error(GnomeVFSResult code, const gchar *uri) { const gchar *error_desc; error_desc = gnome_vfs_result_to_string(code); g_printerr("error %d when accessing %s: %s\n", code, uri, error_desc); return (code); }
The main program creates or opens a file and writes a test string:
const gchar filename[] = "gnome-vfsdemo-testfile"; const gchar test_text[] = "This is a test."; int main(int argc, char **argv) { gchar *file_path; gchar *uri; guint permissions; GnomeVFSHandle *fd; GnomeVFSResult result; GnomeVFSFileSize bytes_written; /* initialize GnomeVFS */ if (!gnome_vfs_init()) { g_error("could not initialize GnomeVFS\n"); } /* get full pathname and URI */ file_path = gnome_util_prepend_user_home(filename); g_print("filename is %s\n", file_path); uri = gnome_vfs_get_uri_from_local_path(file_path); g_print("URI is %s\n", uri); g_free(file_path); /* permissions: user has read-write access, group, and other read-only */ permissions = GNOME_VFS_PERM_USER_READ GNOME_VFS_PERM_USER_WRITE GNOME_VFS_PERM_GROUP_READ GNOME_VFS_PERM_OTHER_READ; /* create and open URI */ g_print("creating/opening URI...\n"); result = gnome_vfs_create(&fd, uri, GNOME_VFS_OPEN_WRITE, FALSE, permissions); if (result != GNOME_VFS_OK) { return (print_error(result, uri)); } g_print(" success.\n"); /* write test_text into file descriptor */ g_print("writing \"%s\" into file descriptor...\n", test_text); result = gnome_vfs_write(fd, test_text, strlen(test_text), &bytes_written); if (result != GNOME_VFS_OK) { return (print_error(result, uri)); } g_print(" success. %d bytes written.\n", (guint) bytes_written); /* close file */ g_print("closing file descriptor...\n"); result = gnome_vfs_close(fd); if (result != GNOME_VFS_OK) { return (print_error(result, uri)); } g_print(" success.\n"); g_free(uri); /* shut down GnomeVFS */ gnome_vfs_shutdown(); return (0); }
If you'd like to see an error message, run this program, run chmod 000 gnome-vfsdemo-testfile in your home directory, and then run the program again.
As you can see from this example, synchronous GnomeVFS operations are similar to those of traditional Unix utilities, but the implementation is slightly different. A URI as a string or a GnomeVFSURI structure takes the place of a filename (see Section 8.8 for more information on GnomeVFSURI ). Because there are two ways to specify URIs, there are two versions of many functions (for example, gnome_vfs_open() and gnome_vfs_open_uri() ).
GnomeVFS does not use GError, opting instead for a system very similar to errno / strerror() in Unix. All access functions return a GnomeVFSResult code. The preceding example illustrates how you might work with this error code; see Section 8.10 for a full description of the error codes.
GnomeVFSFileHandle is a full data structure. Because functions such as gnome_vfs_open() return GnomeVFSResult , they take the addresses of pointers to a GnomeVFSFileHandle as parameters. Addresses of pointers and memory pervade the GnomeVFS API.
Note | GnomeVFSFileHandle structures are not GObject objects. There are special management functions for file descriptors. |
The next few subsections form a reference to synchronous GnomeVFS file operations.
The functions in this section use these parameters:
handle ( GnomeVFSHandle * ) is a file descriptor pointer.
handle_addr ( GnomeVFSHandle ** ) is the address of a file descriptor pointer.
uri_string ( gchar * ) is a string containing a URI.
uri ( GnomeVFSURI * ) is a URI structure (see Section 8.8).
mode ( guint ) is the access mode, described later in this section.
All of these functions return GnomeVFSResult :
gnome_vfs_open( handle_addr , uri_string , mode )
Opens uri_string and sets the pointer at handle_addr to point to the new file descriptor.
gnome_vfs_open_uri( handle_addr , uri , mode )
Same as the preceding function, but with the GnomeVFSURI uri .
gnome_vfs_create( handle_addr , uri_string , mode , exclusive , permissions )
Creates and opens a file at uri_string , setting the pointer at handle_addr to point to the new file descriptor. The exclusive parameter is a Boolean value; if this is TRUE , this function returns an error if the file already exists. See the discussion that follows for a description of permissions .
gnome_vfs_create_uri( handle_addr , uri , mode , exclusive , permissions )
Same as the preceding function, but with a URI structure instead of a URI string.
gnome_vfs_close( handle )
Closes the file descriptor at handle .
Specify the GnomeVFSOpenMode mode parameter as a bitwise OR of any of the following values:
GNOME_VFS_OPEN_READ : Read access.
GNOME_VFS_OPEN_WRITE : Write access.
GNOME_VFS_OPEN_RANDOM : Random access (allows seek operations).
Note | Make sure that you set the options that you need; GNOME_VFS_OPEN_WRITE does not imply GNOME_VFS_OPEN_READ . |
The permissions mode parameter is a Unix-style unsigned integer. Set it to a bitwise OR of these values:
GNOME_VFS_PERM_USER_READ : User has read permission.
GNOME_VFS_PERM_USER_WRITE : User has write permission.
GNOME_VFS_PERM_USER_EXEC : User has execute permission.
GNOME_VFS_PERM_USER_ALL : A bitwise OR of the three preceding permissions.
GNOME_VFS_PERM_GROUP_READ : Group has read permission.
GNOME_VFS_PERM_GROUP_WRITE : Group has write permission.
GNOME_VFS_PERM_GROUP_EXEC : Group has execute permission.
GNOME_VFS_PERM_GROUP_ALL : A bitwise OR of the three preceding permissions.
GNOME_VFS_PERM_OTHER_READ : Everyone has read permission.
GNOME_VFS_PERM_OTHER_WRITE : Everyone has write permission.
GNOME_VFS_PERM_OTHER_EXEC : Everyone has execute permission.
GNOME_VFS_PERM_OTHER_ALL : A bitwise OR of the three preceding permissions.
GNOME_VFS_PERM_SUID : An executable with this bit set runs as the file's owner.
GNOME_VFS_PERM_SGID : An executable with this bit set runs with the file's group.
GNOME_VFS_PERM_STICKY : You can delete a a file in a directory with this permission, but only if you are the file owner.
The functions in this section use these parameters:
handle ( GnomeVFSHandle * ) is a file descriptor.
buffer ( gpointer ) points to a buffer.
bytes ( GnomeVFSFileSize ) is a byte count, buffer .
byte_count_addr ( GnomeVFSFileSize * ) indicates where to write a byte count.
All of these functions return GnomeVFSResult :
gnome_vfs_read( handle , buffer , n_bytes , byte_count_addr )
Reads at most bytes from handle into buffer and writes the number of bytes read into the location at byte_count_addr . Usually, bytes is the size of buffer .
gnome_vfs_write( handle , buffer , n_bytes , byte_count_addr )
Same as the preceding function, but writes from buffer to handle .
gnome_vfs_tell( handle , offset_addr )
Writes the current file position in handle to offset_addr ( GnomeVFSFileSize * ).
gnome_vfs_seek( handle , start_pos , offset )
Sets the file position in handle to offset bytes from start_pos . The offset parameter has type GnomeVFSFileSize , and start_pos is one of the following:
GNOME_VFS_SEEK_START : Beginning of file.
GNOME_VFS_SEEK_END : End of file.
GNOME_VFS_SEEK_CURRENT : Current file position in handle .
The most important function to retrieving information on a file is
GnomeVFSResult result ; result = gnome_vfs_get_file_info( uri_string , info , options );
Here, uri_string is the URI to query, info is a GnomeVFSFileInfo structure to fill, and options is a bitwise OR of any of the following:
GNOME_VFS_FILE_INFO_DEFAULT
GNOME_VFS_FILE_INFO_GET_MIME_TYPE : Retrieve the MIME type of the file.
GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE : Try to determine the MIME type without looking inside the file; that is, look at the file extension.
GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE : Use every available means to detect the MIME type. This can take some time.
GNOME_VFS_FILE_INFO_FOLLOW_LINKS : Automatically follow symbolic links.
GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS : Extract permissions. This can take some time on remote systems.
A GnomeVFSFileInfo result usually has invalid fields because not all files exhibit every characteristic in the structure (for example, a file from the Web does not have a hard link count). Furthermore, you can turn off permissions fields. At the very least, though, you can count on this field being valid:
name ( char * ): The file's base name (without a path ).
Admittedly, the name alone isn't much to go on. These three fields are usually also available:
uid ( guint ): The file owner.
gid ( guint ): The file group.
valid_fields ( GnomeVFSFileInfoFields ): Valid fields in the rest of the GnomeVFSFileInfo structure. This is a bit field; GNOME_VFS_FILE_INFO_FIELDS_NONE means that no other fields are valid. See the discussion that follows for the other bit settings.
Here are the other fields along with their validity bits:
type ( GnomeVFSFileType )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_TYPE
The file type. Possible values include
GNOME_VFS_FILE_TYPE_UNKNOWN
GNOME_VFS_FILE_TYPE_REGULAR
GNOME_VFS_FILE_TYPE_DIRECTORY
GNOME_VFS_FILE_TYPE_FIFO (named pipe)
GNOME_VFS_FILE_TYPE_SOCKET
GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE
GNOME_VFS_FILE_TYPE_BLOCK_DEVICE
GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK
permissions ( GnomeVFSFilePermissions )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS
Access permissions.
flags ( GnomeVFSFileFlags ; bit mask)
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_FLAGS
A bitwise OR of the following miscellaneous options:
GNOME_VFS_FILE_FLAGS_NONE
GNOME_VFS_FILE_FLAGS_SYMLINK (symbolic link)
GNOME_VFS_FILE_FLAGS_LOCAL (resides on the local file system)
device ( dev_t )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_DEVICE
The device number, if this is a local file and a device. Depending on your operating system, you may be able extract the major and minor device numbers with MAJOR() and MINOR() .
inode ( GnomeVFSInodeNumber )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_INODE
The file system inode number.
link_count ( guint )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT
The file system hard link count.
size ( GnomeVFSFileSize )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_SIZE
The file size, in bytes.
block_count ( GnomeVFSFileSize )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT
The number of 512-byte blocks that the file occupies.
io_block_size ( guint )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE
Optimal buffer size for reading to or from the file.
atime ( time_t )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_ATIME
The file's last access (read or write) time; time_t is not completely platform independent.
mtime ( time_t )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_MTIME
The file's last modification time (creation or alteration of the file content).
ctime ( time_t )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_CTIME
The file's last change time. A change is anything that alters the file's inode structure.
symlink_name ( char * )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME
If the file is a symbolic link, this is the link target.
mime_type ( char * )
Validity bit: GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
The file's MIME type.
You can change some of a file's information with
result = gnome_vfs_set_file_info( uri_string , info , fields );
Here, uri_string is the target URI, info is the GnomeVFSFileInfo structure containing the information, and fields is a bitwise OR for the fields to change:
GNOME_VFS_SET_FILE_INFO_NAME (filename)
GNOME_VFS_SET_FILE_INFO_PERMISSIONS
GNOME_VFS_SET_FILE_INFO_OWNER
GNOME_VFS_SET_FILE_INFO_TIME (access and modification times)
The following functions are similar to the preceding basic functions and return GnomeVFSResult :
gnome_vfs_get_file_info_uri(GnomeVFSURI * uri , GnomeVFSFileInfo * info , GnomeVFSFileInfoOptions options )
Like gnome_vfs_get_file_info() , but uses a URI structure rather than a string.
gnome_vfs_get_file_info_from_handle(GnomeVFSHandle handle , GnomeVFSFileInfo * info , GnomeVFSFileInfoOptions options )
Like gnome_vfs_get_file_info() , but operates on an the open file descriptor handle .
gnome_vfs_set_file_info_uri(GnomeVFSURI * uri , GnomeVFSFileInfo * info , GnomeVFSSetFileInfoMask fields )
Like gnome_vfs_set_file_info() , but uses a URI structure rather than a string.
gnome_vfs_check_same_fs(const gchar * uri_str1 , const gchar * uri_str2 , gboolean * same_fs )
Writes TRUE into * same_fs if uri_str1 and uri_str2 are on the same file system.
You can manage GnomeVFSFileInfo structures with these functions:
GnomeVFSFileInfo *gnome_vfs_file_info_new(void)
Returns a freshly allocated and initialized GnomeVFSFileInfo structure. This structure will have one reference count.
void gnome_vfs_file_info_ref(GnomeVFSFileInfo * info )
Increases the reference count for info by one.
void gnome_vfs_file_info_unref(GnomeVFSFileInfo * info )
Decreases the reference count for info by one; deallocates the structure if that was the last reference count.
void gnome_vfs_file_info_clear(GnomeVFSFileInfo * info )
Clears the fields in info so that you can start filling it with information.
void gnome_vfs_file_info_copy(GnomeVFSFileInfo * dest , const GnomeVFSFileInfo * src )
Copies the fields in src to dest .
GnomeVFSFileInfo *gnome_vfs_file_info_dup(const GnomeVFSFileInfo * info )
Returns a freshly allocated copy of info .
gboolean gnome_vfs_file_info_matches(const GnomeVFSFileInfo * a , const GnomeVFSFileInfo * b )
Returns TRUE if the fields in a and b are equal.
Functions in this section manage existing files and return GnomeVFSResult :
gnome_vfs_unlink(const gchar * uri_string )
Removes (a hard link to) the file at uri_string .
gnome_vfs_unlink_from_uri(GnomeVFSURI * uri )
Same as the preceding function, but with a URI structure uri .
gnome_vfs_move(const gchar * old_name , const gchar * new_name , gboolean force )
Moves the file from URI old_name to new_name . If force is TRUE , this function overwrites any file already at new_name .
gnome_vfs_move_uri(GnomeVFSURI * old_uri , GnomeVFSURI * new_uri , gboolean force )
Same as the preceding function, but with URI structure arguments.
gnome_vfs_create_symbolic_link(GnomeVFSURI * uri , const gchar * target )
Creates a symbolic link at uri that points to target ; you can supply relative paths for target such as ../../example . Remember that target is just a name; it doesn't need to exist.
gnome_vfs_truncate(const gchar * uri_string , GnomeVFSFileSize length )
Truncates the file at uri_string to length bytes.
gnome_vfs_truncate_uri(GnomeVFSFileSize * uri , GnomeVFSFileSize length )
Same as the preceding function, but with the URI structure uri .
gnome_vfs_truncate_handle(GnomeVFSHandle * handle , GnomeVFSFileSize length )
Same as the preceding function, but with the open file descriptor handle .
Now that you can work with files, you are ready to navigate and operate on GnomeVFS directories.