=================================================================== RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-unix-mounts.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- libgnomevfs/gnome-vfs-unix-mounts.h 2003/11/05 15:44:53 1.2 +++ libgnomevfs/gnome-vfs-unix-mounts.h 2004/09/22 08:38:38 1.3 @@ -59,7 +59,7 @@ GnomeVFSUnixMountPoint *mount_point2); gboolean _gnome_vfs_get_unix_mount_table (GList **return_list); gboolean _gnome_vfs_get_current_unix_mounts (GList **return_list); -dev_t _gnome_vfs_unix_mount_get_unix_device (GnomeVFSUnixMount *mount); +GList * _gnome_vfs_unix_mount_get_unix_device (GList *mounts); void _gnome_vfs_monitor_unix_mounts (GnomeVFSUnixMountCallback mount_table_changed, gpointer mount_table_changed_user_data, GnomeVFSUnixMountCallback current_mounts_changed, =================================================================== RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-unix-mounts.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- libgnomevfs/gnome-vfs-unix-mounts.c 2004/09/21 07:45:25 1.16 +++ libgnomevfs/gnome-vfs-unix-mounts.c 2004/09/22 08:38:38 1.17 @@ -91,98 +91,111 @@ * to avoid this... * Various ugly workarounds can be tried later. */ -dev_t -_gnome_vfs_unix_mount_get_unix_device (GnomeVFSUnixMount *mount) +GList * +_gnome_vfs_unix_mount_get_unix_device (GList *mounts) { - struct stat statbuf; - dev_t unix_device; - pid_t pid; - int pipes[2]; -#ifdef HAVE_POLL - struct pollfd poll_fd; -#else - struct timeval tv; - fd_set read_fds; -#endif - int res; - int status; - - if (pipe (pipes) == -1) { - return 0; - } - - pid = fork (); + GList *result = NULL; - if (pid == -1) { - close (pipes[0]); - close (pipes[1]); - return 0; - } + while (mounts) { + dev_t unix_device = 0; + pid_t pid; + int pipes[2]; + int status; - unix_device = 0; - - if (pid == 0) { - /* Child */ - close (pipes[0]); + if (pipe (pipes) == -1) + goto error; pid = fork (); + if (pid == -1) { + close (pipes[0]); + close (pipes[1]); + goto error; + } - /* Fork an intermediate child that immediately exits so - * we can waitpid it. This means the final process will get - * owned by init and not go zombie - */ if (pid == 0) { - /* Grandchild */ - if (stat (mount->mount_path, &statbuf) == 0) { - write (pipes[1], (char *)&statbuf.st_dev, sizeof (dev_t)); + /* Child */ + close (pipes[0]); + + /* Fork an intermediate child that immediately exits + * so we can waitpid it. This means the final process + * will get owned by init and not go zombie. + */ + pid = fork (); + + if (pid == 0) { + /* Grandchild */ + struct stat statbuf; + while (mounts) { + GnomeVFSUnixMount *mount = mounts->data; + unix_device = + stat (mount->mount_path, &statbuf) == 0 + ? statbuf.st_dev + : 0; + write (pipes[1], (char *)&unix_device, sizeof (dev_t)); + mounts = mounts->next; + } } - } else { close (pipes[1]); + _exit (0); + g_assert_not_reached (); } - _exit (0); - } else { /* Parent */ close (pipes[1]); - - wait_again: + + retry_waitpid: if (waitpid (pid, &status, 0) < 0) { if (errno == EINTR) - goto wait_again; + goto retry_waitpid; else if (errno == ECHILD) ; /* do nothing, child already reaped */ else g_warning ("waitpid() should not fail in gnome_vfs_unix_mount_get_unix_device"); } + while (mounts) { + int res; - do { + do { #ifdef HAVE_POLL - poll_fd.fd = pipes[0]; - poll_fd.events = POLLIN; - res = poll (&poll_fd, 1, STAT_TIMEOUT_SECONDS*1000); + struct pollfd poll_fd; + poll_fd.fd = pipes[0]; + poll_fd.events = POLLIN; + res = poll (&poll_fd, 1, STAT_TIMEOUT_SECONDS * 1000); #else - tv.tv_sec = STAT_TIMEOUT_SECONDS; - tv.tv_usec = 0; + struct timeval tv; + fd_set read_fds; + + tv.tv_sec = STAT_TIMEOUT_SECONDS; + tv.tv_usec = 0; - FD_ZERO(&read_fds); - FD_SET(pipes[0], &read_fds); + FD_ZERO(&read_fds); + FD_SET(pipes[0], &read_fds); - res = select (pipes[0] + 1, - &read_fds, NULL, NULL, &tv); + res = select (pipes[0] + 1, + &read_fds, NULL, NULL, &tv); #endif - } while (res == -1 && errno == EINTR); - - if (res > 0) { - if (read (pipes[0], (char *)&unix_device, sizeof (dev_t)) != sizeof (dev_t)) { - unix_device = 0; - } + } while (res == -1 && errno == EINTR); + + if (res <= 0 || + read (pipes[0], (char *)&unix_device, sizeof (dev_t)) != sizeof (dev_t)) + break; + + result = g_list_prepend (result, GUINT_TO_POINTER ((gulong)unix_device)); + mounts = mounts->next; } close (pipes[0]); + + error: + if (mounts) { + unix_device = 0; + result = g_list_prepend (result, GUINT_TO_POINTER ((gulong)unix_device)); + mounts = mounts->next; + } } - - return unix_device; + + return g_list_reverse (result); } #ifndef HAVE_SETMNTENT =================================================================== RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-volume-monitor-daemon.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- libgnomevfs/gnome-vfs-volume-monitor-daemon.c 2004/09/02 15:51:48 1.14 +++ libgnomevfs/gnome-vfs-volume-monitor-daemon.c 2004/09/22 08:38:38 1.15 @@ -851,7 +851,7 @@ vol->priv->volume_type = GNOME_VFS_VOLUME_TYPE_MOUNTPOINT; vol->priv->device_path = g_strdup (mount->device_path); - vol->priv->unix_device = _gnome_vfs_unix_mount_get_unix_device (mount); + vol->priv->unix_device = 0; /* Caller must fill in. */ vol->priv->activation_uri = gnome_vfs_get_uri_from_local_path (mount->mount_path); vol->priv->filesystem_type = g_strdup (mount->filesystem_type); vol->priv->is_read_only = mount->is_read_only; @@ -981,9 +981,8 @@ update_mtab_volumes (GnomeVFSVolumeMonitorDaemon *volume_monitor_daemon) { GList *new_mtab; - GList *removed, *added; - GList *l; - GnomeVFSUnixMount *mount; + GList *removed, *added, *devices; + GList *l, *ld; char *uri; GnomeVFSVolume *vol; GnomeVFSVolumeMonitor *volume_monitor; @@ -998,7 +997,7 @@ &added, &removed); for (l = removed; l != NULL; l = l->next) { - mount = l->data; + GnomeVFSUnixMount *mount = l->data; uri = gnome_vfs_get_uri_from_local_path (mount->mount_path); vol = _gnome_vfs_volume_monitor_find_mtab_volume_by_activation_uri (volume_monitor, uri); @@ -1011,15 +1010,22 @@ g_free (uri); } - - for (l = added; l != NULL; l = l->next) { - mount = l->data; + + devices = _gnome_vfs_unix_mount_get_unix_device (added); + + for (l = added, ld = devices; + l != NULL; + l = l->next, ld = ld->next) { + GnomeVFSUnixMount *mount = l->data; + dev_t unix_device = GPOINTER_TO_UINT (ld->data); vol = create_vol_from_mount (volume_monitor, mount); + vol->priv->unix_device = unix_device; _gnome_vfs_volume_monitor_mounted (volume_monitor, vol); gnome_vfs_volume_unref (vol); } - + + g_list_free (devices); g_list_free (added); g_list_free (removed); g_list_foreach (volume_monitor_daemon->last_mtab,