diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bb6cfcec..9d6bebd82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,9 @@ endif() pkg_check_modules(GLIB REQUIRED glib-2.0) pkg_check_modules(GOBJECT REQUIRED gobject-2.0) pkg_check_modules(GIO REQUIRED gio-2.0) +if(UNIX) + pkg_check_modules(GIO_UNIX gio-unix-2.0) +endif() pkg_check_modules(LIBCDIO libcdio) pkg_check_modules(GSTREAMER gstreamer-1.0) pkg_check_modules(GSTREAMER_BASE gstreamer-base-1.0) @@ -391,6 +394,11 @@ optional_component(GIO ON "Devices: GIO device backend" DEPENDS "Unix or Windows" "NOT APPLE" ) +optional_component(GIO_UNIX ON "Devices: GIO device backend (Unix support)" + DEPENDS "libgio-unix" GIO_UNIX_FOUND + DEPENDS "Unix" "UNIX" +) + optional_component(LIBGPOD ON "Devices: iPod classic support" DEPENDS "libgpod" LIBGPOD_FOUND DEPENDS "gdk-pixbuf" GDK_PIXBUF_FOUND diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cd22e1fca..d1a85043c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -986,6 +986,10 @@ if(HAVE_GIO) link_directories(${GIO_LIBRARY_DIRS}) endif() +if(HAVE_GIO_UNIX) + link_directories(${GIO_UNIX_LIBRARY_DIRS}) +endif() + if(HAVE_AUDIOCD) link_directories(${LIBCDIO_LIBRARY_DIRS}) endif() @@ -1113,6 +1117,11 @@ if(HAVE_GIO) target_link_libraries(strawberry_lib PRIVATE ${GIO_LIBRARIES}) endif() +if(HAVE_GIO_UNIX) + target_include_directories(strawberry_lib SYSTEM PRIVATE ${GIO_UNIX_INCLUDE_DIRS}) + target_link_libraries(strawberry_lib PRIVATE ${GIO_UNIX_LIBRARIES}) +endif() + if(HAVE_AUDIOCD) target_include_directories(strawberry_lib SYSTEM PRIVATE ${LIBCDIO_INCLUDE_DIRS}) target_link_libraries(strawberry_lib PRIVATE ${LIBCDIO_LIBRARIES}) diff --git a/src/config.h.in b/src/config.h.in index 395f03b66..08f8a277b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -7,6 +7,7 @@ #cmakedefine HAVE_BACKTRACE #cmakedefine HAVE_GIO +#cmakedefine HAVE_GIO_UNIX #cmakedefine HAVE_DBUS #cmakedefine HAVE_X11 #cmakedefine HAVE_UDISKS2 diff --git a/src/device/giolister.cpp b/src/device/giolister.cpp index 77520d176..b01e24c47 100644 --- a/src/device/giolister.cpp +++ b/src/device/giolister.cpp @@ -25,6 +25,9 @@ #include #include #include +#ifdef HAVE_GIO_UNIX +# include +#endif #include #include @@ -60,6 +63,8 @@ bool GioLister::DeviceInfo::is_suitable() const { if (!volume_ptr) return false; // This excludes smb or ssh mounts + if (is_system_internal) return false; + if (drive_ptr && !drive_removable) return false; // This excludes internal drives if (filesystem_type.isEmpty()) return true; @@ -447,7 +452,8 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) { } g_object_unref(icon); - GFile *root = g_mount_get_root(mount); + ScopedGObject root; + root.reset_without_add(g_mount_get_root(mount)); // Get the mount path mount_path = ConvertAndFree(g_file_get_path(root)); @@ -466,6 +472,21 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) { g_object_unref(actual_mount); } +#ifdef HAVE_GIO_UNIX + GUnixMountEntry *unix_mount = g_unix_mount_for(g_file_get_path(root), NULL); + if (unix_mount) { + // the GIO's definition of system internal mounts include filesystems like + // autofs, tmpfs, sysfs, etc, and various system directories, including the root, + // /boot, /var, /home, etc. + is_system_internal = g_unix_mount_is_system_internal(unix_mount); + g_unix_mount_free(unix_mount); + // Although checking most of the internal mounts is safe, + // we really don't want to touch autofs filesystems, as that would + // trigger automounting. + if (is_system_internal) return; + } +#endif + // Query the filesystem info for size, free space, and type error = nullptr; GFileInfo *info = g_file_query_filesystem_info(root, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," G_FILE_ATTRIBUTE_FILESYSTEM_FREE "," G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, nullptr, &error); @@ -494,9 +515,6 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) { g_object_unref(info); } } - - g_object_unref(root); - } void GioLister::DeviceInfo::ReadVolumeInfo(GVolume *volume) { diff --git a/src/device/giolister.h b/src/device/giolister.h index d7169f35f..9c0e8ee06 100644 --- a/src/device/giolister.h +++ b/src/device/giolister.h @@ -77,7 +77,7 @@ class GioLister : public DeviceLister { private: struct DeviceInfo { - DeviceInfo() : drive_removable(false), filesystem_size(0), filesystem_free(0), invalid_enclosing_mount(false) {} + DeviceInfo() : drive_removable(false), filesystem_size(0), filesystem_free(0), invalid_enclosing_mount(false), is_system_internal(false) {} QString unique_id() const; bool is_suitable() const; @@ -111,6 +111,7 @@ class GioLister : public DeviceLister { QString filesystem_type; bool invalid_enclosing_mount; + bool is_system_internal; }; void VolumeAdded(GVolume *volume);