Skip to content

Commit 02d2ace

Browse files
committed
Implement isOnRemovableDrive
1 parent eb610da commit 02d2ace

2 files changed

Lines changed: 53 additions & 2 deletions

File tree

modules/yup_core/native/yup_Files_linux.cpp

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
namespace yup
4141
{
4242

43+
namespace
44+
{
45+
4346
enum
4447
{
4548
U_ISOFS_SUPER_MAGIC = 0x9660, // linux/iso_fs.h
@@ -48,6 +51,37 @@ enum
4851
U_SMB_SUPER_MAGIC = 0x517B // linux/smb_fs.h
4952
};
5053

54+
static String getBlockDeviceName (dev_t dev)
55+
{
56+
// Example sysfs entry:
57+
// /sys/dev/block/8:16 -> ../../block/sdb/sdb1
58+
char sysPath[128] = {};
59+
std::snprintf (sysPath, sizeof (sysPath), "/sys/dev/block/%u:%u", static_cast<unsigned int> (major (dev)), static_cast<unsigned int> (minor (dev)));
60+
61+
char buf[4096 + 1] = {};
62+
const ssize_t len = ::readlink (sysPath, buf, 4096);
63+
if (len <= 0)
64+
return {};
65+
66+
buf[len] = 0;
67+
const String link (CharPointer_UTF8 (buf));
68+
69+
// Look for "/block/" component
70+
const int blockIndex = link.indexOf ("/block/");
71+
if (blockIndex < 0)
72+
return {};
73+
74+
String rest = link.substring (blockIndex + 7); // skip "/block/"
75+
76+
// rest is typically "sdb/sdb1" or just "sdb"
77+
const int slash = rest.indexOfChar ('/');
78+
if (slash >= 0)
79+
rest = rest.substring (0, slash);
80+
81+
return rest; // e.g. "sdb"
82+
}
83+
} // namespace
84+
5185
bool File::isOnCDRomDrive() const
5286
{
5387
struct statfs buf;
@@ -81,8 +115,21 @@ bool File::isOnHardDisk() const
81115

82116
bool File::isOnRemovableDrive() const
83117
{
84-
jassertfalse; // xxx not implemented for linux!
85-
return false;
118+
struct stat st {};
119+
const auto path = getFullPathName();
120+
121+
if (::stat (path.toUTF8(), &st) != 0)
122+
return false;
123+
124+
const auto devName = getBlockDeviceName (st.st_dev);
125+
if (devName.isEmpty())
126+
return false;
127+
128+
const File removableFlag ("/sys/block/" + devName + "/removable");
129+
if (! removableFlag.existsAsFile())
130+
return false;
131+
132+
return removableFlag.loadFileAsString().trim() == "1";
86133
}
87134

88135
String File::getVersion() const

modules/yup_core/yup_core.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ YUP_END_IGNORE_WARNINGS_MSVC
115115
#include <sys/stat.h>
116116
#include <sys/time.h>
117117

118+
#if __has_include(<sys/sysmacros.h>)
119+
#include <sys/sysmacros.h>
120+
#endif
121+
118122
#if YUP_USE_CURL
119123
#include <curl/curl.h>
120124
#endif

0 commit comments

Comments
 (0)