diff --git a/Source/NSWorkspace.m b/Source/NSWorkspace.m index 623084bb3e..bcbf974ddb 100644 --- a/Source/NSWorkspace.m +++ b/Source/NSWorkspace.m @@ -2,7 +2,7 @@ Workspace class - Copyright (C) 1996-2016 Free Software Foundation, Inc. + Copyright (C) 1996-2026 Free Software Foundation, Inc. Author: Scott Christley Date: 1996 @@ -482,6 +482,7 @@ - (BOOL) _launchApplication: (NSString*)appName arguments: (NSArray*)args; - (id) _connectApplication: (NSString*)appName; - (id) _workspaceApplication; +- (NSString*) _stripPartitionSuffixFromDeviceName: (NSString*)devName; @end @@ -1287,11 +1288,13 @@ - (BOOL) getFileSystemInfoForPath: (NSString*)fullPath r = NO; devName = [fsName lastPathComponent]; - // This is a very crude way of removing the partition number - if ([devName length] > 3) - devName = [devName substringToIndex: 3]; + + /* Extract block device name by removing partition suffix */ + devName = [self _stripPartitionSuffixFromDeviceName: devName]; + /* For other devices (loop, ram, sr, etc.), use as-is */ devInfoPath = [@"/sys/block" stringByAppendingPathComponent:devName]; + devInfoPath = [devInfoPath stringByAppendingPathComponent:@"removable"]; removableString = [[NSString alloc] initWithContentsOfFile:devInfoPath]; @@ -3655,4 +3658,48 @@ - (id) _workspaceApplication return app; } +- (NSString*) _stripPartitionSuffixFromDeviceName: (NSString*)devName +{ + /* Handle various device naming schemes: + * sd*, hd*, vd*, xvd* → remove trailing digits (sda1 → sda) + * nvme*n*p* → remove trailing p (nvme0n1p1 → nvme0n1) + * mmcblk*p* → remove trailing p (mmcblk0p1 → mmcblk0) + * loop*, ram*, sr* → use as-is + */ + if ([devName hasPrefix:@"nvme"] || [devName hasPrefix:@"mmcblk"]) + { + /* For nvme and mmcblk devices, partition names have a 'p' separator + * e.g., nvme0n1p1, mmcblk0p1 */ + NSRange pRange = [devName rangeOfString:@"p" options:NSBackwardsSearch]; + if (pRange.location != NSNotFound) + { + /* Check if everything after 'p' is digits */ + NSString *suffix = [devName substringFromIndex:pRange.location + 1]; + NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; + if ([suffix rangeOfCharacterFromSet:nonDigits].location == NSNotFound && [suffix length] > 0) + { + /* It's a partition, strip it */ + devName = [devName substringToIndex:pRange.location]; + } + } + } + else if ([devName hasPrefix:@"sd"] || [devName hasPrefix:@"hd"] || + [devName hasPrefix:@"vd"] || [devName hasPrefix:@"xvd"]) + { + /* For sd/hd/vd/xvd devices, remove trailing digits (sda1 → sda) */ + NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet]; + NSInteger i = [devName length] - 1; + while (i >= 0 && [digits characterIsMember:[devName characterAtIndex:i]]) + { + i--; + } + if (i < (NSInteger)[devName length] - 1) + { + /* Found trailing digits, strip them */ + devName = [devName substringToIndex:i + 1]; + } + } + return devName; +} + @end