Author: benny Date: 2007-01-06 22:23:47 +0000 (Sat, 06 Jan 2007) New Revision: 24278
Modified: libexo/trunk/ChangeLog libexo/trunk/configure.in.in libexo/trunk/exo-mount-notify/main.c libexo/trunk/exo-mount/exo-mount-fstab.c libexo/trunk/exo-mount/exo-mount-utils.c libexo/trunk/exo-mount/exo-mount-utils.h libexo/trunk/exo-mount/main.c Log: 2007-01-06 Benedikt Meurer <[EMAIL PROTECTED]> * exo-mount-notify/main.c(signal_io_func): Do not block Thunar's unmount operation waiting for the last notification to go away. * configure.in.in, exo-mount/: Be smarter when checking device files for equality, comparing them by their major/minor device ids instead of their paths. Modified: libexo/trunk/ChangeLog =================================================================== --- libexo/trunk/ChangeLog 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/ChangeLog 2007-01-06 22:23:47 UTC (rev 24278) @@ -1,5 +1,14 @@ 2007-01-06 Benedikt Meurer <[EMAIL PROTECTED]> + * exo-mount-notify/main.c(signal_io_func): Do not block Thunar's + unmount operation waiting for the last notification to go + away. + * configure.in.in, exo-mount/: Be smarter when checking device files + for equality, comparing them by their major/minor device ids instead + of their paths. + +2007-01-06 Benedikt Meurer <[EMAIL PROTECTED]> + * exo-mount/exo-mount-fstab.c: Add missing <errno.h> include. 2007-01-06 Benedikt Meurer <[EMAIL PROTECTED]> Modified: libexo/trunk/configure.in.in =================================================================== --- libexo/trunk/configure.in.in 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/configure.in.in 2007-01-06 22:23:47 UTC (rev 24278) @@ -115,7 +115,7 @@ dnl *** Check for standard functions *** dnl ************************************ AC_FUNC_MMAP() -AC_CHECK_FUNCS([getfsspec getfsstat getmntent regexec setmntent]) +AC_CHECK_FUNCS([getfsstat getmntent regexec setfsent setmntent]) dnl ****************************************** dnl *** Check for Message Digest functions *** Modified: libexo/trunk/exo-mount/exo-mount-fstab.c =================================================================== --- libexo/trunk/exo-mount/exo-mount-fstab.c 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/exo-mount/exo-mount-fstab.c 2007-01-06 22:23:47 UTC (rev 24278) @@ -138,7 +138,6 @@ #if defined(HAVE_SETMNTENT) /* Linux */ struct mntent *mntent; - gchar *resolved; FILE *fp; /* try to open the fstab file */ @@ -160,26 +159,14 @@ break; /* check if this entry matches */ - if (strcmp (device_file, mntent->mnt_fsname) == 0) - { - /* exakt match, nice */ - path = g_strdup (mntent->mnt_dir); - } - else - { - /* but maybe the fstab entry is a symlink */ - resolved = exo_mount_utils_resolve (mntent->mnt_fsname); - if (strcmp (device_file, resolved) == 0) - path = g_strdup (mntent->mnt_dir); - g_free (resolved); - } + if (exo_mount_utils_is_same_device (device_file, mntent->mnt_fsname)) + path = g_strdup (mntent->mnt_dir); } /* close the file handle */ endmntent (fp); #elif defined(HAVE_GETMNTENT) /* Solaris */ struct mnttab mntent; - gchar *resolved; FILE *fp; /* try to open the fstab file */ @@ -200,46 +187,50 @@ break; /* check if this entry matches */ - if (strcmp (device_file, mntent.mnt_special) == 0) - { - /* exakt match, nice */ - path = g_strdup (mntent.mnt_mountp); - } - else - { - /* but maybe the fstab entry is a symlink */ - resolved = exo_mount_utils_resolve (mntent.mnt_special); - if (strcmp (device_file, resolved) == 0) - path = g_strdup (mntent.mnt_mountp); - g_free (resolved); - } + if (exo_mount_utils_is_same_device (device_file, mntent.mnt_special)) + path = g_strdup (mntent.mnt_mountp); } /* close the file handle */ fclose (fp); -#elif defined(HAVE_GETFSSPEC) /* FreeBSD */ +#elif defined(HAVE_SETFSENT) /* FreeBSD */ struct fstab *fs; - /* look up the entry for the device file, - * fortunately FreeBSD isn't playing the - * weird symlink tricks for most devices, - * so we don't need the damn stupid Linux - * symlink resolving stuff here... - */ - fs = getfsspec (device_file); - if (G_LIKELY (fs != NULL)) + /* open the fstab file */ + if (setfsent () == 0) { + g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), + _("Failed to open file \"%s\": %s"), _PATH_FSTAB, + g_strerror (errno)); + return NULL; + } + + /* look up an entry for our device file */ + while (path == NULL) + { + /* grab the next entry */ + fs = getfsent (); + if (fs == NULL) + break; + /* check if this is a usable file system */ - if (strcmp (fs->fs_type, FSTAB_SW) != 0 + if (strcmp (fs->fs_type, FSTAB_SW) == 0 #ifdef FSTAB_DP - && strcmp (fs->fs_type, FSTAB_DP) != 0 + || strcmp (fs->fs_type, FSTAB_DP) == 0 #endif - && strcmp (fs->fs_type, FSTAB_XX) != 0) + || strcmp (fs->fs_type, FSTAB_XX) == 0) { - /* jap, usable file system */ - path = g_strdup (fs->fs_file); + /* skip this one then */ + continue; } + + /* check if this entry matches */ + if (exo_mount_utils_is_same_device (device_file, fs->fs_spec)) + path = g_strdup (fs->fs_file); } + + /* close the file handle */ + endfsent (); #else #error "Add support for your operating system here." #endif Modified: libexo/trunk/exo-mount/exo-mount-utils.c =================================================================== --- libexo/trunk/exo-mount/exo-mount-utils.c 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/exo-mount/exo-mount-utils.c 2007-01-06 22:23:47 UTC (rev 24278) @@ -21,6 +21,9 @@ #include <config.h> #endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif @@ -33,6 +36,9 @@ #ifdef HAVE_SYS_MOUNT_H #include <sys/mount.h> #endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif #ifdef HAVE_MEMORY_H #include <memory.h> @@ -49,19 +55,20 @@ -static void exo_mount_utils_canonicalize_filename (gchar *filename); - - - -/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */ -static void +/** + * exo_mount_utils_canonicalize_filename: + * @filename : an absolute local path. + * + * Translates the @filename to a canonicalized form. + **/ +void exo_mount_utils_canonicalize_filename (gchar *filename) { gboolean last_was_slash = FALSE; - gchar *p = filename; - gchar *q = filename; + gchar *p; + gchar *q; - while (*p) + for (p = q = filename; *p != '\0'; ) { if (*p == G_DIR_SEPARATOR) { @@ -119,65 +126,6 @@ /** - * exo_mount_utils_resolve: - * @device_file : absolute or relative path to a device file. - * - * Resolves the @device_file path, which might be a symbolic link - * to it's real path. The caller is responsible to free the returned - * string using g_free() when no longer needed. - * - * Return value: the resolved path of the @device_file. - **/ -gchar* -exo_mount_utils_resolve (const gchar *device_file) -{ - gchar *dirname; - gchar *target; - gchar *path; - - g_return_val_if_fail (device_file != NULL, NULL); - - /* check if it's an absolute path */ - if (!g_path_is_absolute (device_file)) - path = g_build_filename ("/dev", device_file, NULL); - else - path = g_strdup (device_file); - - /* resolve all present symlinks */ - while (g_file_test (path, G_FILE_TEST_IS_SYMLINK)) - { - /* use the path, if we cannot resolve a symlink */ - target = g_file_read_link (path, NULL); - if (G_UNLIKELY (target == NULL)) - break; - - /* check if the link is relative */ - if (!g_path_is_absolute (target)) - { - /* relative to the current path then */ - dirname = g_path_get_dirname (path); - g_free (path); - path = g_build_filename (dirname, target, NULL); - g_free (dirname); - g_free (target); - } - else - { - /* use the absolute target */ - g_free (path); - path = target; - } - } - - /* canonicalize the path */ - exo_mount_utils_canonicalize_filename (path); - - return path; -} - - - -/** * exo_mount_utils_is_mounted: * @device_file : an absolute path to a device file. * @readonly_return : if non-%NULL and the device is mounted, this @@ -193,7 +141,6 @@ gboolean *readonly_return) { gboolean result = FALSE; - gchar *resolved; #if defined(HAVE_SETMNTENT) /* Linux */ struct mntent *mntent; @@ -212,14 +159,7 @@ break; /* check if this is the entry we are looking for */ - result = (strcmp (mntent->mnt_fsname, device_file) == 0); - if (G_LIKELY (!result)) - { - /* but maybe the mount entry is a symlink */ - resolved = exo_mount_utils_resolve (mntent->mnt_fsname); - result = (strcmp (resolved, device_file) == 0); - g_free (resolved); - } + result = exo_mount_utils_is_same_device (mntent->mnt_fsname, device_file); /* check if the device was mounted read-only */ if (readonly_return != NULL && result) @@ -245,14 +185,7 @@ break; /* check if this is the entry we are looking for */ - result = (strcmp (mntent.mnt_special, device_file) == 0); - if (G_LIKELY (!result)) - { - /* but maybe the mount entry is a symlink */ - resolved = exo_mount_utils_resolve (mntent.mnt_special); - result = (strcmp (resolved, device_file) == 0); - g_free (resolved); - } + result = exo_mount_utils_is_same_device (mntent.mnt_special, device_file); /* check if the device was mounted read-only */ if (readonly_return != NULL && result) @@ -281,14 +214,7 @@ for (n = 0; n < mntsize && !result; ++n) { /* check if this is the entry we are looking for */ - result = (strcmp (mntbuf[n].f_mntfromname, device_file) == 0); - if (G_LIKELY (!result)) - { - /* but maybe the mount entry is a symlink */ - resolved = exo_mount_utils_resolve (mntbuf[n].f_mntfromname); - result = (strcmp (resolved, device_file) == 0); - g_free (resolved); - } + result = exo_mount_utils_is_same_device (mntbuf[n].f_mntfromname, device_file); /* check if the device was mounted read-only */ if (readonly_return != NULL && result) @@ -306,3 +232,41 @@ } + +/** + * exo_mount_utils_is_same_device: + * @device_file1 : absolute path to the first device file. + * @device_file2 : absolute path to the second device file. + * + * Returns %TRUE if @device_file1 and @device_file2 refer to + * the same device (comparing their device major and minor + * numbers). + * + * Return value: %TRUE if @device_file1 and @device_file2 + * refer to the same device, %FALSE otherwise. + **/ +gboolean +exo_mount_utils_is_same_device (const gchar *device_file1, + const gchar *device_file2) +{ + struct stat statb1; + struct stat statb2; + + g_return_val_if_fail (device_file1 != NULL, FALSE); + g_return_val_if_fail (device_file2 != NULL, FALSE); + + /* both device file names must be absolute paths */ + if (!g_path_is_absolute (device_file1) || !g_path_is_absolute (device_file2)) + return FALSE; + + /* try to stat both device files */ + if (stat (device_file1, &statb1) < 0 || stat (device_file2, &statb2) < 0) + return FALSE; + + /* must be both a character or a block device whose rdev matches */ + return ((S_ISBLK (statb1.st_mode) && S_ISBLK (statb2.st_mode)) + || (S_ISCHR (statb1.st_mode) && S_ISCHR (statb1.st_mode))) + && (statb1.st_rdev == statb2.st_rdev); +} + + Modified: libexo/trunk/exo-mount/exo-mount-utils.h =================================================================== --- libexo/trunk/exo-mount/exo-mount-utils.h 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/exo-mount/exo-mount-utils.h 2007-01-06 22:23:47 UTC (rev 24278) @@ -24,11 +24,14 @@ G_BEGIN_DECLS; -gchar *exo_mount_utils_resolve (const gchar *device_file) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +void exo_mount_utils_canonicalize_filename (gchar *filename) G_GNUC_INTERNAL; -gboolean exo_mount_utils_is_mounted (const gchar *device_file, - gboolean *readonly_return) G_GNUC_INTERNAL; +gboolean exo_mount_utils_is_mounted (const gchar *device_file, + gboolean *readonly_return) G_GNUC_INTERNAL; +gboolean exo_mount_utils_is_same_device (const gchar *device_file1, + const gchar *device_file2) G_GNUC_INTERNAL; + G_END_DECLS; #endif /* !__EXO_MOUNT_UTILS_H__ */ Modified: libexo/trunk/exo-mount/main.c =================================================================== --- libexo/trunk/exo-mount/main.c 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/exo-mount/main.c 2007-01-06 22:23:47 UTC (rev 24278) @@ -168,9 +168,12 @@ return EXIT_FAILURE; } - /* resolve the device file path */ - if (G_UNLIKELY (opt_device != NULL)) - opt_device = exo_mount_utils_resolve (opt_device); + /* make sure the device file path is absolute */ + if (opt_device != NULL && !g_path_is_absolute (opt_device)) + { + /* device is always relative to /dev then */ + opt_device = g_build_filename ("/dev", opt_device, NULL); + } #ifdef HAVE_HAL /* query the device information from the HAL daemon */ @@ -183,9 +186,6 @@ /* determine the device file from the device struct */ opt_device = exo_mount_hal_device_get_file (device); - /* resolve the device file path (again) */ - opt_device = exo_mount_utils_resolve (opt_device); - /* determine name and icon of the device */ icon = exo_mount_hal_device_get_icon (device); name = exo_mount_hal_device_get_name (device); @@ -194,6 +194,9 @@ mounted_readonly = exo_mount_hal_device_is_readonly (device); #endif + /* canonicalize the device file path */ + exo_mount_utils_canonicalize_filename (opt_device); + /* check if the device is currently mounted */ mounted = exo_mount_utils_is_mounted (opt_device, &mounted_readonly); if ((!opt_eject && !opt_unmount && mounted) @@ -285,6 +288,16 @@ g_spawn_close_pid (pid); } + /* if we tried to mount, make sure it's really mounted now */ + if (err == NULL && (!opt_eject && !opt_unmount) + && !exo_mount_utils_is_mounted (opt_device, NULL)) + { + /* although somebody claims that we were successfully, that's not the case */ + g_set_error (&err, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "Mount operation claims to be successfull, " + "but kernel doesn't list the volume as mounted"); + } + /* check if we failed */ if (G_UNLIKELY (err != NULL)) { Modified: libexo/trunk/exo-mount-notify/main.c =================================================================== --- libexo/trunk/exo-mount-notify/main.c 2007-01-06 18:32:10 UTC (rev 24277) +++ libexo/trunk/exo-mount-notify/main.c 2007-01-06 22:23:47 UTC (rev 24278) @@ -115,12 +115,15 @@ notify_notification_show (notification, NULL); g_free (message); - /* we don't care for the pipe anymore */ - return FALSE; + /* release the notification, so it stays active even + * after the process exits, otherwise we'll block + * Thunar's unmount operations... + */ + g_object_unref (G_OBJECT (notification)); } } - /* bring down the notification */ + /* terminate the process */ gtk_main_quit (); return TRUE; _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits