diff --git a/include/BlockSpecial.h b/include/BlockSpecial.h
new file mode 100644
index 00000000..376e3b03
--- /dev/null
+++ b/include/BlockSpecial.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2016 Mike Fleetwood
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+
+/* BlockSpecial
+ *
+ * Representation of a POSIX block special file, e.g. /dev/sda1. Also
+ * tracks the major, minor device numbers so that different names for
+ * the same block device can be compared equal.
+ * Refs: mknod(1) and mknod(2).
+ */
+
+#ifndef GPARTED_BLOCKSPECIAL_H
+#define GPARTED_BLOCKSPECIAL_H
+
+#include
+
+namespace GParted
+{
+
+class BlockSpecial
+{
+public:
+ BlockSpecial();
+ BlockSpecial( const Glib::ustring & name );
+ ~BlockSpecial();
+
+ Glib::ustring m_name; // E.g. Block special file {"/dev/sda1", 8, 1},
+ unsigned long m_major; // plain file {"FILENAME", 0, 0} and empty object
+ unsigned long m_minor; // {"", 0, 0}.
+};
+
+// Operator overloading > The Decision between Member and Non-member
+// http://stackoverflow.com/questions/4421706/operator-overloading/4421729#4421729
+// "2. If a binary operator treats both operands equally (it leaves them unchanged),
+// implement this operator as a non-member function."
+bool operator==( const BlockSpecial & lhs, const BlockSpecial & rhs );
+
+}//GParted
+
+#endif /* GPARTED_BLOCKSPECIAL_H */
diff --git a/include/LVM2_PV_Info.h b/include/LVM2_PV_Info.h
index 25f0e1d1..37009475 100644
--- a/include/LVM2_PV_Info.h
+++ b/include/LVM2_PV_Info.h
@@ -25,14 +25,18 @@
#ifndef GPARTED_LVM2_PV_INFO_H
#define GPARTED_LVM2_PV_INFO_H
+#include "../include/BlockSpecial.h"
#include "../include/Utils.h"
+#include
+#include
+
namespace GParted
{
struct LVM2_PV
{
- Glib::ustring pv_name;
+ BlockSpecial pv_name;
Byte_Value pv_size;
Byte_Value pv_free;
Glib::ustring vg_name;
diff --git a/include/Makefile.am b/include/Makefile.am
index 61f722ed..32fc41c1 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,6 +1,7 @@
gparted_includedir = $(pkgincludedir)
EXTRA_DIST = \
+ BlockSpecial.h \
Copy_Blocks.h \
DMRaid.h \
Device.h \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3ef9bc21..63865aab 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,6 +3,7 @@
gparted.appdata.xml.in
gparted.desktop.in.in
include/Utils.h
+src/BlockSpecial.cc
src/Copy_Blocks.cc
src/Dialog_Base_Partition.cc
src/Dialog_Disklabel.cc
diff --git a/src/BlockSpecial.cc b/src/BlockSpecial.cc
new file mode 100644
index 00000000..1941b3f3
--- /dev/null
+++ b/src/BlockSpecial.cc
@@ -0,0 +1,55 @@
+/* Copyright (C) 2016 Mike Fleetwood
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "../include/BlockSpecial.h"
+
+#include
+#include
+#include
+#include
+
+namespace GParted
+{
+
+BlockSpecial::BlockSpecial() : m_name( "" ), m_major( 0UL ), m_minor( 0UL )
+{
+}
+
+BlockSpecial::BlockSpecial( const Glib::ustring & name ) : m_name( name ), m_major( 0UL ), m_minor( 0UL )
+{
+ struct stat sb;
+ if ( stat( name.c_str(), &sb ) == 0 && S_ISBLK( sb.st_mode ) )
+ {
+ m_major = major( sb.st_rdev );
+ m_minor = minor( sb.st_rdev );
+ }
+}
+
+BlockSpecial::~BlockSpecial()
+{
+}
+
+bool operator==( const BlockSpecial & lhs, const BlockSpecial & rhs )
+{
+ if ( lhs.m_major > 0UL && lhs.m_minor > 0UL )
+ // Match block special files by major, minor device numbers.
+ return lhs.m_major == rhs.m_major && lhs.m_minor == rhs.m_minor;
+ else
+ // For non-block special files fall back to name string compare.
+ return lhs.m_name == rhs.m_name;
+}
+
+} //GParted
diff --git a/src/LVM2_PV_Info.cc b/src/LVM2_PV_Info.cc
index 07c676cc..98a98b72 100644
--- a/src/LVM2_PV_Info.cc
+++ b/src/LVM2_PV_Info.cc
@@ -15,6 +15,7 @@
*/
#include "../include/LVM2_PV_Info.h"
+#include "../include/BlockSpecial.h"
namespace GParted
{
@@ -37,13 +38,13 @@ enum LV_BIT
// lvm_found - Is the "lvm" command available?
// lvm2_pv_cache - Vector of PV fields: pv_name, pv_size, pv_free, vg_name.
// E.g.
-// //pv_name , pv_size , pv_free , vg_name
-// [{"/dev/sda10", 1073741824, 1073741824, "" },
-// {"/dev/sda11", 1069547520, 1069547520, "Test-VG1"},
-// {"/dev/sda12", 1069547520, 335544320, "Test_VG2"},
-// {"/dev/sda13", 1069547520, 0, "Test_VG3"},
-// {"/dev/sda14", 1069547520, 566231040, "Test_VG3"},
-// {"/dev/sda15", 1069547520, 545259520, "Test-VG4"}
+// //pv_name , pv_size , pv_free , vg_name
+// [{BlockSpecial("/dev/sda10"), 1073741824, 1073741824, "" },
+// {BlockSpecial("/dev/sda11"), 1069547520, 1069547520, "Test-VG1"},
+// {BlockSpecial("/dev/sda12"), 1069547520, 335544320, "Test_VG2"},
+// {BlockSpecial("/dev/sda13"), 1069547520, 0, "Test_VG3"},
+// {BlockSpecial("/dev/sda14"), 1069547520, 566231040, "Test_VG3"},
+// {BlockSpecial("/dev/sda15"), 1069547520, 545259520, "Test-VG4"}
// ]
// lvm2_vg_cache - Vector storing VG fields: vg_name, vg_attr, lv_name, lv_attr.
// See vgs(8) and lvs(8) for details of vg_attr and lv_attr respectively.
@@ -145,7 +146,7 @@ std::vector LVM2_PV_Info::get_vg_members( const Glib::ustring & v
{
if ( vgname == lvm2_pv_cache[i].vg_name )
{
- members.push_back( lvm2_pv_cache[i].pv_name );
+ members.push_back( lvm2_pv_cache[i].pv_name.m_name );
}
}
@@ -252,10 +253,10 @@ void LVM2_PV_Info::load_lvm2_pv_info_cache()
Utils::split( Utils::trim( lines[i] ), fields, "," );
if ( fields.size() < PVFIELD_COUNT )
continue; // Not enough fields
- LVM2_PV pv;
- pv.pv_name = fields[PVFIELD_PV_NAME];
- if ( pv.pv_name.size() == 0 )
+ if ( fields[PVFIELD_PV_NAME] == "" )
continue; // Empty PV name
+ LVM2_PV pv;
+ pv.pv_name = BlockSpecial( fields[PVFIELD_PV_NAME] );
pv.pv_size = lvm2_pv_size_to_num( fields[PVFIELD_PV_SIZE] );
pv.pv_free = lvm2_pv_size_to_num( fields[PVFIELD_PV_FREE] );
pv.vg_name = fields[PVFIELD_VG_NAME];
@@ -331,12 +332,13 @@ void LVM2_PV_Info::load_lvm2_pv_info_cache()
// Returns found cache entry or not found substitute.
const LVM2_PV & LVM2_PV_Info::get_pv_cache_entry_by_name( const Glib::ustring & pvname )
{
+ BlockSpecial bs_pvname( pvname );
for ( unsigned int i = 0 ; i < lvm2_pv_cache.size() ; i ++ )
{
- if ( pvname == lvm2_pv_cache[i].pv_name )
+ if ( bs_pvname == lvm2_pv_cache[i].pv_name )
return lvm2_pv_cache[i];
}
- static LVM2_PV pv = {"", -1, -1, ""};
+ static LVM2_PV pv = {BlockSpecial(), -1, -1, ""};
return pv;
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 819c9108..39d6be38 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,7 @@ AM_CXXFLAGS = -Wall
sbin_PROGRAMS = gpartedbin
gpartedbin_SOURCES = \
+ BlockSpecial.cc \
Copy_Blocks.cc \
DMRaid.cc \
Device.cc \