+2007-12-11 David Zeuthen <davidz@redhat.com>
+
+ Rework how volumes, drives and volume monitoring is
+ done. Previosly the model was
+
+ GDrive <1-1> GVolume
+
+ where a GDrive instance represented a mount point and a GVolume
+ instance represented a mounted file system. This patch changes it
+ the model to
+
+ GDrive <1-N> GVolume <1-1> GMount
+
+ where GMount now serves the purpose of the old GVolume and the new
+ GVolume serves the purpose of the old GDrive. In addition the new
+ GDrive interface is used to represent a collection of GVolume
+ instances (typically partitions) and also contains utility to query
+ the state of the physical drive the GDrive object represents (such
+ as checking for media, polling the drive, ejecting the media etc.).
+
+ Also implement mounting and unmounting in the Unix volume monitor
+ backend. A subquent patch will introduce GDrive support for ejection
+ of media.
+
+ * Makefile.am:
+ * gdrive.c: (g_drive_is_media_check_automatic),
+ (g_drive_is_media_removable), (g_drive_has_media),
+ (g_drive_can_poll_for_media), (g_drive_eject),
+ (g_drive_eject_finish), (g_drive_poll_for_media),
+ (g_drive_poll_for_media_finish):
+ * gdrive.h:
+ * gfile.c: (g_file_find_enclosing_mount):
+ * gfile.h:
+ * gio.symbols:
+ * glocaldirectorymonitor.c:
+ (g_local_directory_monitor_constructor), (mounts_changed):
+ * glocalfile.c: (get_mount_info),
+ (g_local_file_find_enclosing_mount),
+ (g_local_file_file_iface_init):
+ * gnativevolumemonitor.h:
+ * gunionvolumemonitor.c: (get_mounts), (get_volumes),
+ (get_connected_drives), (g_union_volume_monitor_class_init),
+ (child_volume_added), (child_volume_removed),
+ (child_volume_changed), (child_mount_added), (child_mount_removed),
+ (child_mount_pre_unmount), (child_mount_changed),
+ (child_drive_changed), (g_union_volume_monitor_add_monitor),
+ (g_union_volume_monitor_remove_monitor),
+ (_g_mount_get_for_mount_path):
+ * gunixmounts.c: (g_unix_is_mount_path_system_internal),
+ (guess_system_internal), (_g_get_unix_mounts),
+ (_g_get_unix_mount_points), (g_get_unix_mount_at),
+ (g_unix_mount_free), (g_unix_mount_compare),
+ (g_unix_mount_get_mount_path), (g_unix_mount_get_device_path),
+ (g_unix_mount_get_fs_type), (g_unix_mount_is_readonly),
+ (g_unix_mount_is_system_internal), (g_unix_mount_guess_type),
+ (type_to_icon), (g_unix_mount_guess_name),
+ (g_unix_mount_guess_icon), (g_unix_mount_point_guess_name),
+ (g_unix_mount_point_guess_icon), (_canonicalize_filename),
+ (_resolve_symlink), (_resolve_dev_root):
+ * gunixmounts.h:
+ * gunixvolume.c: (g_unix_volume_finalize), (_g_unix_volume_new),
+ (_g_unix_volume_disconnected), (_g_unix_volume_set_mount),
+ (_g_unix_volume_unset_mount), (g_unix_volume_get_icon),
+ (g_unix_volume_get_name), (g_unix_volume_can_mount),
+ (g_unix_volume_get_drive), (g_unix_volume_get_mount),
+ (_g_unix_volume_has_mount_path), (mount_cb), (mount_read_error),
+ (g_unix_volume_mount), (g_unix_volume_mount_finish),
+ (g_unix_volume_volume_iface_init):
+ * gunixvolume.h:
+ * gunixvolumemonitor.c: (g_unix_volume_monitor_finalize),
+ (get_mounts), (get_volumes), (get_connected_drives),
+ (get_mount_for_mount_path), (g_unix_volume_monitor_class_init),
+ (mountpoints_changed), (mounts_changed),
+ (g_unix_volume_monitor_init),
+ (_g_unix_volume_monitor_lookup_volume_for_mount_path),
+ (find_mount_by_mountpath), (update_volumes), (update_mounts):
+ * gunixvolumemonitor.h:
+ * gvolume.c: (g_volume_get_mount), (g_volume_can_mount),
+ (g_volume_mount), (g_volume_mount_finish):
+ * gvolume.h:
+ * gvolumemonitor.c: (g_volume_monitor_class_init),
+ (g_volume_monitor_get_connected_drives),
+ (g_volume_monitor_get_volumes), (g_volume_monitor_get_mounts):
+ * gvolumemonitor.h:
+
2007-12-10 Matthias Clasen <mclasen@redhat.com>
* gmountoperation.h (GPasswordFlags): Close the gap
appinfo_sources += gdesktopappinfo.c gdesktopappinfo.h
platform_libadd += xdgmime/libxdgmime.la
unix_sources = \
- gunixdrive.c \
- gunixdrive.h \
+ gunixmount.c \
+ gunixmount.h \
gunixmounts.c \
gunixmounts.h \
gunixvolume.c \
gunixoutputstream.c \
$(NULL)
+
giounixincludedir=$(includedir)/gio-unix-2.0/gio
giounixinclude_HEADERS = \
gdesktopappinfo.h \
giomodule-priv.h \
gioscheduler.c \
gloadableicon.c \
+ gmount.c \
gmemoryinputstream.c \
gmemoryoutputstream.c \
gmountoperation.c \
gvfs.c \
gvolume.c \
gvolumemonitor.c \
- gvolumeprivate.h \
+ gmountprivate.h \
gioenumtypes.h \
gioenumtypes.c \
$(appinfo_sources) \
giomodule.h \
gioscheduler.h \
gloadableicon.h \
+ gmount.h \
gmemoryinputstream.h \
gmemoryoutputstream.h \
gmountoperation.h \
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
* @short_description: Virtual File System drive management
* @include: gio/gdrive.h
*
- * #GDrive manages drive operations from GVFS, including volume mounting
- * and ejecting, and getting the drive's name and icon.
- *
+ * #GDrive is a container class for #GVolume objects that stem from
+ * the same piece of media. As such, #GDrive abstracts a drive with
+ * (or without) removable media and provides operations for querying
+ * whether media is available, determing whether media change is
+ * automatically detected and ejecting the media.
+ *
+ * If the #GDrive reports that media isn't automatically detected, one
+ * can poll for media; typically one should not do this periodically
+ * as a poll for media operation is potententially expensive and may
+ * spin up the drive creating noise.
+ *
+ * For porting from GnomeVFS note that there is no equivalent of
+ * #GDrive in that API.
**/
static void g_drive_base_init (gpointer g_class);
* g_drive_has_volumes:
* @drive: a #GDrive.
*
- * Checks if a drive has any volumes.
+ * Check if @drive has any mountable volumes.
*
- * Returns: %TRUE if @drive contains volumes, %FALSE otherwise.
+ * Returns: %TRUE if the @drive contains volumes, %FALSE otherwise.
**/
gboolean
g_drive_has_volumes (GDrive *drive)
* g_drive_get_volumes:
* @drive: a #GDrive.
*
- * Gets a list of volumes for a drive.
+ * Get a list of mountable volumes for @drive.
*
* Returns: #GList containing any #GVolume<!---->s on the given @drive.
- * <!-- NOTE: Fact-check this. -->
**/
GList *
g_drive_get_volumes (GDrive *drive)
}
/**
- * g_drive_is_automounted:
+ * g_drive_is_media_check_automatic:
* @drive: a #GDrive.
*
- * Checks if a drive was automatically mounted, e.g. by HAL.
+ * Checks if @drive is capabable of automatically detecting media changes.
*
- * Returns: %TRUE if the drive was automounted. %FALSE otherwise.
+ * Returns: %TRUE if the @drive is capabable of automatically detecting media changes, %FALSE otherwise.
**/
gboolean
-g_drive_is_automounted (GDrive *drive)
+g_drive_is_media_check_automatic (GDrive *drive)
{
GDriveIface *iface;
iface = G_DRIVE_GET_IFACE (drive);
- return (* iface->is_automounted) (drive);
+ return (* iface->is_media_check_automatic) (drive);
}
/**
- * g_drive_can_mount:
+ * g_drive_is_media_removable:
* @drive: a #GDrive.
*
- * Checks if a drive can be mounted.
+ * Checks if the @drive supports removable media.
*
- * Returns: %TRUE if the @drive can be mounted. %FALSE otherwise.
+ * Returns: %TRUE if @drive supports removable media, %FALSE otherwise.
**/
gboolean
-g_drive_can_mount (GDrive *drive)
+g_drive_is_media_removable (GDrive *drive)
{
GDriveIface *iface;
iface = G_DRIVE_GET_IFACE (drive);
- if (iface->can_mount == NULL)
- return FALSE;
+ return (* iface->is_media_removable) (drive);
+}
- return (* iface->can_mount) (drive);
+/**
+ * g_drive_has_media:
+ * @drive: a #GDrive.
+ *
+ * Checks if the @drive has media. Note that the OS may not be polling
+ * the drive for media changes; see g_drive_is_media_check_automatic()
+ * for more details.
+ *
+ * Returns: %TRUE if @drive has media, %FALSE otherwise.
+ **/
+gboolean
+g_drive_has_media (GDrive *drive)
+{
+ GDriveIface *iface;
+
+ g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+ iface = G_DRIVE_GET_IFACE (drive);
+
+ return (* iface->has_media) (drive);
}
/**
}
/**
- * g_drive_mount:
+ * g_drive_can_poll_for_media:
+ * @drive: a #GDrive.
+ *
+ * Checks if a drive can be polled for media changes.
+ *
+ * Returns: %TRUE if the @drive can be polled for media changes. %FALSE otherwise.
+ **/
+gboolean
+g_drive_can_poll_for_media (GDrive *drive)
+{
+ GDriveIface *iface;
+
+ g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+ iface = G_DRIVE_GET_IFACE (drive);
+
+ if (iface->poll_for_media == NULL)
+ return FALSE;
+
+ return (* iface->can_poll_for_media) (drive);
+}
+
+/**
+ * g_drive_eject:
* @drive: a #GDrive.
- * @mount_operation: a #GMountOperation.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback.
* @user_data: a #gpointer.
*
- * Mounts a drive.
+ * Ejects a drive.
+ *
**/
void
-g_drive_mount (GDrive *drive,
- GMountOperation *mount_operation,
+g_drive_eject (GDrive *drive,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
GDriveIface *iface;
g_return_if_fail (G_IS_DRIVE (drive));
- g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
iface = G_DRIVE_GET_IFACE (drive);
- if (iface->mount_fn == NULL)
+ if (iface->eject == NULL)
{
g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("drive doesn't implement mount"));
+ _("drive doesn't implement eject"));
return;
}
- (* iface->mount_fn) (drive, mount_operation, cancellable, callback, user_data);
+ (* iface->eject) (drive, cancellable, callback, user_data);
}
/**
- * g_drive_mount_finish:
+ * g_drive_eject_finish
* @drive: a #GDrive.
* @result: a #GAsyncResult.
* @error: a #GError.
*
- * Finishes mounting a drive.
- *
- * If the @drive's interface does not implement the mount operation, @error will
- * be set to %G_IO_ERROR_NOT_SUPPORTED and %FALSE will be returned.
+ * Finishes ejecting a drive.
*
- * Returns: %TRUE if the mount was finished successfully,
- * %FALSE if operation failed.
+ * Returns: %TRUE if the drive has been ejected successfully,
+ * %FALSE otherwise.
**/
gboolean
-g_drive_mount_finish (GDrive *drive,
+g_drive_eject_finish (GDrive *drive,
GAsyncResult *result,
GError **error)
{
}
iface = G_DRIVE_GET_IFACE (drive);
- return (* iface->mount_finish) (drive, result, error);
+
+ return (* iface->eject_finish) (drive, result, error);
}
/**
- * g_drive_eject:
+ * g_drive_poll_for_media:
* @drive: a #GDrive.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback.
* @user_data: a #gpointer.
*
- * Ejects a drive.
+ * Polls @drive to see if media has been inserted or removed.
*
**/
void
-g_drive_eject (GDrive *drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+g_drive_poll_for_media (GDrive *drive,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GDriveIface *iface;
iface = G_DRIVE_GET_IFACE (drive);
- if (iface->eject == NULL)
+ if (iface->poll_for_media == NULL)
{
g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("drive doesn't implement eject"));
+ _("drive doesn't implement polling for media"));
return;
}
- (* iface->eject) (drive, cancellable, callback, user_data);
+ (* iface->poll_for_media) (drive, cancellable, callback, user_data);
}
/**
- * g_drive_eject_finish
+ * g_drive_poll_for_media_finish
* @drive: a #GDrive.
* @result: a #GAsyncResult.
* @error: a #GError.
*
- * Finishes ejecting a drive.
- *
- * If @drive's interface does not implement the eject operation, @error will
- * be set to %G_IO_ERROR_NOT_SUPPORTED and %FALSE will be returned.
+ * Finishes poll_for_mediaing a drive.
*
- * Returns: %TRUE if the drive has been ejected successfully,
+ * Returns: %TRUE if the drive has been poll_for_mediaed successfully,
* %FALSE otherwise.
**/
gboolean
-g_drive_eject_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
+g_drive_poll_for_media_finish (GDrive *drive,
+ GAsyncResult *result,
+ GError **error)
{
GDriveIface *iface;
iface = G_DRIVE_GET_IFACE (drive);
- return (* iface->mount_finish) (drive, result, error);
+ return (* iface->poll_for_media_finish) (drive, result, error);
}
#define __G_DRIVE_C__
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#ifndef __G_DRIVE_H__
#define __G_DRIVE_H__
#include <glib-object.h>
+#include <gio/gmount.h>
#include <gio/gvolume.h>
#include <gio/gmountoperation.h>
* @get_name: Returns the name for the given #GDrive.
* @get_icon: Returns a #GIcon for the given #GDrive.
* @has_volumes: Returns %TRUE if the #GDrive has mountable volumes.
- * @get_volumes: Returns a #GList of volumes for the #GDrive.
- * @is_automounted: returns %TRUE if the #GDrive was automounted.
- * @can_mount: Returns %TRUE if the #GDrive can be mounted.
- * @can_eject: Returns %TRUE if the #GDrive can be ejected.
- * @mount_fn: Mounts a given #GDrive.
- * @mount_finish: Finishes a mount operation.
+ * @get_volumes: Returns a list #GList of #GVolume for the #GDrive.
+ * @is_media_removable: Returns %TRUE if the #GDrive supports removal and insertion of media.
+ * @has_media: Returns %TRUE if the #GDrive has media inserted.
+ * @is_media_check_automatic: Returns %TRUE if the #GDrive is capabable of automatically detecting media changes.
+ * @can_poll_for_media: Returns %TRUE if the #GDrive is capable of manually polling for media change.
+ * @can_eject: Returns %TRUE if the #GDrive can eject media.
* @eject: Ejects a #GDrive.
* @eject_finish: Finishes an eject operation.
+ * @poll_for_media: Poll for media insertion/removal on a #GDrive.
+ * @poll_for_media_finish: Finishes a media poll operation.
*
* Interface for creating #GDrive implementations.
*/
GTypeInterface g_iface;
/* signals */
- void (*changed) (GVolume *volume);
+ void (*changed) (GDrive *drive);
/* Virtual Table */
-
- char * (*get_name) (GDrive *drive);
- GIcon * (*get_icon) (GDrive *drive);
- gboolean (*has_volumes) (GDrive *drive);
- GList * (*get_volumes) (GDrive *drive);
- gboolean (*is_automounted)(GDrive *drive);
- gboolean (*can_mount) (GDrive *drive);
- gboolean (*can_eject) (GDrive *drive);
- void (*mount_fn) (GDrive *drive,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gboolean (*mount_finish)(GDrive *drive,
- GAsyncResult *result,
- GError **error);
- void (*eject) (GDrive *drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gboolean (*eject_finish)(GDrive *drive,
- GAsyncResult *result,
- GError **error);
+ char * (*get_name) (GDrive *drive);
+ GIcon * (*get_icon) (GDrive *drive);
+ gboolean (*has_volumes) (GDrive *drive);
+ GList * (*get_volumes) (GDrive *drive);
+ gboolean (*is_media_removable) (GDrive *drive);
+ gboolean (*has_media) (GDrive *drive);
+ gboolean (*is_media_check_automatic) (GDrive *drive);
+ gboolean (*can_eject) (GDrive *drive);
+ gboolean (*can_poll_for_media) (GDrive *drive);
+ void (*eject) (GDrive *drive,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*eject_finish) (GDrive *drive,
+ GAsyncResult *result,
+ GError **error);
+ void (*poll_for_media) (GDrive *drive,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*poll_for_media_finish) (GDrive *drive,
+ GAsyncResult *result,
+ GError **error);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_g_reserved1) (void);
+ void (*_g_reserved2) (void);
+ void (*_g_reserved3) (void);
+ void (*_g_reserved4) (void);
+ void (*_g_reserved5) (void);
+ void (*_g_reserved6) (void);
+ void (*_g_reserved7) (void);
+ void (*_g_reserved8) (void);
};
-GType g_drive_get_type (void) G_GNUC_CONST;
+GType g_drive_get_type (void) G_GNUC_CONST;
-char * g_drive_get_name (GDrive *drive);
-GIcon * g_drive_get_icon (GDrive *drive);
-gboolean g_drive_has_volumes (GDrive *drive);
-GList * g_drive_get_volumes (GDrive *drive);
-gboolean g_drive_is_automounted (GDrive *drive);
-gboolean g_drive_can_mount (GDrive *drive);
-gboolean g_drive_can_eject (GDrive *drive);
-void g_drive_mount (GDrive *drive,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean g_drive_mount_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error);
-void g_drive_eject (GDrive *drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean g_drive_eject_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error);
+char * g_drive_get_name (GDrive *drive);
+GIcon * g_drive_get_icon (GDrive *drive);
+gboolean g_drive_has_volumes (GDrive *drive);
+GList * g_drive_get_volumes (GDrive *drive);
+gboolean g_drive_is_media_removable (GDrive *drive);
+gboolean g_drive_has_media (GDrive *drive);
+gboolean g_drive_is_media_check_automatic (GDrive *drive);
+gboolean g_drive_can_poll_for_media (GDrive *drive);
+gboolean g_drive_can_eject (GDrive *drive);
+void g_drive_eject (GDrive *drive,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean g_drive_eject_finish (GDrive *drive,
+ GAsyncResult *result,
+ GError **error);
+void g_drive_poll_for_media (GDrive *drive,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean g_drive_poll_for_media_finish (GDrive *drive,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
}
/**
- * g_file_find_enclosing_volume:
+ * g_file_find_enclosing_mount:
* @file: input #GFile.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @error: a #GError.
*
- * Gets a #GVolume for the #GFile.
+ * Gets a #GMount for the #GFile.
*
- * If the #GFileIface for @file does not have a volume (e.g. possibly a
+ * If the #GFileIface for @file does not have a mount (e.g. possibly a
* remote share), @error will be set to %G_IO_ERROR_NOT_FOUND and %NULL
* will be returned.
*
* triggering the cancellable object from another thread. If the operation
* was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
*
- * Returns: a #GVolume where the @file is located or %NULL on error.
+ * Returns: a #GMount where the @file is located or %NULL on error.
**/
-GVolume *
-g_file_find_enclosing_volume (GFile *file,
+GMount *
+g_file_find_enclosing_mount (GFile *file,
GCancellable *cancellable,
GError **error)
{
return NULL;
iface = G_FILE_GET_IFACE (file);
- if (iface->find_enclosing_volume == NULL)
+ if (iface->find_enclosing_mount == NULL)
{
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
- return (* iface->find_enclosing_volume) (file, cancellable, error);
+ return (* iface->find_enclosing_mount) (file, cancellable, error);
}
/**
typedef struct _GFileMonitor GFileMonitor;
/**
- * GVolume:
+ * GMount:
*
- * A handle to an object implementing the #GVolumeIface interface.
+ * A handle to an object implementing the #GMountIface interface.
**/
-typedef struct _GVolume GVolume; /* Dummy typedef */
+typedef struct _GMount GMount; /* Dummy typedef */
/**
* GFileProgressCallback:
* @query_filesystem_info: Gets a #GFileInfo for the file system #GFile is on.
* @_query_filesystem_info_async: Asynchronously gets a #GFileInfo for the file system #GFile is on.
* @_query_filesystem_info_finish: Finishes asynchronously getting the file system info.
- * @find_enclosing_volume: Gets a #GVolume for the #GFile.
- * @find_enclosing_volume_async: Asynchronously gets the #GVolume for a #GFile.
- * @find_enclosing_volume_finish: Finishes asynchronously getting the volume.
+ * @find_enclosing_mount: Gets a #GMount for the #GFile.
+ * @find_enclosing_mount_async: Asynchronously gets the #GMount for a #GFile.
+ * @find_enclosing_mount_finish: Finishes asynchronously getting the volume.
* @set_display_name: Sets the display name for a #GFile.
* @set_display_name_async: Asynchronously sets a #GFile's display name.
* @set_display_name_finish: Finishes asynchronously setting a #GFile's display name.
void (*_query_filesystem_info_async) (void);
void (*_query_filesystem_info_finish) (void);
- GVolume * (*find_enclosing_volume)(GFile *file,
+ GMount * (*find_enclosing_mount)(GFile *file,
GCancellable *cancellable,
GError **error);
- void (*find_enclosing_volume_async)(GFile *file,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- GVolume * (*find_enclosing_volume_finish)(GFile *file,
- GAsyncResult *res,
- GError **error);
+ void (*find_enclosing_mount_async)(GFile *file,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ GMount * (*find_enclosing_mount_finish)(GFile *file,
+ GAsyncResult *res,
+ GError **error);
GFile * (*set_display_name) (GFile *file,
const char *display_name,
const char *attributes,
GCancellable *cancellable,
GError **error);
-GVolume * g_file_find_enclosing_volume (GFile *file,
- GCancellable *cancellable,
- GError **error);
+GMount * g_file_find_enclosing_mount (GFile *file,
+ GCancellable *cancellable,
+ GError **error);
GFileEnumerator * g_file_enumerate_children (GFile *file,
const char *attributes,
GFileQueryInfoFlags flags,
g_drive_get_icon
g_drive_has_volumes
g_drive_get_volumes
-g_drive_is_automounted
-g_drive_can_mount
+g_drive_is_media_removable
+g_drive_has_media
+g_drive_is_media_check_automatic
+g_drive_can_poll_for_media
g_drive_can_eject
-g_drive_mount
-g_drive_mount_finish
g_drive_eject
g_drive_eject_finish
+g_drive_poll_for_media
+g_drive_poll_for_media_finish
#endif
#endif
g_file_query_info_async
g_file_query_info_finish
g_file_query_filesystem_info
-g_file_find_enclosing_volume
+g_file_find_enclosing_mount
g_file_enumerate_children
g_file_enumerate_children_async
g_file_enumerate_children_finish
g_unix_mount_get_fs_type
g_unix_mount_is_readonly
g_unix_mount_is_system_internal
-g_unix_mount_guess_type
+g_unix_mount_guess_name
+g_unix_mount_guess_icon
g_unix_mount_point_compare
g_unix_mount_point_get_mount_path
g_unix_mount_point_get_device_path
g_unix_mount_point_is_readonly
g_unix_mount_point_is_user_mountable
g_unix_mount_point_is_loopback
-g_unix_mount_point_guess_type
+g_unix_mount_point_guess_name
+g_unix_mount_point_guess_icon
g_get_unix_mount_points
g_get_unix_mounts
g_get_unix_mount_at
g_unix_mount_points_changed_since
g_unix_mount_monitor_get_type G_GNUC_CONST
g_unix_mount_monitor_new
+g_unix_is_mount_path_system_internal
#endif /* G_OS_UNIX */
#endif
#endif
#endif
#endif
+#if IN_HEADER(__G_MOUNT_H__)
+#if IN_FILE(__G_MOUNT_C__)
+g_mount_get_type G_GNUC_CONST
+g_mount_get_root
+g_mount_get_name
+g_mount_get_icon
+g_mount_get_volume
+g_mount_get_drive
+g_mount_can_unmount
+g_mount_unmount
+g_mount_unmount_finish
+#endif
+#endif
+
#if IN_HEADER(__G_VOLUME_H__)
#if IN_FILE(__G_VOLUME_C__)
g_volume_get_type G_GNUC_CONST
-g_volume_get_root
g_volume_get_name
g_volume_get_icon
g_volume_get_drive
-g_volume_can_unmount
-g_volume_can_eject
-g_volume_unmount
-g_volume_unmount_finish
-g_volume_eject
-g_volume_eject_finish
+g_volume_get_mount
+g_volume_can_mount
+g_volume_mount
+g_volume_mount_finish
#endif
#endif
#if IN_HEADER(__G_VOLUME_MONITOR_H__)
#if IN_FILE(__G_VOLUME_MONITOR_C__)
g_volume_monitor_get_type G_GNUC_CONST
-g_volume_monitor_get_mounted_volumes
g_volume_monitor_get_connected_drives
+g_volume_monitor_get_volumes
+g_volume_monitor_get_mounts
#endif
#if IN_FILE(__G_UNION_VOLUME_MONITOR_C__)
g_volume_monitor_get
#ifdef G_OS_WIN32
g_warning ("G_OS_WIN32: no mount emulation");
#else
- GUnixMount *mount;
+ GUnixMountEntry *mount;
/* Emulate unmount detection */
gpointer user_data)
{
GLocalDirectoryMonitor *local_monitor = user_data;
- GUnixMount *mount;
+ GUnixMountEntry *mount;
gboolean is_mounted;
GFile *file;
#include "glocalfileoutputstream.h"
#include "glocaldirectorymonitor.h"
#include "glocalfilemonitor.h"
-#include "gvolumeprivate.h"
+#include "gmountprivate.h"
#include <glib/gstdio.h>
#include "glibintl.h"
guint mount_info;
char *mountpoint;
dev_t *dev;
- GUnixMount *mount;
+ GUnixMountEntry *mount;
guint64 cache_time;
if (g_lstat (path, &buf) != 0)
return info;
}
-static GVolume *
-g_local_file_find_enclosing_volume (GFile *file,
- GCancellable *cancellable,
- GError **error)
+static GMount *
+g_local_file_find_enclosing_mount (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
struct stat buf;
char *mountpoint;
- GVolume *volume;
+ GMount *mount;
if (g_lstat (local->filename, &buf) != 0)
{
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
{
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
- volume = _g_volume_get_for_mount_path (mountpoint);
+ mount = _g_mount_get_for_mount_path (mountpoint);
g_free (mountpoint);
- if (volume)
- return volume;
+ if (mount)
+ return mount;
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
- _("Containing volume does not exist"));
+ _("Containing mount does not exist"));
return NULL;
}
iface->enumerate_children = g_local_file_enumerate_children;
iface->query_info = g_local_file_query_info;
iface->query_filesystem_info = g_local_file_query_filesystem_info;
- iface->find_enclosing_volume = g_local_file_find_enclosing_volume;
+ iface->find_enclosing_mount = g_local_file_find_enclosing_mount;
iface->query_settable_attributes = g_local_file_query_settable_attributes;
iface->query_writable_namespaces = g_local_file_query_writable_namespaces;
iface->set_attribute = g_local_file_set_attribute;
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
+ */
+
+#include <config.h>
+#include "gmount.h"
+#include "gmountprivate.h"
+#include "gsimpleasyncresult.h"
+#include "glibintl.h"
+
+#include "gioalias.h"
+
+/**
+ * SECTION:gmount
+ * @short_description: mount management
+ *
+ * The #GMount interface represents user-visible mounts. Note, when
+ * porting from GnomeVFS, #GMount is the moral equivalent of
+ * #GnomeVFSVolume.
+ *
+ * Unmounting a #GMount instance is an asynchronous operation. For
+ * more information about asynchronous operations, see #GAsyncReady
+ * and #GSimpleAsyncReady. To unmount a #GMount instance, first call
+ * g_mount_unmount() with (at least) the #GMount instance and a
+ * #GAsyncReadyCallback. The callback will be fired when the
+ * operation has resolved (either with success or failure), and a
+ * #GAsyncReady structure will be passed to the callback. That
+ * callback should then call g_mount_unmount_finish() with the #GMount
+ * and the #GAsyncReady data to see if the operation was completed
+ * successfully. If an @error is present when
+ * g_mount_unmount_finish() is called, then it will be filled with any
+ * error information.
+ **/
+
+static void g_mount_base_init (gpointer g_class);
+static void g_mount_class_init (gpointer g_class,
+ gpointer class_data);
+
+GType
+g_mount_get_type (void)
+{
+ static GType mount_type = 0;
+
+ if (! mount_type)
+ {
+ static const GTypeInfo mount_info =
+ {
+ sizeof (GMountIface), /* class_size */
+ g_mount_base_init, /* base_init */
+ NULL, /* base_finalize */
+ g_mount_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ mount_type =
+ g_type_register_static (G_TYPE_INTERFACE, I_("GMount"),
+ &mount_info, 0);
+
+ g_type_interface_add_prerequisite (mount_type, G_TYPE_OBJECT);
+ }
+
+ return mount_type;
+}
+
+static void
+g_mount_class_init (gpointer g_class,
+ gpointer class_data)
+{
+}
+
+static void
+g_mount_base_init (gpointer g_class)
+{
+ static gboolean initialized = FALSE;
+
+ if (! initialized)
+ {
+ /**
+ * GMount::changed:
+ *
+ * Emitted when the mount has been changed.
+ **/
+ g_signal_new (I_("changed"),
+ G_TYPE_MOUNT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GMountIface, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ initialized = TRUE;
+ }
+}
+
+/**
+ * g_mount_get_root:
+ * @mount: a #GMount.
+ *
+ * Gets the root directory on @mount.
+ *
+ * Returns: a #GFile.
+ **/
+GFile *
+g_mount_get_root (GMount *mount)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ return (* iface->get_root) (mount);
+}
+
+/**
+ * g_mount_get_name:
+ * @mount: a #GMount.
+ *
+ * Gets the name of @mount.
+ *
+ * Returns: the name for the given @mount. The returned string should
+ * be freed when no longer needed.
+ **/
+char *
+g_mount_get_name (GMount *mount)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ return (* iface->get_name) (mount);
+}
+
+/**
+ * g_mount_get_icon:
+ * @mount: a #GMount.
+ *
+ * Gets the icon for @mount.
+ *
+ * Returns: a #GIcon.
+ **/
+GIcon *
+g_mount_get_icon (GMount *mount)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ return (* iface->get_icon) (mount);
+}
+
+/**
+ * g_mount_get_volume:
+ * @mount: a #GMount.
+ *
+ * Gets the volume for the @mount.
+ *
+ * Returns: a #GVolume or %NULL if @mount is not associated with a volume.
+ **/
+GVolume *
+g_mount_get_volume (GMount *mount)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ return (* iface->get_volume) (mount);
+}
+
+/**
+ * g_mount_get_drive:
+ * @mount: a #GMount.
+ *
+ * Gets the drive for the @mount.
+ *
+ * This is a convenience method for getting the #GVolume and then
+ * using that object to get the #GDrive.
+ *
+ * Returns: a #GDrive or %NULL if @mount is not associated with a volume or a drive.
+ **/
+GDrive *
+g_mount_get_drive (GMount *mount)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ return (* iface->get_drive) (mount);
+}
+
+/**
+ * g_mount_can_unmount:
+ * @mount: a #GMount.
+ *
+ * Checks if @mount can be mounted.
+ *
+ * Returns: %TRUE if the @mount can be unmounted.
+ **/
+gboolean
+g_mount_can_unmount (GMount *mount)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ return (* iface->can_unmount) (mount);
+}
+
+/**
+ * g_mount_unmount:
+ * @mount: a #GMount.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback.
+ * @user_data: user data passed to @callback.
+ *
+ * Unmounts a mount. This is an asynchronous operation, and is
+ * finished by calling g_mount_unmount_finish() with the @mount
+ * and #GAsyncResults data returned in the @callback.
+ **/
+void
+g_mount_unmount (GMount *mount,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GMountIface *iface;
+
+ g_return_if_fail (G_IS_MOUNT (mount));
+
+ iface = G_MOUNT_GET_IFACE (mount);
+
+ if (iface->unmount == NULL)
+ {
+ g_simple_async_report_error_in_idle (G_OBJECT (mount),
+ callback, user_data,
+ G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("mount doesn't implement unmount"));
+
+ return;
+ }
+
+ (* iface->unmount) (mount, cancellable, callback, user_data);
+}
+
+/**
+ * g_mount_unmount_finish:
+ * @mount: a #GMount.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ * ignore.
+ *
+ * Finishes unmounting a mount. If any errors occured during the operation,
+ * @error will be set to contain the errors and %FALSE will be returned.
+ *
+ * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
+ **/
+gboolean
+g_mount_unmount_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ GMountIface *iface;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ if (G_IS_SIMPLE_ASYNC_RESULT (result))
+ {
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+ }
+
+ iface = G_MOUNT_GET_IFACE (mount);
+ return (* iface->unmount_finish) (mount, result, error);
+}
+
+#define __G_MOUNT_C__
+#include "gioaliasdef.c"
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
+ */
+
+#ifndef __G_MOUNT_H__
+#define __G_MOUNT_H__
+
+#include <glib-object.h>
+#include <gio/gfile.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_MOUNT (g_mount_get_type ())
+#define G_MOUNT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_MOUNT, GMount))
+#define G_IS_MOUNT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_MOUNT))
+#define G_MOUNT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_MOUNT, GMountIface))
+
+/* GMount typedef is in gfile.h due to include order issues */
+/**
+ * GVolume:
+ *
+ * Opaque mountable volume object.
+ **/
+typedef struct _GVolume GVolume; /* Dummy typedef */
+
+/**
+ * GDrive:
+ *
+ * Opaque drive object.
+ **/
+typedef struct _GDrive GDrive; /* Dummy typedef */
+
+typedef struct _GMountIface GMountIface;
+
+/**
+ * GMountIface:
+ * @g_iface: The parent interface.
+ * @changed: Changed signal that is emitted when the mount's state has changed.
+ * @get_root: Gets a #GFile to the root directory of the #GMount.
+ * @get_name: Gets a string containing the name of the #GMount.
+ * @get_icon: Gets a #GIcon for the #GMount.
+ * @get_volume: Gets a #GVolume the mount is located on. Returns %NULL if the #GMount is not associated with a #GVolume.
+ * @get_drive: Gets a #GDrive the volume of the mount is located on. Returns %NULL if the #GMount is not associated with a #GDrive or a #GVolume. This is convenience method for getting the #GVolume and using that to get the #GDrive.
+ * @can_unmount: Checks if a #GMount can be unmounted.
+ * @unmount: Starts unmounting a #GMount.
+ * @unmount_finish: Finishes an unmounting operation.
+ *
+ * Interface for implementing operations for mounts.
+ **/
+struct _GMountIface
+{
+ GTypeInterface g_iface;
+
+ /* signals */
+
+ void (*changed) (GMount *mount);
+
+ /* Virtual Table */
+
+ GFile * (*get_root) (GMount *mount);
+ char * (*get_name) (GMount *mount);
+ GIcon * (*get_icon) (GMount *mount);
+ GVolume * (*get_volume) (GMount *mount);
+ GDrive * (*get_drive) (GMount *mount);
+ gboolean (*can_unmount) (GMount *mount);
+ void (*unmount) (GMount *mount,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*unmount_finish) (GMount *mount,
+ GAsyncResult *result,
+ GError **error);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_g_reserved1) (void);
+ void (*_g_reserved2) (void);
+ void (*_g_reserved3) (void);
+ void (*_g_reserved4) (void);
+ void (*_g_reserved5) (void);
+ void (*_g_reserved6) (void);
+ void (*_g_reserved7) (void);
+ void (*_g_reserved8) (void);
+};
+
+GType g_mount_get_type (void) G_GNUC_CONST;
+
+GFile * g_mount_get_root (GMount *mount);
+char * g_mount_get_name (GMount *mount);
+GIcon * g_mount_get_icon (GMount *mount);
+GVolume * g_mount_get_volume (GMount *mount);
+GDrive * g_mount_get_drive (GMount *mount);
+gboolean g_mount_can_unmount (GMount *mount);
+void g_mount_unmount (GMount *mount,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean g_mount_unmount_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __G_MOUNT_H__ */
G_BEGIN_DECLS
-GVolume *_g_volume_get_for_mount_path (const char *mountpoint);
+GMount *_g_mount_get_for_mount_path (const char *mount_path);
G_END_DECLS
struct _GNativeVolumeMonitorClass {
GVolumeMonitorClass parent_class;
- GVolume * (*get_volume_for_mountpoint) (const char *mountpoint);
+ GMount * (*get_mount_for_mount_path) (const char *mount_path);
int priority;
};
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
#include <glib.h>
#include "gunionvolumemonitor.h"
-#include "gvolumeprivate.h"
+#include "gmountprivate.h"
#include "giomodule-priv.h"
#ifdef G_OS_UNIX
#include "gunixvolumemonitor.h"
}
static GList *
-get_mounted_volumes (GVolumeMonitor *volume_monitor)
+get_mounts (GVolumeMonitor *volume_monitor)
{
GUnionVolumeMonitor *monitor;
GVolumeMonitor *child_monitor;
{
child_monitor = l->data;
- res = g_list_concat (res,
- g_volume_monitor_get_mounted_volumes (child_monitor));
+ res = g_list_concat (res, g_volume_monitor_get_mounts (child_monitor));
+ }
+
+ G_UNLOCK (the_volume_monitor);
+
+ return res;
+}
+
+static GList *
+get_volumes (GVolumeMonitor *volume_monitor)
+{
+ GUnionVolumeMonitor *monitor;
+ GVolumeMonitor *child_monitor;
+ GList *res;
+ GList *l;
+
+ monitor = G_UNION_VOLUME_MONITOR (volume_monitor);
+
+ res = NULL;
+
+ G_LOCK (the_volume_monitor);
+
+ for (l = monitor->monitors; l != NULL; l = l->next)
+ {
+ child_monitor = l->data;
+
+ res = g_list_concat (res, g_volume_monitor_get_volumes (child_monitor));
}
G_UNLOCK (the_volume_monitor);
{
child_monitor = l->data;
- res = g_list_concat (res,
- g_volume_monitor_get_connected_drives (child_monitor));
+ res = g_list_concat (res, g_volume_monitor_get_connected_drives (child_monitor));
}
G_UNLOCK (the_volume_monitor);
gobject_class->finalize = g_union_volume_monitor_finalize;
gobject_class->dispose = g_union_volume_monitor_dispose;
- monitor_class->get_mounted_volumes = get_mounted_volumes;
monitor_class->get_connected_drives = get_connected_drives;
+ monitor_class->get_volumes = get_volumes;
+ monitor_class->get_mounts = get_mounts;
}
static void
-child_volume_mounted (GVolumeMonitor *child_monitor,
- GVolume *child_volume,
- GUnionVolumeMonitor *union_monitor)
+child_volume_added (GVolumeMonitor *child_monitor,
+ GVolume *child_volume,
+ GUnionVolumeMonitor *union_monitor)
{
g_signal_emit_by_name (union_monitor,
- "volume_mounted",
+ "volume_added",
child_volume);
}
static void
-child_volume_pre_unmount (GVolumeMonitor *child_monitor,
- GVolume *child_volume,
- GUnionVolumeMonitor *union_monitor)
+child_volume_removed (GVolumeMonitor *child_monitor,
+ GVolume *child_volume,
+ GUnionVolumeMonitor *union_monitor)
{
g_signal_emit_by_name (union_monitor,
- "volume_pre_unmount",
+ "volume_removed",
child_volume);
}
static void
-child_volume_unmounted (GVolumeMonitor *child_monitor,
- GVolume *child_volume,
- GUnionVolumeMonitor *union_monitor)
+child_volume_changed (GVolumeMonitor *child_monitor,
+ GVolume *child_volume,
+ GUnionVolumeMonitor *union_monitor)
{
g_signal_emit_by_name (union_monitor,
- "volume_unmounted",
+ "volume_changed",
child_volume);
}
static void
+child_mount_added (GVolumeMonitor *child_monitor,
+ GMount *child_mount,
+ GUnionVolumeMonitor *union_monitor)
+{
+ g_signal_emit_by_name (union_monitor,
+ "mount_added",
+ child_mount);
+}
+
+static void
+child_mount_removed (GVolumeMonitor *child_monitor,
+ GMount *child_mount,
+ GUnionVolumeMonitor *union_monitor)
+{
+ g_signal_emit_by_name (union_monitor,
+ "mount_removed",
+ child_mount);
+}
+
+static void
+child_mount_pre_unmount (GVolumeMonitor *child_monitor,
+ GMount *child_mount,
+ GUnionVolumeMonitor *union_monitor)
+{
+ g_signal_emit_by_name (union_monitor,
+ "mount_pre_unmount",
+ child_mount);
+}
+
+
+static void
+child_mount_changed (GVolumeMonitor *child_monitor,
+ GMount *child_mount,
+ GUnionVolumeMonitor *union_monitor)
+{
+ g_signal_emit_by_name (union_monitor,
+ "mount_changed",
+ child_mount);
+}
+
+static void
child_drive_connected (GVolumeMonitor *child_monitor,
GDrive *child_drive,
GUnionVolumeMonitor *union_monitor)
}
static void
+child_drive_changed (GVolumeMonitor *child_monitor,
+ GDrive *child_drive,
+ GUnionVolumeMonitor *union_monitor)
+{
+ g_signal_emit_by_name (union_monitor,
+ "drive_changed",
+ child_drive);
+}
+
+static void
g_union_volume_monitor_add_monitor (GUnionVolumeMonitor *union_monitor,
GVolumeMonitor *volume_monitor)
{
g_list_prepend (union_monitor->monitors,
g_object_ref (volume_monitor));
- g_signal_connect (volume_monitor, "volume_mounted", (GCallback)child_volume_mounted, union_monitor);
- g_signal_connect (volume_monitor, "volume_pre_unmount", (GCallback)child_volume_pre_unmount, union_monitor);
- g_signal_connect (volume_monitor, "volume_unmounted", (GCallback)child_volume_unmounted, union_monitor);
+ g_signal_connect (volume_monitor, "volume_added", (GCallback)child_volume_added, union_monitor);
+ g_signal_connect (volume_monitor, "volume_removed", (GCallback)child_volume_removed, union_monitor);
+ g_signal_connect (volume_monitor, "volume_changed", (GCallback)child_volume_changed, union_monitor);
+ g_signal_connect (volume_monitor, "mount_added", (GCallback)child_mount_added, union_monitor);
+ g_signal_connect (volume_monitor, "mount_removed", (GCallback)child_mount_removed, union_monitor);
+ g_signal_connect (volume_monitor, "mount_pre_unmount", (GCallback)child_mount_pre_unmount, union_monitor);
+ g_signal_connect (volume_monitor, "mount_changed", (GCallback)child_mount_changed, union_monitor);
g_signal_connect (volume_monitor, "drive_connected", (GCallback)child_drive_connected, union_monitor);
g_signal_connect (volume_monitor, "drive_disconnected", (GCallback)child_drive_disconnected, union_monitor);
+ g_signal_connect (volume_monitor, "drive_changed", (GCallback)child_drive_changed, union_monitor);
}
static void
union_monitor->monitors = g_list_delete_link (union_monitor->monitors, l);
- g_signal_handlers_disconnect_by_func (child_monitor, child_volume_mounted, union_monitor);
- g_signal_handlers_disconnect_by_func (child_monitor, child_volume_pre_unmount, union_monitor);
- g_signal_handlers_disconnect_by_func (child_monitor, child_volume_unmounted, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_volume_added, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_volume_removed, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_volume_changed, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_mount_added, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_mount_removed, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_mount_pre_unmount, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_mount_changed, union_monitor);
g_signal_handlers_disconnect_by_func (child_monitor, child_drive_connected, union_monitor);
g_signal_handlers_disconnect_by_func (child_monitor, child_drive_disconnected, union_monitor);
+ g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor);
}
static gpointer
}
/**
- * g_volume_get_for_mount_path:
+ * _g_mount_get_for_mount_path:
* @mountpoint: a string.
*
- * Returns: a #GVolume for given @mountpoint or %NULL.
+ * Returns: a #GMount for given @mount_path or %NULL.
**/
-GVolume *
-_g_volume_get_for_mount_path (const char *mountpoint)
+GMount *
+_g_mount_get_for_mount_path (const char *mount_path)
{
GType native_type;
GNativeVolumeMonitorClass *klass;
- GVolume *volume;
+ GMount *mount;
native_type = get_native_type ();
if (native_type == G_TYPE_INVALID)
return NULL;
- volume = NULL;
+ mount = NULL;
klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (native_type));
- if (klass->get_volume_for_mountpoint)
- volume = klass->get_volume_for_mountpoint (mountpoint);
+ if (klass->get_mount_for_mount_path)
+ mount = klass->get_mount_for_mount_path (mount_path);
g_type_class_unref (klass);
- return volume;
+ return mount;
}
#define __G_UNION_VOLUME_MONITOR_C__
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#ifndef __G_UNION_VOLUME_MONITOR_H__
+++ /dev/null
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <glib.h>
-#include "gunixdrive.h"
-#include "gunixvolume.h"
-#include "gthemedicon.h"
-#include "gvolumemonitor.h"
-#include "glibintl.h"
-
-#include "gioalias.h"
-
-struct _GUnixDrive {
- GObject parent;
-
- GUnixVolume *volume; /* owned by volume monitor */
- char *name;
- char *icon;
- char *mountpoint;
- GUnixMountType guessed_type;
-};
-
-static void g_unix_volume_drive_iface_init (GDriveIface *iface);
-
-#define g_unix_drive_get_type _g_unix_drive_get_type
-G_DEFINE_TYPE_WITH_CODE (GUnixDrive, g_unix_drive, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_DRIVE,
- g_unix_volume_drive_iface_init))
-
-static void
-g_unix_drive_finalize (GObject *object)
-{
- GUnixDrive *drive;
-
- drive = G_UNIX_DRIVE (object);
-
- if (drive->volume)
- _g_unix_volume_unset_drive (drive->volume, drive);
-
- g_free (drive->name);
- g_free (drive->icon);
- g_free (drive->mountpoint);
-
- if (G_OBJECT_CLASS (g_unix_drive_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_unix_drive_parent_class)->finalize) (object);
-}
-
-static void
-g_unix_drive_class_init (GUnixDriveClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = g_unix_drive_finalize;
-}
-
-static void
-g_unix_drive_init (GUnixDrive *unix_drive)
-{
-}
-
-static char *
-type_to_icon (GUnixMountType type)
-{
- const char *icon_name = NULL;
-
- switch (type)
- {
- case G_UNIX_MOUNT_TYPE_HD:
- icon_name = "drive-harddisk";
- break;
- case G_UNIX_MOUNT_TYPE_FLOPPY:
- case G_UNIX_MOUNT_TYPE_ZIP:
- case G_UNIX_MOUNT_TYPE_JAZ:
- case G_UNIX_MOUNT_TYPE_MEMSTICK:
- icon_name = "drive-removable-media";
- break;
- case G_UNIX_MOUNT_TYPE_CDROM:
- icon_name = "drive-optical";
- break;
- case G_UNIX_MOUNT_TYPE_NFS:
- /* TODO: Would like a better icon here... */
- icon_name = "drive-removable-media";
- break;
- case G_UNIX_MOUNT_TYPE_CAMERA:
- icon_name = "camera-photo";
- break;
- case G_UNIX_MOUNT_TYPE_IPOD:
- icon_name = "multimedia-player";
- break;
- case G_UNIX_MOUNT_TYPE_UNKNOWN:
- default:
- icon_name = "drive-removable-media";
- break;
- }
- return g_strdup (icon_name);
-}
-
-/**
- * g_unix_drive_new:
- * @volume_monitor: a #GVolumeMonitor.
- * @mountpoint: a #GUnixMountPoint.
- *
- * Returns: a #GUnixDrive for the given #GUnixMountPoint.
- **/
-GUnixDrive *
-_g_unix_drive_new (GVolumeMonitor *volume_monitor,
- GUnixMountPoint *mountpoint)
-{
- GUnixDrive *drive;
-
- if (!(g_unix_mount_point_is_user_mountable (mountpoint) ||
- g_str_has_prefix (g_unix_mount_point_get_device_path (mountpoint), "/vol/")) ||
- g_unix_mount_point_is_loopback (mountpoint))
- return NULL;
-
- drive = g_object_new (G_TYPE_UNIX_DRIVE, NULL);
-
- drive->guessed_type = g_unix_mount_point_guess_type (mountpoint);
-
- /* TODO: */
- drive->mountpoint = g_strdup (g_unix_mount_point_get_mount_path (mountpoint));
- drive->icon = type_to_icon (drive->guessed_type);
- drive->name = g_strdup (_("Unknown drive"));
-
- return drive;
-}
-
-/**
- * g_unix_drive_disconnected:
- * @drive:
- *
- **/
-void
-_g_unix_drive_disconnected (GUnixDrive *drive)
-{
- if (drive->volume)
- {
- _g_unix_volume_unset_drive (drive->volume, drive);
- drive->volume = NULL;
- }
-}
-
-/**
- * g_unix_drive_set_volume:
- * @drive:
- * @volume:
- *
- **/
-void
-_g_unix_drive_set_volume (GUnixDrive *drive,
- GUnixVolume *volume)
-{
- if (drive->volume == volume)
- return;
-
- if (drive->volume)
- _g_unix_volume_unset_drive (drive->volume, drive);
-
- drive->volume = volume;
-
- /* TODO: Emit changed in idle to avoid locking issues */
- g_signal_emit_by_name (drive, "changed");
-}
-
-/**
- * g_unix_drive_unset_volume:
- * @drive:
- * @volume:
- *
- **/
-void
-_g_unix_drive_unset_volume (GUnixDrive *drive,
- GUnixVolume *volume)
-{
- if (drive->volume == volume)
- {
- drive->volume = NULL;
- /* TODO: Emit changed in idle to avoid locking issues */
- g_signal_emit_by_name (drive, "changed");
- }
-}
-
-static GIcon *
-g_unix_drive_get_icon (GDrive *drive)
-{
- GUnixDrive *unix_drive = G_UNIX_DRIVE (drive);
-
- return g_themed_icon_new (unix_drive->icon);
-}
-
-static char *
-g_unix_drive_get_name (GDrive *drive)
-{
- GUnixDrive *unix_drive = G_UNIX_DRIVE (drive);
-
- return g_strdup (unix_drive->name);
-}
-
-static gboolean
-g_unix_drive_is_automounted (GDrive *drive)
-{
- /* TODO */
- return FALSE;
-}
-
-static gboolean
-g_unix_drive_can_mount (GDrive *drive)
-{
- /* TODO */
- return TRUE;
-}
-
-static gboolean
-g_unix_drive_can_eject (GDrive *drive)
-{
- /* TODO */
- return FALSE;
-}
-
-static GList *
-g_unix_drive_get_volumes (GDrive *drive)
-{
- GList *l;
- GUnixDrive *unix_drive = G_UNIX_DRIVE (drive);
-
- l = NULL;
- if (unix_drive->volume)
- l = g_list_prepend (l, g_object_ref (unix_drive->volume));
-
- return l;
-}
-
-static gboolean
-g_unix_drive_has_volumes (GDrive *drive)
-{
- GUnixDrive *unix_drive = G_UNIX_DRIVE (drive);
-
- return unix_drive->volume != NULL;
-}
-
-
-gboolean
-_g_unix_drive_has_mountpoint (GUnixDrive *drive,
- const char *mountpoint)
-{
- return strcmp (drive->mountpoint, mountpoint) == 0;
-}
-
-static void
-g_unix_drive_mount (GDrive *drive,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- /* TODO */
-}
-
-
-static gboolean
-g_unix_drive_mount_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return TRUE;
-}
-
-static void
-g_unix_drive_eject (GDrive *drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- /* TODO */
-}
-
-static gboolean
-g_unix_drive_eject_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return TRUE;
-}
-
-static void
-g_unix_volume_drive_iface_init (GDriveIface *iface)
-{
- iface->get_name = g_unix_drive_get_name;
- iface->get_icon = g_unix_drive_get_icon;
- iface->has_volumes = g_unix_drive_has_volumes;
- iface->get_volumes = g_unix_drive_get_volumes;
- iface->is_automounted = g_unix_drive_is_automounted;
- iface->can_mount = g_unix_drive_can_mount;
- iface->can_eject = g_unix_drive_can_eject;
- iface->mount_fn = g_unix_drive_mount;
- iface->mount_finish = g_unix_drive_mount_finish;
- iface->eject = g_unix_drive_eject;
- iface->eject_finish = g_unix_drive_eject_finish;
-}
+++ /dev/null
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_UNIX_DRIVE_H__
-#define __G_UNIX_DRIVE_H__
-
-#include <glib-object.h>
-#include <gio/gdrive.h>
-#include <gio/gunixmounts.h>
-#include <gio/gunixvolumemonitor.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_UNIX_DRIVE (_g_unix_drive_get_type ())
-#define G_UNIX_DRIVE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_DRIVE, GUnixDrive))
-#define G_UNIX_DRIVE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_DRIVE, GUnixDriveClass))
-#define G_IS_UNIX_DRIVE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_DRIVE))
-#define G_IS_UNIX_DRIVE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_DRIVE))
-
-typedef struct _GUnixDriveClass GUnixDriveClass;
-
-struct _GUnixDriveClass {
- GObjectClass parent_class;
-};
-
-GType _g_unix_drive_get_type (void) G_GNUC_CONST;
-
-GUnixDrive *_g_unix_drive_new (GVolumeMonitor *volume_monitor,
- GUnixMountPoint *mountpoint);
-gboolean _g_unix_drive_has_mountpoint (GUnixDrive *drive,
- const char *mountpoint);
-void _g_unix_drive_set_volume (GUnixDrive *drive,
- GUnixVolume *volume);
-void _g_unix_drive_unset_volume (GUnixDrive *drive,
- GUnixVolume *volume);
-void _g_unix_drive_disconnected (GUnixDrive *drive);
-
-G_END_DECLS
-
-#endif /* __G_UNIX_DRIVE_H__ */
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include "gunixvolumemonitor.h"
+#include "gunixmount.h"
+#include "gunixvolume.h"
+#include "gmountprivate.h"
+#include "gvolumemonitor.h"
+#include "gthemedicon.h"
+#include "gsimpleasyncresult.h"
+#include "glibintl.h"
+
+#include "gioalias.h"
+
+struct _GUnixMount {
+ GObject parent;
+
+ GVolumeMonitor *volume_monitor;
+
+ GUnixVolume *volume; /* owned by volume monitor */
+
+ char *name;
+ GIcon *icon;
+ char *device_path;
+ char *mount_path;
+};
+
+static void g_unix_mount_mount_iface_init (GMountIface *iface);
+
+#define g_unix_mount_get_type _g_unix_mount_get_type
+G_DEFINE_TYPE_WITH_CODE (GUnixMount, g_unix_mount, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
+ g_unix_mount_mount_iface_init))
+
+
+static void
+g_unix_mount_finalize (GObject *object)
+{
+ GUnixMount *mount;
+
+ mount = G_UNIX_MOUNT (object);
+
+ if (mount->volume_monitor != NULL)
+ g_object_unref (mount->volume_monitor);
+
+ if (mount->volume)
+ _g_unix_volume_unset_mount (mount->volume, mount);
+
+ //TODO: g_warn_if_fail (volume->volume == NULL);
+ g_object_unref (mount->icon);
+ g_free (mount->name);
+ g_free (mount->device_path);
+ g_free (mount->mount_path);
+
+ if (G_OBJECT_CLASS (g_unix_mount_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_unix_mount_parent_class)->finalize) (object);
+}
+
+static void
+g_unix_mount_class_init (GUnixMountClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = g_unix_mount_finalize;
+}
+
+static void
+g_unix_mount_init (GUnixMount *unix_mount)
+{
+}
+
+GUnixMount *
+_g_unix_mount_new (GVolumeMonitor *volume_monitor,
+ GUnixMountEntry *mount_entry,
+ GUnixVolume *volume)
+{
+ GUnixMount *mount;
+
+ /* No volume for mount: Ignore internal things */
+ if (volume == NULL && g_unix_mount_is_system_internal (mount_entry))
+ return NULL;
+
+ mount = g_object_new (G_TYPE_UNIX_MOUNT, NULL);
+ mount->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL;
+ mount->device_path = g_strdup (g_unix_mount_get_device_path (mount_entry));
+ mount->mount_path = g_strdup (g_unix_mount_get_mount_path (mount_entry));
+ mount->name = g_unix_mount_guess_name (mount_entry);
+ mount->icon = g_unix_mount_guess_icon (mount_entry);
+
+ /* need to do this last */
+ mount->volume = volume;
+ if (volume != NULL)
+ _g_unix_volume_set_mount (volume, mount);
+
+ return mount;
+}
+
+void
+_g_unix_mount_unmounted (GUnixMount *mount)
+{
+ if (mount->volume != NULL)
+ {
+ _g_unix_volume_unset_mount (mount->volume, mount);
+ mount->volume = NULL;
+ g_signal_emit_by_name (mount, "changed");
+ /* there's really no need to emit mount_changed on the volume monitor
+ * as we're going to be deleted.. */
+ }
+}
+
+void
+_g_unix_mount_unset_volume (GUnixMount *mount,
+ GUnixVolume *volume)
+{
+ if (mount->volume == volume)
+ {
+ mount->volume = NULL;
+ /* TODO: Emit changed in idle to avoid locking issues */
+ g_signal_emit_by_name (mount, "changed");
+ if (mount->volume_monitor != NULL)
+ g_signal_emit_by_name (mount->volume_monitor, "mount_changed", mount);
+ }
+}
+
+static GFile *
+g_unix_mount_get_root (GMount *mount)
+{
+ GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
+
+ return g_file_new_for_path (unix_mount->mount_path);
+}
+
+static GIcon *
+g_unix_mount_get_icon (GMount *mount)
+{
+ GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
+
+ return g_object_ref (unix_mount->icon);
+}
+
+static char *
+g_unix_mount_get_name (GMount *mount)
+{
+ GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
+
+ return g_strdup (unix_mount->name);
+}
+
+gboolean
+_g_unix_mount_has_mount_path (GUnixMount *mount,
+ const char *mount_path)
+{
+ return strcmp (mount->mount_path, mount_path) == 0;
+}
+
+static GDrive *
+g_unix_mount_get_drive (GMount *mount)
+{
+ GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
+
+ if (unix_mount->volume != NULL)
+ return g_volume_get_drive (G_VOLUME (unix_mount->volume));
+
+ return NULL;
+}
+
+static GVolume *
+g_unix_mount_get_volume (GMount *mount)
+{
+ GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
+
+ if (unix_mount->volume)
+ return G_VOLUME (g_object_ref (unix_mount->volume));
+
+ return NULL;
+}
+
+static gboolean
+g_unix_mount_can_unmount (GMount *mount)
+{
+ return TRUE;
+}
+
+
+typedef struct {
+ GUnixMount *unix_mount;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ GCancellable *cancellable;
+ int error_fd;
+ GIOChannel *error_channel;
+ guint error_channel_source_id;
+ GString *error_string;
+} UnmountOp;
+
+static void
+unmount_cb (GPid pid, gint status, gpointer user_data)
+{
+ UnmountOp *data = user_data;
+ GSimpleAsyncResult *simple;
+
+ if (WEXITSTATUS (status) != 0)
+ {
+ GError *error;
+ error = g_error_new_literal (G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ data->error_string->str);
+ simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_mount),
+ data->callback,
+ data->user_data,
+ error);
+ g_error_free (error);
+ }
+ else
+ {
+ simple = g_simple_async_result_new (G_OBJECT (data->unix_mount),
+ data->callback,
+ data->user_data,
+ NULL);
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+
+ g_source_remove (data->error_channel_source_id);
+ g_io_channel_unref (data->error_channel);
+ g_string_free (data->error_string, TRUE);
+ close (data->error_fd);
+ g_spawn_close_pid (pid);
+ g_free (data);
+}
+
+static gboolean
+unmount_read_error (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ char *str;
+ gsize str_len;
+ UnmountOp *data = user_data;
+
+ g_io_channel_read_to_end (channel, &str, &str_len, NULL);
+ g_string_append (data->error_string, str);
+ g_free (str);
+ return TRUE;
+}
+
+static void
+g_unix_mount_unmount (GMount *mount,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
+ UnmountOp *data;
+ GPid child_pid;
+ GError *error;
+ char *argv[] = {"umount", NULL, NULL};
+
+ if (unix_mount->mount_path != NULL)
+ argv[1] = unix_mount->mount_path;
+ else
+ argv[1] = unix_mount->device_path;
+
+ data = g_new0 (UnmountOp, 1);
+ data->unix_mount = unix_mount;
+ data->callback = callback;
+ data->user_data = user_data;
+ data->cancellable = cancellable;
+
+ error = NULL;
+ if (!g_spawn_async_with_pipes (NULL, /* working dir */
+ argv,
+ NULL, /* envp */
+ G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
+ NULL, /* child_setup */
+ NULL, /* user_data for child_setup */
+ &child_pid,
+ NULL, /* standard_input */
+ NULL, /* standard_output */
+ &(data->error_fd),
+ &error)) {
+ GSimpleAsyncResult *simple;
+ simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_mount),
+ data->callback,
+ data->user_data,
+ error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ g_error_free (error);
+ g_free (data);
+ return;
+ }
+ data->error_string = g_string_new ("");
+ data->error_channel = g_io_channel_unix_new (data->error_fd);
+ data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, unmount_read_error, data);
+ g_child_watch_add (child_pid, unmount_cb, data);
+}
+
+static gboolean
+g_unix_mount_unmount_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+g_unix_mount_mount_iface_init (GMountIface *iface)
+{
+ iface->get_root = g_unix_mount_get_root;
+ iface->get_name = g_unix_mount_get_name;
+ iface->get_icon = g_unix_mount_get_icon;
+ iface->get_drive = g_unix_mount_get_drive;
+ iface->get_volume = g_unix_mount_get_volume;
+ iface->can_unmount = g_unix_mount_can_unmount;
+ iface->unmount = g_unix_mount_unmount;
+ iface->unmount_finish = g_unix_mount_unmount_finish;
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
+ */
+
+#ifndef __G_UNIX_MOUNT_H__
+#define __G_UNIX_MOUNT_H__
+
+#include <glib-object.h>
+#include <gio/gmount.h>
+#include <gio/gunixmounts.h>
+#include <gio/gunixvolumemonitor.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_UNIX_MOUNT (_g_unix_mount_get_type ())
+#define G_UNIX_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_MOUNT, GUnixMount))
+#define G_UNIX_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_MOUNT, GUnixMountClass))
+#define G_IS_UNIX_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_MOUNT))
+#define G_IS_UNIX_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_MOUNT))
+
+typedef struct _GUnixMountClass GUnixMountClass;
+
+struct _GUnixMountClass {
+ GObjectClass parent_class;
+};
+
+GType _g_unix_mount_get_type (void) G_GNUC_CONST;
+
+GUnixMount *_g_unix_mount_new (GVolumeMonitor *volume_monitor,
+ GUnixMountEntry *mount_entry,
+ GUnixVolume *volume);
+gboolean _g_unix_mount_has_mount_path (GUnixMount *mount,
+ const char *mount_path);
+void _g_unix_mount_unset_volume (GUnixMount *mount,
+ GUnixVolume *volume);
+void _g_unix_mount_unmounted (GUnixMount *mount);
+
+G_END_DECLS
+
+#endif /* __G_UNIX_MOUNT_H__ */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
#include "gunixmounts.h"
#include "gfile.h"
#include "gfilemonitor.h"
+#include "glibintl.h"
+#include "gthemedicon.h"
#include "gioalias.h"
+static const char *_resolve_dev_root (void);
+
/**
* SECTION:gunixmounts
* @short_description: Unix Mounts
*
**/
-struct _GUnixMount {
+/**
+ * GUnixMountType:
+ * @G_UNIX_MOUNT_TYPE_UNKNOWN: Unknown UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_FLOPPY: Floppy disk UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_CDROM: CDROM UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_NFS: Network File System (NFS) UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_ZIP: ZIP UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_JAZ: JAZZ UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_MEMSTICK: Memory Stick UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_CF: Compact Flash UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_SM: Smart Media UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_SDMMC: SD/MMC UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_IPOD: iPod UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_CAMERA: Digital camera UNIX mount type.
+ * @G_UNIX_MOUNT_TYPE_HD: Hard drive UNIX mount type.
+ *
+ * Types of UNIX mounts.
+ **/
+typedef enum {
+ G_UNIX_MOUNT_TYPE_UNKNOWN,
+ G_UNIX_MOUNT_TYPE_FLOPPY,
+ G_UNIX_MOUNT_TYPE_CDROM,
+ G_UNIX_MOUNT_TYPE_NFS,
+ G_UNIX_MOUNT_TYPE_ZIP,
+ G_UNIX_MOUNT_TYPE_JAZ,
+ G_UNIX_MOUNT_TYPE_MEMSTICK,
+ G_UNIX_MOUNT_TYPE_CF,
+ G_UNIX_MOUNT_TYPE_SM,
+ G_UNIX_MOUNT_TYPE_SDMMC,
+ G_UNIX_MOUNT_TYPE_IPOD,
+ G_UNIX_MOUNT_TYPE_CAMERA,
+ G_UNIX_MOUNT_TYPE_HD
+} GUnixMountType;
+
+struct _GUnixMountEntry {
char *mount_path;
char *device_path;
char *filesystem_type;
return FALSE;
}
+/**
+ * g_unix_is_mount_path_system_internal:
+ * @mount_path: a mount path, e.g. <literal>/media/disk</literal> or <literal>/usr</literal>
+ *
+ * Determines if @mount_path is considered an implementation of the
+ * OS. This is primarily used for hiding mountable and mounted volumes
+ * that only are used in the OS and has little to no relevance to the
+ * casual user.
+ *
+ * Returns; %TRUE if @mount_path is considered an implementation detail of the OS.
+ **/
+gboolean
+g_unix_is_mount_path_system_internal (const char *mount_path)
+{
+ const char *ignore_mountpoints[] = {
+ /* Includes all FHS 2.3 toplevel dirs and other specilized
+ * directories that we want to hide from the user.
+ */
+ "/", /* we already have "Filesystem root" in Nautilus */
+ "/bin",
+ "/boot",
+ "/dev",
+ "/etc",
+ "/home",
+ "/lib",
+ "/lib64",
+ "/media",
+ "/mnt",
+ "/opt",
+ "/root",
+ "/sbin",
+ "/srv",
+ "/tmp",
+ "/usr",
+ "/var",
+ "/var/log/audit", /* https://bugzilla.redhat.com/show_bug.cgi?id=333041 */
+ "/var/tmp", /* https://bugzilla.redhat.com/show_bug.cgi?id=335241 */
+ "/proc",
+ "/sbin",
+ "/net",
+ NULL
+ };
+
+ if (is_in (mount_path, ignore_mountpoints))
+ return TRUE;
+
+ if (g_str_has_prefix (mount_path, "/dev") ||
+ g_str_has_prefix (mount_path, "/proc") ||
+ g_str_has_prefix (mount_path, "/sys"))
+ return TRUE;
+
+ if (strstr (mount_path, "/.gvfs") != NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
static gboolean
guess_system_internal (const char *mountpoint,
const char *fs,
"/dev/vn",
NULL
};
- const char *ignore_mountpoints[] = {
- /* Includes all FHS 2.3 toplevel dirs */
- "/bin",
- "/boot",
- "/dev",
- "/etc",
- "/home",
- "/lib",
- "/lib64",
- "/media",
- "/mnt",
- "/opt",
- "/root",
- "/sbin",
- "/srv",
- "/tmp",
- "/usr",
- "/var",
- "/proc",
- "/sbin",
- "/net",
- NULL
- };
if (is_in (fs, ignore_fs))
return TRUE;
if (is_in (device, ignore_devices))
return TRUE;
- if (is_in (mountpoint, ignore_mountpoints))
- return TRUE;
-
- if (g_str_has_prefix (mountpoint, "/dev") ||
- g_str_has_prefix (mountpoint, "/proc") ||
- g_str_has_prefix (mountpoint, "/sys"))
- return TRUE;
-
- if (strstr (mountpoint, "/.gvfs") != NULL)
+ if (g_unix_is_mount_path_system_internal (mountpoint))
return TRUE;
return FALSE;
struct mntent *mntent;
FILE *file;
char *read_file;
- GUnixMount *mount_entry;
+ GUnixMountEntry *mount_entry;
GHashTable *mounts_hash;
GList *return_list;
if (mntent->mnt_fsname != NULL &&
mntent->mnt_fsname[0] == '/' &&
g_hash_table_lookup (mounts_hash, mntent->mnt_fsname))
- continue;
+ continue;
- mount_entry = g_new0 (GUnixMount, 1);
+ mount_entry = g_new0 (GUnixMountEntry, 1);
mount_entry->mount_path = g_strdup (mntent->mnt_dir);
- mount_entry->device_path = g_strdup (mntent->mnt_fsname);
+ if (strcmp (mntent->mnt_fsname, "/dev/root") == 0)
+ mount_entry->device_path = g_strdup (_resolve_dev_root ());
+ else
+ mount_entry->device_path = g_strdup (mntent->mnt_fsname);
mount_entry->filesystem_type = g_strdup (mntent->mnt_type);
#if defined (HAVE_HASMNTOPT)
struct mnttab mntent;
FILE *file;
char *read_file;
- GUnixMount *mount_entry;
+ GUnixMountEntry *mount_entry;
GList *return_list;
read_file = get_mtab_read_file ();
G_LOCK (getmntent);
while (! getmntent (file, &mntent))
{
- mount_entry = g_new0 (GUnixMount, 1);
+ mount_entry = g_new0 (GUnixMountEntry, 1);
mount_entry->mount_path = g_strdup (mntent.mnt_mountp);
mount_entry->device_path = g_strdup (mntent.mnt_special);
return_list = NULL;
while (vmount_number > 0)
{
- mount_entry = g_new0 (GUnixMount, 1);
+ mount_entry = g_new0 (GUnixMountEntry, 1);
mount_entry->device_path = g_strdup (vmt2dataptr (vmount_info, VMT_OBJECT));
mount_entry->mount_path = g_strdup (vmt2dataptr (vmount_info, VMT_STUB));
{
struct statfs *mntent = NULL;
int num_mounts, i;
- GUnixMount *mount_entry;
+ GUnixMountEntry *mount_entry;
GList *return_list;
/* Pass MNT_NOWAIT to avoid blocking trying to update NFS mounts. */
for (i = 0; i < num_mounts; i++)
{
- mount_entry = g_new0 (GUnixMount, 1);
+ mount_entry = g_new0 (GUnixMountEntry, 1);
mount_entry->mount_path = g_strdup (mntent[i].f_mntonname);
mount_entry->device_path = g_strdup (mntent[i].f_mntfromname);
if ((strcmp (mntent->mnt_dir, "ignore") == 0) ||
(strcmp (mntent->mnt_dir, "swap") == 0))
continue;
-
+
mount_entry = g_new0 (GUnixMountPoint, 1);
mount_entry->mount_path = g_strdup (mntent->mnt_dir);
- mount_entry->device_path = g_strdup (mntent->mnt_fsname);
+ if (strcmp (mntent->mnt_fsname, "/dev/root") == 0)
+ mount_entry->device_path = g_strdup (_resolve_dev_root ());
+ else
+ mount_entry->device_path = g_strdup (mntent->mnt_fsname);
mount_entry->filesystem_type = g_strdup (mntent->mnt_type);
#ifdef HAVE_HASMNTOPT
* @mount_path: path for a possible unix mount.
* @time_read: guint64 to contain a timestamp.
*
- * Gets a #GUnixMount for a given mount path. If @time_read
+ * Gets a #GUnixMountEntry for a given mount path. If @time_read
* is set, it will be filled with a unix timestamp for checking
* if the mounts have changed since with g_unix_mounts_changed_since().
*
* Returns: a #GUnixMount.
**/
-GUnixMount *
+GUnixMountEntry *
g_get_unix_mount_at (const char *mount_path,
guint64 *time_read)
{
GList *mounts, *l;
- GUnixMount *mount_entry, *found;
+ GUnixMountEntry *mount_entry, *found;
mounts = g_get_unix_mounts (time_read);
* Frees a unix mount.
**/
void
-g_unix_mount_free (GUnixMount *mount_entry)
+g_unix_mount_free (GUnixMountEntry *mount_entry)
{
g_return_if_fail (mount_entry != NULL);
/**
* g_unix_mount_compare:
- * @mount1: first #GUnixMount to compare.
- * @mount2: second #GUnixMount to compare.
+ * @mount1: first #GUnixMountEntry to compare.
+ * @mount2: second #GUnixMountEntry to compare.
*
* Compares two unix mounts.
*
* or less than @mount2, respectively.
**/
gint
-g_unix_mount_compare (GUnixMount *mount1,
- GUnixMount *mount2)
+g_unix_mount_compare (GUnixMountEntry *mount1,
+ GUnixMountEntry *mount2)
{
int res;
/**
* g_unix_mount_get_mount_path:
- * @mount_entry: input #GUnixMount to get the mount path for.
+ * @mount_entry: input #GUnixMountEntry to get the mount path for.
*
* Gets the mount path for a unix mount.
*
* Returns: the mount path for @mount_entry.
**/
const char *
-g_unix_mount_get_mount_path (GUnixMount *mount_entry)
+g_unix_mount_get_mount_path (GUnixMountEntry *mount_entry)
{
g_return_val_if_fail (mount_entry != NULL, NULL);
* Returns: a string containing the device path.
**/
const char *
-g_unix_mount_get_device_path (GUnixMount *mount_entry)
+g_unix_mount_get_device_path (GUnixMountEntry *mount_entry)
{
g_return_val_if_fail (mount_entry != NULL, NULL);
* Returns: a string containing the file system type.
**/
const char *
-g_unix_mount_get_fs_type (GUnixMount *mount_entry)
+g_unix_mount_get_fs_type (GUnixMountEntry *mount_entry)
{
g_return_val_if_fail (mount_entry != NULL, NULL);
* Returns: %TRUE if @mount_entry is read only.
**/
gboolean
-g_unix_mount_is_readonly (GUnixMount *mount_entry)
+g_unix_mount_is_readonly (GUnixMountEntry *mount_entry)
{
g_return_val_if_fail (mount_entry != NULL, FALSE);
* Returns: %TRUE if the unix mount is for a system path.
**/
gboolean
-g_unix_mount_is_system_internal (GUnixMount *mount_entry)
+g_unix_mount_is_system_internal (GUnixMountEntry *mount_entry)
{
g_return_val_if_fail (mount_entry != NULL, FALSE);
* Returns: a #GUnixMountType.
**/
GUnixMountType
-g_unix_mount_guess_type (GUnixMount *mount_entry)
+g_unix_mount_guess_type (GUnixMountEntry *mount_entry)
{
g_return_val_if_fail (mount_entry != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
g_return_val_if_fail (mount_entry->mount_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
mount_point->filesystem_type);
}
+static const char *
+type_to_icon (GUnixMountType type, gboolean is_mount_point)
+{
+ const char *icon_name;
+
+ switch (type)
+ {
+ case G_UNIX_MOUNT_TYPE_HD:
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "drive-harddisk";
+ break;
+ case G_UNIX_MOUNT_TYPE_FLOPPY:
+ case G_UNIX_MOUNT_TYPE_ZIP:
+ case G_UNIX_MOUNT_TYPE_JAZ:
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "media-floppy";
+ break;
+ case G_UNIX_MOUNT_TYPE_CDROM:
+ if (is_mount_point)
+ icon_name = "drive-optical";
+ else
+ icon_name = "media-optical";
+ break;
+ case G_UNIX_MOUNT_TYPE_NFS:
+ /* TODO: Would like a better icon here... */
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "drive-harddisk";
+ break;
+ case G_UNIX_MOUNT_TYPE_MEMSTICK:
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "media-flash";
+ break;
+ case G_UNIX_MOUNT_TYPE_CAMERA:
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "camera-photo";
+ break;
+ case G_UNIX_MOUNT_TYPE_IPOD:
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "multimedia-player";
+ break;
+ case G_UNIX_MOUNT_TYPE_UNKNOWN:
+ default:
+ if (is_mount_point)
+ icon_name = "drive-removable-media";
+ else
+ icon_name = "drive-harddisk";
+ break;
+ }
+
+ return icon_name;
+}
+
+char *
+g_unix_mount_guess_name (GUnixMountEntry *mount_entry)
+{
+ char *name;
+
+ if (strcmp (mount_entry->mount_path, "/") == 0)
+ name = g_strdup (_("Filesystem root"));
+ else
+ name = g_filename_display_basename (mount_entry->mount_path);
+
+ return name;
+}
+
+GIcon *
+g_unix_mount_guess_icon (GUnixMountEntry *mount_entry)
+{
+ return g_themed_icon_new (type_to_icon (g_unix_mount_guess_type (mount_entry), FALSE));
+}
+
+char *
+g_unix_mount_point_guess_name (GUnixMountPoint *mount_point)
+{
+ char *name;
+
+ if (strcmp (mount_point->mount_path, "/") == 0)
+ name = g_strdup (_("Filesystem root"));
+ else
+ name = g_filename_display_basename (mount_point->mount_path);
+
+ return name;
+}
+
+GIcon *
+g_unix_mount_point_guess_icon (GUnixMountPoint *mount_point)
+{
+ return g_themed_icon_new (type_to_icon (g_unix_mount_point_guess_type (mount_point), TRUE));
+}
+
+
+/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
+static void
+_canonicalize_filename (gchar *filename)
+{
+ gchar *p, *q;
+ gboolean last_was_slash = FALSE;
+
+ p = filename;
+ q = filename;
+
+ while (*p)
+ {
+ if (*p == G_DIR_SEPARATOR)
+ {
+ if (!last_was_slash)
+ *q++ = G_DIR_SEPARATOR;
+
+ last_was_slash = TRUE;
+ }
+ else
+ {
+ if (last_was_slash && *p == '.')
+ {
+ if (*(p + 1) == G_DIR_SEPARATOR ||
+ *(p + 1) == '\0')
+ {
+ if (*(p + 1) == '\0')
+ break;
+
+ p += 1;
+ }
+ else if (*(p + 1) == '.' &&
+ (*(p + 2) == G_DIR_SEPARATOR ||
+ *(p + 2) == '\0'))
+ {
+ if (q > filename + 1)
+ {
+ q--;
+ while (q > filename + 1 &&
+ *(q - 1) != G_DIR_SEPARATOR)
+ q--;
+ }
+
+ if (*(p + 2) == '\0')
+ break;
+
+ p += 2;
+ }
+ else
+ {
+ *q++ = *p;
+ last_was_slash = FALSE;
+ }
+ }
+ else
+ {
+ *q++ = *p;
+ last_was_slash = FALSE;
+ }
+ }
+
+ p++;
+ }
+
+ if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
+ q--;
+
+ *q = '\0';
+}
+
+static char *
+_resolve_symlink (const char *file)
+{
+ GError *error;
+ char *dir;
+ char *link;
+ char *f;
+ char *f1;
+
+ f = g_strdup (file);
+
+ while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) {
+ link = g_file_read_link (f, &error);
+ if (link == NULL) {
+ g_error_free (error);
+ g_free (f);
+ f = NULL;
+ goto out;
+ }
+
+ dir = g_path_get_dirname (f);
+ f1 = g_strdup_printf ("%s/%s", dir, link);
+ g_free (dir);
+ g_free (link);
+ g_free (f);
+ f = f1;
+ }
+
+ out:
+ if (f != NULL)
+ _canonicalize_filename (f);
+ return f;
+}
+
+static const char *
+_resolve_dev_root (void)
+{
+ static gboolean have_real_dev_root = FALSE;
+ static char real_dev_root[256];
+ struct stat statbuf;
+
+ /* see if it's cached already */
+ if (have_real_dev_root)
+ goto found;
+
+ /* otherwise we're going to find it right away.. */
+ have_real_dev_root = TRUE;
+
+ if (stat ("/dev/root", &statbuf) == 0) {
+ if (! S_ISLNK (statbuf.st_mode)) {
+ dev_t root_dev = statbuf.st_dev;
+ FILE *f;
+ char buf[1024];
+
+ /* see if device with similar major:minor as /dev/root is mention
+ * in /etc/mtab (it usually is)
+ */
+ f = fopen ("/etc/mtab", "r");
+ if (f != NULL) {
+ struct mntent ent;
+
+ while (getmntent_r (f, &ent, buf, sizeof (buf)) != NULL) {
+
+ if (stat (ent.mnt_fsname, &statbuf) == 0 &&
+ statbuf.st_dev == root_dev) {
+ strncpy (real_dev_root, ent.mnt_fsname, sizeof (real_dev_root) - 1);
+ real_dev_root[sizeof (real_dev_root) - 1] = '\0';
+ fclose (f);
+ goto found;
+ }
+ }
+ fclose (f);
+ }
+
+ /* no, that didn't work.. next we could scan /dev ... but I digress.. */
+
+ } else {
+ char *resolved;
+ resolved = _resolve_symlink ("/dev/root");
+ if (resolved != NULL) {
+ strncpy (real_dev_root, resolved, sizeof (real_dev_root) - 1);
+ real_dev_root[sizeof (real_dev_root) - 1] = '\0';
+ g_free (resolved);
+ goto found;
+ }
+ }
+ }
+
+ /* bah sucks.. */
+ strcpy (real_dev_root, "/dev/root");
+
+ found:
+ return real_dev_root;
+}
+
#define __G_UNIX_MOUNTS_C__
#include "gioaliasdef.c"
#include <glib.h>
#include <glib-object.h>
+#include <gio/gicon.h>
G_BEGIN_DECLS
/**
- * GUnixMount:
+ * GUnixMountEntry:
*
- * Defines a Unix mount.
+ * Defines a Unix mount entry (e.g. "/media/cdrom").
**/
-typedef struct _GUnixMount GUnixMount;
+typedef struct _GUnixMountEntry GUnixMountEntry;
/**
* GUnixMountPoint:
typedef struct _GUnixMountPoint GUnixMountPoint;
/**
- * GUnixMountType:
- * @G_UNIX_MOUNT_TYPE_UNKNOWN: Unknown UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_FLOPPY: Floppy disk UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_CDROM: CDROM UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_NFS: Network File System (NFS) UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_ZIP: ZIP UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_JAZ: JAZZ UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_MEMSTICK: Memory Stick UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_CF: Compact Flash UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_SM: Smart Media UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_SDMMC: SD/MMC UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_IPOD: iPod UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_CAMERA: Digital camera UNIX mount type.
- * @G_UNIX_MOUNT_TYPE_HD: Hard drive UNIX mount type.
- *
- * Types of UNIX mounts.
- **/
-typedef enum {
- G_UNIX_MOUNT_TYPE_UNKNOWN,
- G_UNIX_MOUNT_TYPE_FLOPPY,
- G_UNIX_MOUNT_TYPE_CDROM,
- G_UNIX_MOUNT_TYPE_NFS,
- G_UNIX_MOUNT_TYPE_ZIP,
- G_UNIX_MOUNT_TYPE_JAZ,
- G_UNIX_MOUNT_TYPE_MEMSTICK,
- G_UNIX_MOUNT_TYPE_CF,
- G_UNIX_MOUNT_TYPE_SM,
- G_UNIX_MOUNT_TYPE_SDMMC,
- G_UNIX_MOUNT_TYPE_IPOD,
- G_UNIX_MOUNT_TYPE_CAMERA,
- G_UNIX_MOUNT_TYPE_HD
-} GUnixMountType;
-
-/**
* GUnixMountMonitor:
*
* Watches #GUnixMount<!-- -->s for changes.
#define G_IS_UNIX_MOUNT_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_MOUNT_MONITOR))
#define G_IS_UNIX_MOUNT_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_MOUNT_MONITOR))
-void g_unix_mount_free (GUnixMount *mount_entry);
+void g_unix_mount_free (GUnixMountEntry *mount_entry);
void g_unix_mount_point_free (GUnixMountPoint *mount_point);
-gint g_unix_mount_compare (GUnixMount *mount1,
- GUnixMount *mount2);
-const char * g_unix_mount_get_mount_path (GUnixMount *mount_entry);
-const char * g_unix_mount_get_device_path (GUnixMount *mount_entry);
-const char * g_unix_mount_get_fs_type (GUnixMount *mount_entry);
-gboolean g_unix_mount_is_readonly (GUnixMount *mount_entry);
-gboolean g_unix_mount_is_system_internal (GUnixMount *mount_entry);
-GUnixMountType g_unix_mount_guess_type (GUnixMount *mount_entry);
+gint g_unix_mount_compare (GUnixMountEntry *mount1,
+ GUnixMountEntry *mount2);
+const char * g_unix_mount_get_mount_path (GUnixMountEntry *mount_entry);
+const char * g_unix_mount_get_device_path (GUnixMountEntry *mount_entry);
+const char * g_unix_mount_get_fs_type (GUnixMountEntry *mount_entry);
+gboolean g_unix_mount_is_readonly (GUnixMountEntry *mount_entry);
+gboolean g_unix_mount_is_system_internal (GUnixMountEntry *mount_entry);
+char * g_unix_mount_guess_name (GUnixMountEntry *mount_entry);
+GIcon * g_unix_mount_guess_icon (GUnixMountEntry *mount_entry);
gint g_unix_mount_point_compare (GUnixMountPoint *mount1,
GUnixMountPoint *mount2);
gboolean g_unix_mount_point_is_readonly (GUnixMountPoint *mount_point);
gboolean g_unix_mount_point_is_user_mountable (GUnixMountPoint *mount_point);
gboolean g_unix_mount_point_is_loopback (GUnixMountPoint *mount_point);
-GUnixMountType g_unix_mount_point_guess_type (GUnixMountPoint *mount_point);
+char * g_unix_mount_point_guess_name (GUnixMountPoint *mount_point);
+GIcon * g_unix_mount_point_guess_icon (GUnixMountPoint *mount_point);
GList * g_get_unix_mount_points (guint64 *time_read);
GList * g_get_unix_mounts (guint64 *time_read);
-GUnixMount * g_get_unix_mount_at (const char *mount_path,
+GUnixMountEntry * g_get_unix_mount_at (const char *mount_path,
guint64 *time_read);
gboolean g_unix_mounts_changed_since (guint64 time);
gboolean g_unix_mount_points_changed_since (guint64 time);
GType g_unix_mount_monitor_get_type (void) G_GNUC_CONST;
GUnixMountMonitor *g_unix_mount_monitor_new (void);
+
+
+char *g_unix_get_canonical_device_path (const char *device_path);
+
+gboolean g_unix_is_mount_path_system_internal (const char *mount_path);
+
G_END_DECLS
#endif /* __G_UNIX_MOUNTS_H__ */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include <glib.h>
-#include "gunixvolumemonitor.h"
#include "gunixvolume.h"
-#include "gunixdrive.h"
-#include "gvolumeprivate.h"
-#include "gvolumemonitor.h"
+#include "gunixmount.h"
#include "gthemedicon.h"
+#include "gvolumemonitor.h"
+#include "gsimpleasyncresult.h"
#include "glibintl.h"
#include "gioalias.h"
struct _GUnixVolume {
GObject parent;
- GUnixDrive *drive; /* owned by volume monitor */
+ GVolumeMonitor *volume_monitor;
+ GUnixMount *mount; /* owned by volume monitor */
+
+ char *device_path;
+ char *mount_path;
char *name;
- char *icon;
- char *mountpoint;
+ GIcon *icon;
};
static void g_unix_volume_volume_iface_init (GVolumeIface *iface);
G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME,
g_unix_volume_volume_iface_init))
-
static void
g_unix_volume_finalize (GObject *object)
{
volume = G_UNIX_VOLUME (object);
- if (volume->drive)
- _g_unix_drive_unset_volume (volume->drive, volume);
-
- g_warn_if_fail (volume->drive == NULL);
- g_free (volume->name);
- g_free (volume->icon);
- g_free (volume->mountpoint);
+ if (volume->volume_monitor != NULL)
+ g_object_unref (volume->volume_monitor);
+
+ if (volume->mount)
+ _g_unix_mount_unset_volume (volume->mount, volume);
+ g_object_unref (volume->icon);
+ g_free (volume->name);
+ g_free (volume->mount_path);
+ g_free (volume->device_path);
+
if (G_OBJECT_CLASS (g_unix_volume_parent_class)->finalize)
(*G_OBJECT_CLASS (g_unix_volume_parent_class)->finalize) (object);
}
{
}
-static char *
-get_filesystem_volume_name (const char *fs_type)
-{
- /* TODO: add translation table from gnome-vfs */
- return g_strdup_printf (_("%s volume"), fs_type);
-}
-
-static char *
-type_to_icon (GUnixMountType type)
-{
- const char *icon_name = NULL;
-
- switch (type)
- {
- case G_UNIX_MOUNT_TYPE_HD:
- icon_name = "drive-harddisk";
- break;
- case G_UNIX_MOUNT_TYPE_FLOPPY:
- case G_UNIX_MOUNT_TYPE_ZIP:
- case G_UNIX_MOUNT_TYPE_JAZ:
- icon_name = "media-floppy";
- break;
- case G_UNIX_MOUNT_TYPE_CDROM:
- icon_name = "media-optical";
- break;
- case G_UNIX_MOUNT_TYPE_NFS:
- /* TODO: Would like a better icon here... */
- icon_name = "drive-harddisk";
- break;
- case G_UNIX_MOUNT_TYPE_MEMSTICK:
- icon_name = "media-flash";
- break;
- case G_UNIX_MOUNT_TYPE_CAMERA:
- icon_name = "camera-photo";
- break;
- case G_UNIX_MOUNT_TYPE_IPOD:
- icon_name = "multimedia-player";
- break;
- case G_UNIX_MOUNT_TYPE_UNKNOWN:
- default:
- icon_name = "drive-harddisk";
- break;
- }
- return g_strdup (icon_name);
-}
-
+/**
+ * g_unix_volume_new:
+ * @volume_monitor: a #GVolumeMonitor.
+ * @mountpoint: a #GUnixMountPoint.
+ *
+ * Returns: a #GUnixVolume for the given #GUnixMountPoint.
+ **/
GUnixVolume *
-_g_unix_volume_new (GUnixMount *mount,
- GUnixDrive *drive)
+_g_unix_volume_new (GVolumeMonitor *volume_monitor,
+ GUnixMountPoint *mountpoint)
{
GUnixVolume *volume;
- GUnixMountType type;
- const char *mount_path;
- char *volume_name;
- mount_path = g_unix_mount_get_mount_path (mount);
-
- /* No drive for volume. Ignore internal things */
- if (drive == NULL && g_unix_mount_is_system_internal (mount))
+ if (!(g_unix_mount_point_is_user_mountable (mountpoint) ||
+ g_str_has_prefix (g_unix_mount_point_get_device_path (mountpoint), "/vol/")) ||
+ g_unix_mount_point_is_loopback (mountpoint))
return NULL;
volume = g_object_new (G_TYPE_UNIX_VOLUME, NULL);
- volume->drive = drive;
- if (drive)
- _g_unix_drive_set_volume (drive, volume);
- volume->mountpoint = g_strdup (mount_path);
-
- type = g_unix_mount_guess_type (mount);
-
- volume->icon = type_to_icon (type);
-
- volume_name = NULL;
- if (mount_path)
- {
- if (strcmp (mount_path, "/") == 0)
- volume_name = g_strdup (_("Filesystem root"));
- else
- volume_name = g_filename_display_basename (mount_path);
- }
-
- if (volume_name == NULL)
- {
- if (g_unix_mount_get_fs_type (mount) != NULL)
- volume_name = g_strdup (get_filesystem_volume_name (g_unix_mount_get_fs_type (mount)));
- }
-
- if (volume_name == NULL)
- /* TODO: Use volume size as name? */
- volume_name = g_strdup (_("Unknown volume"));
-
- volume->name = volume_name;
+ volume->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL;
+ volume->mount_path = g_strdup (g_unix_mount_point_get_mount_path (mountpoint));
+ volume->device_path = g_strdup (g_unix_mount_point_get_device_path (mountpoint));
+ volume->name = g_unix_mount_point_guess_name (mountpoint);
+ volume->icon = g_unix_mount_point_guess_icon (mountpoint);
return volume;
}
+/**
+ * g_unix_volume_disconnected:
+ * @volume:
+ *
+ **/
void
-_g_unix_volume_unmounted (GUnixVolume *volume)
+_g_unix_volume_disconnected (GUnixVolume *volume)
{
- if (volume->drive)
+ if (volume->mount)
{
- _g_unix_drive_unset_volume (volume->drive, volume);
- volume->drive = NULL;
- g_signal_emit_by_name (volume, "changed");
+ _g_unix_mount_unset_volume (volume->mount, volume);
+ volume->mount = NULL;
}
}
+/**
+ * g_unix_volume_set_mount:
+ * @volume:
+ * @mount:
+ *
+ **/
+void
+_g_unix_volume_set_mount (GUnixVolume *volume,
+ GUnixMount *mount)
+{
+ if (volume->mount == mount)
+ return;
+
+ if (volume->mount)
+ _g_unix_mount_unset_volume (volume->mount, volume);
+
+ volume->mount = mount;
+
+ /* TODO: Emit changed in idle to avoid locking issues */
+ g_signal_emit_by_name (volume, "changed");
+ if (volume->volume_monitor != NULL)
+ g_signal_emit_by_name (volume->volume_monitor, "volume_changed", volume);
+}
+
+/**
+ * g_unix_volume_unset_mount:
+ * @volume:
+ * @mount:
+ *
+ **/
void
-_g_unix_volume_unset_drive (GUnixVolume *volume,
- GUnixDrive *drive)
+_g_unix_volume_unset_mount (GUnixVolume *volume,
+ GUnixMount *mount)
{
- if (volume->drive == drive)
+ if (volume->mount == mount)
{
- volume->drive = NULL;
+ volume->mount = NULL;
/* TODO: Emit changed in idle to avoid locking issues */
g_signal_emit_by_name (volume, "changed");
+ if (volume->volume_monitor != NULL)
+ g_signal_emit_by_name (volume->volume_monitor, "volume_changed", volume);
}
}
-static GFile *
-g_unix_volume_get_root (GVolume *volume)
-{
- GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
-
- return g_file_new_for_path (unix_volume->mountpoint);
-}
-
static GIcon *
g_unix_volume_get_icon (GVolume *volume)
{
GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
-
- return g_themed_icon_new (unix_volume->icon);
+ return g_object_ref (unix_volume->icon);
}
static char *
g_unix_volume_get_name (GVolume *volume)
{
GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
-
return g_strdup (unix_volume->name);
}
-gboolean
-_g_unix_volume_has_mountpoint (GUnixVolume *volume,
- const char *mountpoint)
+static gboolean
+g_unix_volume_can_mount (GVolume *volume)
{
- return strcmp (volume->mountpoint, mountpoint) == 0;
+ return TRUE;
}
static GDrive *
g_unix_volume_get_drive (GVolume *volume)
{
- GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
-
- if (unix_volume->drive)
- return G_DRIVE (g_object_ref (unix_volume->drive));
-
+ /* TODO */
return NULL;
}
-static gboolean
-g_unix_volume_can_unmount (GVolume *volume)
+static GMount *
+g_unix_volume_get_mount (GVolume *volume)
{
- /* TODO */
- return FALSE;
+ GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
+
+ if (unix_volume->mount != NULL)
+ return g_object_ref (unix_volume->mount);
+
+ return NULL;
}
-static gboolean
-g_unix_volume_can_eject (GVolume *volume)
+
+gboolean
+_g_unix_volume_has_mount_path (GUnixVolume *volume,
+ const char *mount_path)
{
- /* TODO */
- return FALSE;
+ return strcmp (volume->mount_path, mount_path) == 0;
}
-static void
-g_unix_volume_unmount (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+
+typedef struct {
+ GUnixVolume *unix_volume;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ GCancellable *cancellable;
+ int error_fd;
+ GIOChannel *error_channel;
+ guint error_channel_source_id;
+ GString *error_string;
+} MountOp;
+
+static void
+mount_cb (GPid pid, gint status, gpointer user_data)
{
- /* TODO */
+ MountOp *data = user_data;
+ GSimpleAsyncResult *simple;
+
+ if (WEXITSTATUS (status) != 0)
+ {
+ GError *error;
+ error = g_error_new_literal (G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ data->error_string->str);
+ simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_volume),
+ data->callback,
+ data->user_data,
+ error);
+ g_error_free (error);
+ }
+ else
+ {
+ simple = g_simple_async_result_new (G_OBJECT (data->unix_volume),
+ data->callback,
+ data->user_data,
+ NULL);
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+
+ g_source_remove (data->error_channel_source_id);
+ g_io_channel_unref (data->error_channel);
+ g_string_free (data->error_string, TRUE);
+ close (data->error_fd);
+ g_spawn_close_pid (pid);
+ g_free (data);
}
static gboolean
-g_unix_volume_unmount_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
+mount_read_error (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer user_data)
{
+ char *str;
+ gsize str_len;
+ MountOp *data = user_data;
+
+ g_io_channel_read_to_end (channel, &str, &str_len, NULL);
+ g_string_append (data->error_string, str);
+ g_free (str);
return TRUE;
}
static void
-g_unix_volume_eject (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+g_unix_volume_mount (GVolume *volume,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- /* TODO */
+ GUnixVolume *unix_volume = G_UNIX_VOLUME (volume);
+ MountOp *data;
+ GPid child_pid;
+ GError *error;
+ char *argv[] = {"mount", NULL, NULL};
+
+ if (unix_volume->mount_path != NULL)
+ argv[1] = unix_volume->mount_path;
+ else
+ argv[1] = unix_volume->device_path;
+
+ data = g_new0 (MountOp, 1);
+ data->unix_volume = unix_volume;
+ data->callback = callback;
+ data->user_data = user_data;
+ data->cancellable = cancellable;
+
+ error = NULL;
+ if (!g_spawn_async_with_pipes (NULL, /* working dir */
+ argv,
+ NULL, /* envp */
+ G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
+ NULL, /* child_setup */
+ NULL, /* user_data for child_setup */
+ &child_pid,
+ NULL, /* standard_input */
+ NULL, /* standard_output */
+ &(data->error_fd),
+ &error)) {
+ GSimpleAsyncResult *simple;
+ simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_volume),
+ data->callback,
+ data->user_data,
+ error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ g_error_free (error);
+ g_free (data);
+ return;
+ }
+ data->error_string = g_string_new ("");
+ data->error_channel = g_io_channel_unix_new (data->error_fd);
+ data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, mount_read_error, data);
+ g_child_watch_add (child_pid, mount_cb, data);
}
+
static gboolean
-g_unix_volume_eject_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
+g_unix_volume_mount_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
{
return TRUE;
}
static void
g_unix_volume_volume_iface_init (GVolumeIface *iface)
{
- iface->get_root = g_unix_volume_get_root;
iface->get_name = g_unix_volume_get_name;
iface->get_icon = g_unix_volume_get_icon;
iface->get_drive = g_unix_volume_get_drive;
- iface->can_unmount = g_unix_volume_can_unmount;
- iface->can_eject = g_unix_volume_can_eject;
- iface->unmount = g_unix_volume_unmount;
- iface->unmount_finish = g_unix_volume_unmount_finish;
- iface->eject = g_unix_volume_eject;
- iface->eject_finish = g_unix_volume_eject_finish;
+ iface->get_mount = g_unix_volume_get_mount;
+ iface->can_mount = g_unix_volume_can_mount;
+ iface->mount_fn = g_unix_volume_mount;
+ iface->mount_finish = g_unix_volume_mount_finish;
}
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#ifndef __G_UNIX_VOLUME_H__
GType _g_unix_volume_get_type (void) G_GNUC_CONST;
-GUnixVolume *_g_unix_volume_new (GUnixMount *mount,
- GUnixDrive *drive);
-gboolean _g_unix_volume_has_mountpoint (GUnixVolume *volume,
- const char *mountpoint);
-void _g_unix_volume_unset_drive (GUnixVolume *volume,
- GUnixDrive *drive);
-void _g_unix_volume_unmounted (GUnixVolume *volume);
+GUnixVolume *_g_unix_volume_new (GVolumeMonitor *volume_monitor,
+ GUnixMountPoint *mountpoint);
+gboolean _g_unix_volume_has_mount_path (GUnixVolume *volume,
+ const char *mount_path);
+void _g_unix_volume_set_mount (GUnixVolume *volume,
+ GUnixMount *mount);
+void _g_unix_volume_unset_mount (GUnixVolume *volume,
+ GUnixMount *mount);
+void _g_unix_volume_disconnected (GUnixVolume *volume);
G_END_DECLS
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
#include <glib.h>
#include "gunixvolumemonitor.h"
#include "gunixmounts.h"
+#include "gunixmount.h"
#include "gunixvolume.h"
-#include "gunixdrive.h"
-#include "gvolumeprivate.h"
+#include "gmountprivate.h"
#include "glibintl.h"
#include "gioalias.h"
GList *last_mountpoints;
GList *last_mounts;
- GList *drives;
GList *volumes;
+ GList *mounts;
};
-static void mountpoints_changed (GUnixMountMonitor *mount_monitor,
- gpointer user_data);
-static void mounts_changed (GUnixMountMonitor *mount_monitor,
- gpointer user_data);
-static void update_drives (GUnixVolumeMonitor *monitor);
-static void update_volumes (GUnixVolumeMonitor *monitor);
+static void mountpoints_changed (GUnixMountMonitor *mount_monitor,
+ gpointer user_data);
+static void mounts_changed (GUnixMountMonitor *mount_monitor,
+ gpointer user_data);
+static void update_volumes (GUnixVolumeMonitor *monitor);
+static void update_mounts (GUnixVolumeMonitor *monitor);
#define g_unix_volume_monitor_get_type _g_unix_volume_monitor_get_type
G_DEFINE_TYPE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR);
g_object_unref (monitor->mount_monitor);
+ g_list_foreach (monitor->last_mountpoints, (GFunc)g_unix_mount_point_free, NULL);
+ g_list_free (monitor->last_mountpoints);
g_list_foreach (monitor->last_mounts, (GFunc)g_unix_mount_free, NULL);
g_list_free (monitor->last_mounts);
g_list_foreach (monitor->volumes, (GFunc)g_object_unref, NULL);
g_list_free (monitor->volumes);
- g_list_foreach (monitor->drives, (GFunc)g_object_unref, NULL);
- g_list_free (monitor->drives);
+ g_list_foreach (monitor->mounts, (GFunc)g_object_unref, NULL);
+ g_list_free (monitor->mounts);
if (G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->finalize)
(*G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->finalize) (object);
}
static GList *
-get_mounted_volumes (GVolumeMonitor *volume_monitor)
+get_mounts (GVolumeMonitor *volume_monitor)
{
GUnixVolumeMonitor *monitor;
GList *l;
monitor = G_UNIX_VOLUME_MONITOR (volume_monitor);
- l = g_list_copy (monitor->volumes);
+ l = g_list_copy (monitor->mounts);
g_list_foreach (l, (GFunc)g_object_ref, NULL);
return l;
}
static GList *
-get_connected_drives (GVolumeMonitor *volume_monitor)
+get_volumes (GVolumeMonitor *volume_monitor)
{
GUnixVolumeMonitor *monitor;
GList *l;
monitor = G_UNIX_VOLUME_MONITOR (volume_monitor);
- l = g_list_copy (monitor->drives);
+ l = g_list_copy (monitor->volumes);
g_list_foreach (l, (GFunc)g_object_ref, NULL);
return l;
}
-static GVolume *
-get_volume_for_mountpoint (const char *mountpoint)
+static GList *
+get_connected_drives (GVolumeMonitor *volume_monitor)
{
+ return NULL;
+}
+
+static GMount *
+get_mount_for_mount_path (const char *mount_path)
+{
+ GUnixMountEntry *mount_entry;
GUnixMount *mount;
- GUnixVolume *volume;
- mount = g_get_unix_mount_at (mountpoint, NULL);
+ mount_entry = g_get_unix_mount_at (mount_path, NULL);
- /* TODO: Set drive? */
- volume = _g_unix_volume_new (mount, NULL);
+ /* TODO: Set mountable volume? */
+ mount = _g_unix_mount_new (NULL, mount_entry, NULL);
- return G_VOLUME (volume);
+ return G_MOUNT (mount);
}
static void
gobject_class->finalize = g_unix_volume_monitor_finalize;
- monitor_class->get_mounted_volumes = get_mounted_volumes;
+ monitor_class->get_mounts = get_mounts;
+ monitor_class->get_volumes = get_volumes;
monitor_class->get_connected_drives = get_connected_drives;
native_class->priority = 0;
- native_class->get_volume_for_mountpoint = get_volume_for_mountpoint;
+ native_class->get_mount_for_mount_path = get_mount_for_mount_path;
}
static void
{
GUnixVolumeMonitor *unix_monitor = user_data;
- /* Update both to make sure drives are created before volumes */
- update_drives (unix_monitor);
+ /* Update both to make sure volumes are created before mounts */
update_volumes (unix_monitor);
+ update_mounts (unix_monitor);
}
static void
{
GUnixVolumeMonitor *unix_monitor = user_data;
- /* Update both to make sure drives are created before volumes */
- update_drives (unix_monitor);
+ /* Update both to make sure volumes are created before mounts */
update_volumes (unix_monitor);
+ update_mounts (unix_monitor);
}
static void
"mountpoints_changed", G_CALLBACK (mountpoints_changed),
unix_monitor);
- update_drives (unix_monitor);
update_volumes (unix_monitor);
-
+ update_mounts (unix_monitor);
}
/**
}
/**
- * g_unix_volume_lookup_drive_for_mountpoint:
+ * _g_unix_volume_monitor_lookup_volume_for_mount_path:
* @monitor:
- * @mountpoint:
+ * @mount_path:
*
- * Returns: #GUnixDrive for the given @mountpoint.
+ * Returns: #GUnixVolume for the given @mount_path.
**/
-GUnixDrive *
-_g_unix_volume_monitor_lookup_drive_for_mountpoint (GUnixVolumeMonitor *monitor,
- const char *mountpoint)
+GUnixVolume *
+_g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor,
+ const char *mount_path)
{
GList *l;
- for (l = monitor->drives; l != NULL; l = l->next)
+ for (l = monitor->volumes; l != NULL; l = l->next)
{
- GUnixDrive *drive = l->data;
+ GUnixVolume *volume = l->data;
- if (_g_unix_drive_has_mountpoint (drive, mountpoint))
- return drive;
+ if (_g_unix_volume_has_mount_path (volume, mount_path))
+ return volume;
}
return NULL;
}
-static GUnixVolume *
-find_volume_by_mountpoint (GUnixVolumeMonitor *monitor,
- const char *mountpoint)
+static GUnixMount *
+find_mount_by_mountpath (GUnixVolumeMonitor *monitor,
+ const char *mount_path)
{
GList *l;
- for (l = monitor->volumes; l != NULL; l = l->next)
+ for (l = monitor->mounts; l != NULL; l = l->next)
{
- GUnixVolume *volume = l->data;
+ GUnixMount *mount = l->data;
- if (_g_unix_volume_has_mountpoint (volume, mountpoint))
- return volume;
+ if (_g_unix_mount_has_mount_path (mount, mount_path))
+ return mount;
}
return NULL;
}
static void
-update_drives (GUnixVolumeMonitor *monitor)
+update_volumes (GUnixVolumeMonitor *monitor)
{
GList *new_mountpoints;
GList *removed, *added;
GList *l;
- GUnixDrive *drive;
+ GUnixVolume *volume;
new_mountpoints = g_get_unix_mount_points (NULL);
{
GUnixMountPoint *mountpoint = l->data;
- drive = _g_unix_volume_monitor_lookup_drive_for_mountpoint (monitor,
- g_unix_mount_point_get_mount_path (mountpoint));
- if (drive)
+ volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor,
+ g_unix_mount_point_get_mount_path (mountpoint));
+ if (volume)
{
- _g_unix_drive_disconnected (drive);
- monitor->drives = g_list_remove (monitor->drives, drive);
- g_signal_emit_by_name (monitor, "drive_disconnected", drive);
- g_object_unref (drive);
+ _g_unix_volume_disconnected (volume);
+ monitor->volumes = g_list_remove (monitor->volumes, volume);
+ g_signal_emit_by_name (monitor, "volume_removed", volume);
+ g_object_unref (volume);
}
}
{
GUnixMountPoint *mountpoint = l->data;
- drive = _g_unix_drive_new (G_VOLUME_MONITOR (monitor), mountpoint);
- if (drive)
+ volume = _g_unix_volume_new (G_VOLUME_MONITOR (monitor), mountpoint);
+ if (volume)
{
- monitor->drives = g_list_prepend (monitor->drives, drive);
- g_signal_emit_by_name (monitor, "drive_connected", drive);
+ monitor->volumes = g_list_prepend (monitor->volumes, volume);
+ g_signal_emit_by_name (monitor, "volume_added", volume);
}
}
}
static void
-update_volumes (GUnixVolumeMonitor *monitor)
+update_mounts (GUnixVolumeMonitor *monitor)
{
GList *new_mounts;
GList *removed, *added;
GList *l;
+ GUnixMount *mount;
GUnixVolume *volume;
- GUnixDrive *drive;
const char *mount_path;
new_mounts = g_get_unix_mounts (NULL);
for (l = removed; l != NULL; l = l->next)
{
- GUnixMount *mount = l->data;
+ GUnixMountEntry *mount_entry = l->data;
- volume = find_volume_by_mountpoint (monitor, g_unix_mount_get_mount_path (mount));
- if (volume)
+ g_warning ("%s %s removed",
+ g_unix_mount_get_mount_path (mount_entry),
+ g_unix_mount_get_device_path (mount_entry));
+
+ mount = find_mount_by_mountpath (monitor, g_unix_mount_get_mount_path (mount_entry));
+ if (mount)
{
- _g_unix_volume_unmounted (volume);
- monitor->volumes = g_list_remove (monitor->volumes, volume);
- g_signal_emit_by_name (monitor, "volume_unmounted", volume);
- g_object_unref (volume);
+ _g_unix_mount_unmounted (mount);
+ monitor->mounts = g_list_remove (monitor->mounts, mount);
+ g_signal_emit_by_name (monitor, "mount_removed", mount);
+ g_object_unref (mount);
}
}
for (l = added; l != NULL; l = l->next)
{
- GUnixMount *mount = l->data;
+ GUnixMountEntry *mount_entry = l->data;
- mount_path = g_unix_mount_get_mount_path (mount);
+ mount_path = g_unix_mount_get_mount_path (mount_entry);
- drive = _g_unix_volume_monitor_lookup_drive_for_mountpoint (monitor,
- mount_path);
- volume = _g_unix_volume_new (mount, drive);
- if (volume)
+ volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, mount_path);
+ mount = _g_unix_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume);
+ if (mount)
{
- monitor->volumes = g_list_prepend (monitor->volumes, volume);
- g_signal_emit_by_name (monitor, "volume_mounted", volume);
+ monitor->mounts = g_list_prepend (monitor->mounts, mount);
+ g_signal_emit_by_name (monitor, "mount_added", mount);
}
}
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#ifndef __G_UNIX_VOLUME_MONITOR_H__
typedef struct _GUnixVolumeMonitorClass GUnixVolumeMonitorClass;
/* Forward definitions */
+typedef struct _GUnixMount GUnixMount;
typedef struct _GUnixVolume GUnixVolume;
-typedef struct _GUnixDrive GUnixDrive;
struct _GUnixVolumeMonitorClass {
GNativeVolumeMonitorClass parent_class;
GType _g_unix_volume_monitor_get_type (void) G_GNUC_CONST;
-GVolumeMonitor *_g_unix_volume_monitor_new (void);
-GUnixDrive * _g_unix_volume_monitor_lookup_drive_for_mountpoint (GUnixVolumeMonitor *monitor,
- const char *mountpoint);
+GVolumeMonitor * _g_unix_volume_monitor_new (void);
+GUnixVolume * _g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor,
+ const char *mount_path);
G_END_DECLS
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
+#include "gmount.h"
#include "gvolume.h"
-#include "gvolumeprivate.h"
#include "gsimpleasyncresult.h"
#include "glibintl.h"
#include "gioalias.h"
/**
- * SECTION:gvolume
- * @short_description: mounted volume management
+ * SECTION:volume
+ * @short_description: volume management
*
- * Class for managing mounted volumes.
- *
- * Unmounting volumes is an asynchronous operation. For more information about
- * asynchronous operations, see #GAsyncReady and #GSimpleAsyncReady. To unmount a volume,
- * first call g_volume_unmount() with (at least) the volume and a #GAsyncReadyCallback.
- * The callback will be fired when the operation has resolved (either with success or failure),
- * and a #GAsyncReady structure will be passed to the callback.
- * That callback should then call g_volume_unmount_finish() with
- * the volume and the #GAsyncReady data to see if the operation was completed successfully.
- * If an @error is present when g_volume_unmount_finish() is called, then it will
- * be filled with any error information.
- *
- * Ejecting volumes is also an asynchronous operation.
- * To eject a volume, call g_volume_eject() with (at least) the volume to eject
- * and a #GAsyncReadyCallback. The callback will be fired when the eject operation
- * has resolved (either with success or failure), and a #GAsyncReady structure will
- * be passed to the callback. That callback should then call g_volume_eject_finish()
- * with the volume and the #GAsyncReady data to determine if the operation was completed
- * successfully. If an @error is present when g_volume_eject_finish() is called, then
- * it will be filled with any error information.
+ * The #GVolume interface represents user-visible objects that can be
+ * mounted. Note, when porting from GnomeVFS, #GVolume is the moral
+ * equivalent of #GnomeVFSDrive.
*
+ * Mounting a #GVolume instance is an asynchronous operation. For more
+ * information about asynchronous operations, see #GAsyncReady and
+ * #GSimpleAsyncReady. To mount a #GVolume, first call
+ * g_volume_mount() with (at least) the #GVolume instane, a
+ * #GMountOperation object and a #GAsyncReadyCallback. The callback
+ * will be fired when the operation has resolved (either with success
+ * or failure), and a #GAsyncReady structure will be passed to the
+ * callback. That callback should then call g_volume_mount_finish()
+ * with the #GVolume instance and the #GAsyncReady data to see if the
+ * operation was completed successfully. If an @error is present when
+ * g_volume_mount_finish() is called, then it will be filled with any
+ * error information.
**/
static void g_volume_base_init (gpointer g_class);
static void g_volume_class_init (gpointer g_class,
- gpointer class_data);
+ gpointer class_data);
GType
g_volume_get_type (void)
static void
g_volume_class_init (gpointer g_class,
- gpointer class_data)
+ gpointer class_data)
{
}
}
/**
- * g_volume_get_root:
- * @volume: a #GVolume.
- *
- * Gets the root directory on @volume.
- *
- * Returns: a #GFile.
- **/
-GFile *
-g_volume_get_root (GVolume *volume)
-{
- GVolumeIface *iface;
-
- g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
-
- iface = G_VOLUME_GET_IFACE (volume);
-
- return (* iface->get_root) (volume);
-}
-
-/**
* g_volume_get_name:
* @volume: a #GVolume.
*
*
* Gets the drive for the @volume.
*
- * Returns: a #GDrive.
+ * Returns: a #GDrive or %NULL if @volume is not associated with a drive.
**/
GDrive *
g_volume_get_drive (GVolume *volume)
}
/**
- * g_volume_can_unmount:
+ * g_volume_get_mount:
* @volume: a #GVolume.
*
- * Checks if @volume can be mounted.
+ * Gets the mount for the @volume.
*
- * Returns: %TRUE if the @volume can be unmounted.
+ * Returns: a #GMount or %NULL if @volume isn't mounted.
**/
-gboolean
-g_volume_can_unmount (GVolume *volume)
+GMount *
+g_volume_get_mount (GVolume *volume)
{
GVolumeIface *iface;
- g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
+ g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
iface = G_VOLUME_GET_IFACE (volume);
- return (* iface->can_unmount) (volume);
+ return (* iface->get_mount) (volume);
}
+
/**
- * g_volume_can_eject:
+ * g_volume_can_mount:
* @volume: a #GVolume.
*
- * Checks if @volume can be ejected.
+ * Checks if a volume can be mounted.
*
- * Returns: %TRUE if the @volume can be ejected.
+ * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise.
**/
gboolean
-g_volume_can_eject (GVolume *volume)
+g_volume_can_mount (GVolume *volume)
{
GVolumeIface *iface;
iface = G_VOLUME_GET_IFACE (volume);
- return (* iface->can_eject) (volume);
-}
-
-/**
- * g_volume_unmount:
- * @volume: a #GVolume.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
- * @callback: a #GAsyncReadyCallback.
- * @user_data: user data passed to @callback.
- *
- * Unmounts a volume. This is an asynchronous operation, and is
- * finished by calling g_volume_unmount_finish() with the @volume
- * and #GAsyncResults data returned in the @callback.
- **/
-void
-g_volume_unmount (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GVolumeIface *iface;
-
- g_return_if_fail (G_IS_VOLUME (volume));
-
- iface = G_VOLUME_GET_IFACE (volume);
-
- if (iface->unmount == NULL)
- {
- g_simple_async_report_error_in_idle (G_OBJECT (volume),
- callback, user_data,
- G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("volume doesn't implement unmount"));
-
- return;
- }
-
- (* iface->unmount) (volume, cancellable, callback, user_data);
-}
+ if (iface->can_mount == NULL)
+ return FALSE;
-/**
- * g_volume_unmount_finish:
- * @volume: a #GVolume.
- * @result: a #GAsyncResult.
- * @error: a #GError location to store the error occuring, or %NULL to
- * ignore.
- *
- * Finishes unmounting a volume. If any errors occured during the operation,
- * @error will be set to contain the errors and %FALSE will be returned.
- *
- * Returns: %TRUE if the volume was successfully unmounted. %FALSE otherwise.
- **/
-gboolean
-g_volume_unmount_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
-{
- GVolumeIface *iface;
-
- g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
-
- if (G_IS_SIMPLE_ASYNC_RESULT (result))
- {
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
- }
-
- iface = G_VOLUME_GET_IFACE (volume);
- return (* iface->unmount_finish) (volume, result, error);
+ return (* iface->can_mount) (volume);
}
/**
- * g_volume_eject:
+ * g_volume_mount:
* @volume: a #GVolume.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @mount_operation: a #GMountOperation.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback.
- * @user_data: user data passed to @callback.
+ * @user_data: a #gpointer.
*
- * Ejects a volume. This is an asynchronous operation, and is
- * finished by calling g_volume_eject_finish() from the @callback
- * with the @volume and #GAsyncResults returned in the callback.
+ * Mounts a volume.
**/
void
-g_volume_eject (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+g_volume_mount (GVolume *volume,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GVolumeIface *iface;
g_return_if_fail (G_IS_VOLUME (volume));
+ g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
iface = G_VOLUME_GET_IFACE (volume);
- if (iface->eject == NULL)
+ if (iface->mount_fn == NULL)
{
- g_simple_async_report_error_in_idle (G_OBJECT (volume),
- callback, user_data,
+ g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("volume doesn't implement eject"));
+ _("volume doesn't implement mount"));
return;
}
- (* iface->eject) (volume, cancellable, callback, user_data);
+ (* iface->mount_fn) (volume, mount_operation, cancellable, callback, user_data);
}
/**
- * g_volume_eject_finish:
- * @volume: a #GVolume.
+ * g_volume_mount_finish:
+ * @volume: pointer to a #GVolume.
* @result: a #GAsyncResult.
- * @error: a #GError location to store the error occuring, or %NULL to
- * ignore.
+ * @error: a #GError.
*
- * Finishes ejecting the volume. If any errors occured during the operation,
- * @error will be set to contain the errors and %FALSE will be returned.
+ * Finishes mounting a volume.
*
- * Returns: %TRUE if the volume was successfully ejected. %FALSE otherwise.
+ * Returns: %TRUE, %FALSE if operation failed.
**/
gboolean
-g_volume_eject_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
+g_volume_mount_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
{
GVolumeIface *iface;
}
iface = G_VOLUME_GET_IFACE (volume);
- return (* iface->eject_finish) (volume, result, error);
+ return (* iface->mount_finish) (volume, result, error);
}
#define __G_VOLUME_C__
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#ifndef __G_VOLUME_H__
#include <glib-object.h>
#include <gio/gfile.h>
+#include <gio/gdrive.h>
G_BEGIN_DECLS
#define G_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_VOLUME))
#define G_VOLUME_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_VOLUME, GVolumeIface))
-/* GVolume typedef is in gfile.h due to include order issues */
-/**
- * GDrive:
- *
- * Opaque drive object.
- **/
-typedef struct _GDrive GDrive; /* Dummy typedef */
-typedef struct _GVolumeIface GVolumeIface;
-
/**
* GVolumeIface:
* @g_iface: The parent interface.
* @changed: Changed signal that is emitted when the volume's state has changed.
- * @get_root: Gets a #GFile to the root directory of the #GVolume.
* @get_name: Gets a string containing the name of the #GVolume.
* @get_icon: Gets a #GIcon for the #GVolume.
- * @get_drive: Gets a #GDrive the volume is located on.
- * @can_unmount: Checks if a #GVolume can be unmounted.
- * @can_eject: Checks if a #GVolume can be ejected.
- * @unmount: Starts unmounting a #GVolume.
- * @unmount_finish: Finishes an unmounting operation.
- * @eject: Starts ejecting a #GVolume.
- * @eject_finish: Finishes an eject operation.
+ * @get_drive: Gets a #GDrive the volume is located on. Returns %NULL if the #GVolume is not associated with a #GDrive.
+ * @get_mount: Gets a #GMount representing the mounted volume. Returns %NULL if the #GVolume is not mounted.
+ * @can_mount: Returns %TRUE if the #GVolume can be mounted.
+ * @mount: Mounts a given #GVolume.
+ * @mount_finish: Finishes a mount operation.
*
- * Interface for implementing operations for mounted volumes.
+ * Interface for implementing operations for mountable volumes.
**/
+typedef struct _GVolumeIface GVolumeIface;
+
struct _GVolumeIface
{
GTypeInterface g_iface;
/* Virtual Table */
- GFile * (*get_root) (GVolume *volume);
- char * (*get_name) (GVolume *volume);
- GIcon * (*get_icon) (GVolume *volume);
- GDrive * (*get_drive) (GVolume *volume);
- gboolean (*can_unmount) (GVolume *volume);
- gboolean (*can_eject) (GVolume *volume);
- void (*unmount) (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gboolean (*unmount_finish) (GVolume *volume,
- GAsyncResult *result,
- GError **error);
- void (*eject) (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gboolean (*eject_finish) (GVolume *volume,
- GAsyncResult *result,
- GError **error);
+ char * (*get_name) (GVolume *volume);
+ GIcon * (*get_icon) (GVolume *volume);
+ GDrive * (*get_drive) (GVolume *volume);
+ GMount * (*get_mount) (GVolume *volume);
+ gboolean (*can_mount) (GVolume *volume);
+ void (*mount_fn) (GVolume *volume,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*mount_finish) (GVolume *volume,
+ GAsyncResult *result,
+ GError **error);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_g_reserved1) (void);
+ void (*_g_reserved2) (void);
+ void (*_g_reserved3) (void);
+ void (*_g_reserved4) (void);
+ void (*_g_reserved5) (void);
+ void (*_g_reserved6) (void);
+ void (*_g_reserved7) (void);
+ void (*_g_reserved8) (void);
};
-GType g_volume_get_type (void) G_GNUC_CONST;
+GType g_volume_get_type (void) G_GNUC_CONST;
-GFile *g_volume_get_root (GVolume *volume);
-char * g_volume_get_name (GVolume *volume);
-GIcon * g_volume_get_icon (GVolume *volume);
-GDrive * g_volume_get_drive (GVolume *volume);
-gboolean g_volume_can_unmount (GVolume *volume);
-gboolean g_volume_can_eject (GVolume *volume);
-void g_volume_unmount (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean g_volume_unmount_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error);
-void g_volume_eject (GVolume *volume,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean g_volume_eject_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error);
+char * g_volume_get_name (GVolume *volume);
+GIcon * g_volume_get_icon (GVolume *volume);
+GDrive * g_volume_get_drive (GVolume *volume);
+GMount * g_volume_get_mount (GVolume *volume);
+gboolean g_volume_can_mount (GVolume *volume);
+void g_volume_mount (GVolume *volume,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean g_volume_mount_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
G_DEFINE_TYPE (GVolumeMonitor, g_volume_monitor, G_TYPE_OBJECT);
enum {
- VOLUME_MOUNTED,
- VOLUME_PRE_UNMOUNT,
- VOLUME_UNMOUNTED,
+ VOLUME_ADDED,
+ VOLUME_REMOVED,
+ VOLUME_CHANGED,
+ MOUNT_ADDED,
+ MOUNT_REMOVED,
+ MOUNT_PRE_UNMOUNT,
+ MOUNT_CHANGED,
DRIVE_CONNECTED,
DRIVE_DISCONNECTED,
+ DRIVE_CHANGED,
LAST_SIGNAL
};
gobject_class->finalize = g_volume_monitor_finalize;
/**
- * GVolumeMonitor::volume-mounted:
+ * GVolumeMonitor::volume-added:
* @volume_monitor: The volume monitor emitting the signal.
- * @volume: the volume that was mounted.
- *
- * Emitted when a volume is mounted.
+ * @volume: a #GVolume that was added.
+ *
+ * Emitted when a mountable volume is added to the system.
**/
- signals[VOLUME_MOUNTED] = g_signal_new (I_("volume_mounted"),
- G_TYPE_VOLUME_MONITOR,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVolumeMonitorClass, volume_mounted),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_VOLUME);
+ signals[VOLUME_ADDED] = g_signal_new (I_("volume_added"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, volume_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_VOLUME);
+
/**
- * GVolumeMonitor::volume-pre-unmount:
+ * GVolumeMonitor::volume-removed:
* @volume_monitor: The volume monitor emitting the signal.
- * @volume: the volume that is being unmounted.
- *
- * Emitted when a volume is about to be unmounted.
- **/
- signals[VOLUME_PRE_UNMOUNT] = g_signal_new (I_("volume_pre_unmount"),
- G_TYPE_VOLUME_MONITOR,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVolumeMonitorClass, volume_pre_unmount),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_VOLUME);
+ * @volume: a #GVolume that was removed.
+ *
+ * Emitted when a mountable volume is removed from the system.
+ **/
+ signals[VOLUME_REMOVED] = g_signal_new (I_("volume_removed"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, volume_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_VOLUME);
+
/**
- * GVolumeMonitor::volume-unmounted:
+ * GVolumeMonitor::volume-changed:
* @volume_monitor: The volume monitor emitting the signal.
- * @volume: the volume that was unmounted.
+ * @volume: a #GVolume that changed.
*
- * Emitted when a volume is unmounted.
+ * Emitted when mountable volume is changed.
**/
- signals[VOLUME_UNMOUNTED] = g_signal_new (I_("volume_unmounted"),
- G_TYPE_VOLUME_MONITOR,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVolumeMonitorClass, volume_unmounted),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_VOLUME);
+ signals[VOLUME_CHANGED] = g_signal_new (I_("volume_changed"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, volume_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_VOLUME);
+
+ /**
+ * GVolumeMonitor::mount-added:
+ * @volume_monitor: The volume monitor emitting the signal.
+ * @mount: a #GMount that was added.
+ *
+ * Emitted when a mount is added.
+ **/
+ signals[MOUNT_ADDED] = g_signal_new (I_("mount_added"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, mount_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_MOUNT);
+
+ /**
+ * GVolumeMonitor::mount-removed:
+ * @volume_monitor: The volume monitor emitting the signal.
+ * @mount: a #GMount that was removed.
+ *
+ * Emitted when a mount is removed.
+ **/
+ signals[MOUNT_REMOVED] = g_signal_new (I_("mount_removed"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, mount_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_MOUNT);
+
+ /**
+ * GVolumeMonitor::mount-pre-unmount:
+ * @volume_monitor: The volume monitor emitting the signal.
+ * @mount: a #GMount that is being unmounted.
+ *
+ * Emitted when a mount is about to be removed.
+ **/
+ signals[MOUNT_PRE_UNMOUNT] = g_signal_new (I_("mount_pre_unmount"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, mount_pre_unmount),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_MOUNT);
+
+ /**
+ * GVolumeMonitor::mount-changed:
+ * @volume_monitor: The volume monitor emitting the signal.
+ * @mount: a #GMount that changed.
+ *
+ * Emitted when a mount changes.
+ **/
+ signals[MOUNT_CHANGED] = g_signal_new (I_("mount_changed"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, mount_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_MOUNT);
+
/**
* GVolumeMonitor::drive-connected:
* @volume_monitor: The volume monitor emitting the signal.
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_DRIVE);
+
+ /**
+ * GVolumeMonitor::drive-changed:
+ * @volume_monitor: The volume monitor emitting the signal.
+ * @drive: the drive that changed
+ *
+ * Emitted when a drive changes.
+ **/
+ signals[DRIVE_CHANGED] = g_signal_new (I_("drive_changed"),
+ G_TYPE_VOLUME_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeMonitorClass, drive_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_DRIVE);
+
}
static void
{
}
+
/**
- * g_volume_monitor_get_mounted_volumes:
+ * g_volume_monitor_get_drives:
* @volume_monitor: a #GVolumeMonitor.
*
- * Gets a list of volumes mounted on the computer.
+ * Gets a list of drives connected to the system.
*
- * Returns: a #GList of mounted #GVolumes.
+ * Returns: a #GList of connected #GDrives.
**/
GList *
-g_volume_monitor_get_mounted_volumes (GVolumeMonitor *volume_monitor)
+g_volume_monitor_get_connected_drives (GVolumeMonitor *volume_monitor)
{
GVolumeMonitorClass *class;
class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
- return class->get_mounted_volumes (volume_monitor);
+ return class->get_connected_drives (volume_monitor);
}
/**
- * g_volume_monitor_get_connected_drives:
+ * g_volume_monitor_get_volumes:
* @volume_monitor: a #GVolumeMonitor.
*
- * Gets a list of drives connected to the computer.
+ * Gets a list of the volumes on the system.
*
- * Returns: a #GList of connected #GDrives.
+ * Returns: a #GList of #GVolume.
**/
GList *
-g_volume_monitor_get_connected_drives (GVolumeMonitor *volume_monitor)
+g_volume_monitor_get_volumes (GVolumeMonitor *volume_monitor)
{
GVolumeMonitorClass *class;
class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
- return class->get_connected_drives (volume_monitor);
+ return class->get_volumes (volume_monitor);
+}
+
+/**
+ * g_volume_monitor_get_mounts:
+ * @volume_monitor: a #GVolumeMonitor.
+ *
+ * Gets a list of the mounts on the system.
+ *
+ * Returns: a #GList of #GMount.
+ **/
+GList *
+g_volume_monitor_get_mounts (GVolumeMonitor *volume_monitor)
+{
+ GVolumeMonitorClass *class;
+
+ g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL);
+
+ class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
+
+ return class->get_mounts (volume_monitor);
}
#define __G_VOLUME_MONITOR_C__
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
+ * David Zeuthen <davidz@redhat.com>
*/
#ifndef __G_VOLUME_MONITOR_H__
#define __G_VOLUME_MONITOR_H__
#include <glib-object.h>
+#include <gio/gmount.h>
#include <gio/gvolume.h>
#include <gio/gdrive.h>
/*< public >*/
/* signals */
- void (* volume_mounted) (GVolumeMonitor *volume_monitor,
- GVolume *volume);
- void (* volume_pre_unmount) (GVolumeMonitor *volume_monitor,
- GVolume *volume);
- void (* volume_unmounted) (GVolumeMonitor *volume_monitor,
- GVolume *volume);
- void (* drive_connected) (GVolumeMonitor *volume_monitor,
+ void (* volume_added) (GVolumeMonitor *volume_monitor,
+ GVolume *volume);
+ void (* volume_removed) (GVolumeMonitor *volume_monitor,
+ GVolume *volume);
+ void (* volume_changed) (GVolumeMonitor *volume_monitor,
+ GVolume *volume);
+
+ void (* mount_added) (GVolumeMonitor *volume_monitor,
+ GMount *mount);
+ void (* mount_removed) (GVolumeMonitor *volume_monitor,
+ GMount *mount);
+ void (* mount_pre_unmount) (GVolumeMonitor *volume_monitor,
+ GMount *mount);
+ void (* mount_changed) (GVolumeMonitor *volume_monitor,
+ GMount *mount);
+
+ void (* drive_connected) (GVolumeMonitor *volume_monitor,
GDrive *drive);
- void (* drive_disconnected) (GVolumeMonitor *volume_monitor,
+ void (* drive_disconnected) (GVolumeMonitor *volume_monitor,
+ GDrive *drive);
+ void (* drive_changed) (GVolumeMonitor *volume_monitor,
GDrive *drive);
/* Vtable */
- GList * (*get_mounted_volumes) (GVolumeMonitor *volume_monitor);
- GList * (*get_connected_drives) (GVolumeMonitor *volume_monitor);
+ GList * (*get_connected_drives) (GVolumeMonitor *volume_monitor);
+ GList * (*get_volumes) (GVolumeMonitor *volume_monitor);
+ GList * (*get_mounts) (GVolumeMonitor *volume_monitor);
/*< private >*/
/* Padding for future expansion */
GType g_volume_monitor_get_type (void) G_GNUC_CONST;
-GVolumeMonitor *g_volume_monitor_get (void);
-GList * g_volume_monitor_get_mounted_volumes (GVolumeMonitor *volume_monitor);
+GVolumeMonitor *g_volume_monitor_get (void);
GList * g_volume_monitor_get_connected_drives (GVolumeMonitor *volume_monitor);
+GList * g_volume_monitor_get_volumes (GVolumeMonitor *volume_monitor);
+GList * g_volume_monitor_get_mounts (GVolumeMonitor *volume_monitor);
G_END_DECLS