aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2026-01-30 20:05:18 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2026-01-30 20:16:59 +0100
commit8463ce06ca9aabc08909f34356b8b0342e5fb8ed (patch)
treec16fc4856d1d1db53783326e005bec8100c00cbc
parent8a347fd31aa2095be8eb683ad4f7627e525229f1 (diff)
downloadbusybox-w32-8463ce06ca9aabc08909f34356b8b0342e5fb8ed.tar.gz
busybox-w32-8463ce06ca9aabc08909f34356b8b0342e5fb8ed.tar.bz2
busybox-w32-8463ce06ca9aabc08909f34356b8b0342e5fb8ed.zip
lsblk: add error messages and exit code when non-blockdevs are given
function old new delta process__sys_block_NAME - 461 +461 lsblk_main 511 550 +39 .rodata 106960 106977 +17 process_SYS_BLOCK_entry 460 - -460 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 2/0 up/down: 517/-460) Total: 57 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--util-linux/lsblk.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/util-linux/lsblk.c b/util-linux/lsblk.c
index 3063d8ae9..560ccbaf8 100644
--- a/util-linux/lsblk.c
+++ b/util-linux/lsblk.c
@@ -71,8 +71,9 @@ struct blockdev_info {
71}; 71};
72 72
73struct globals { 73struct globals {
74 unsigned count;
75 struct blockdev_info *list; 74 struct blockdev_info *list;
75 unsigned count;
76 unsigned exitcode;
76}; 77};
77#define G (*ptr_to_globals) 78#define G (*ptr_to_globals)
78#define INIT_G() do { \ 79#define INIT_G() do { \
@@ -124,6 +125,8 @@ static char *get_majmin_from_stat(const char *filename)
124 (unsigned)minor(st.st_rdev) 125 (unsigned)minor(st.st_rdev)
125 ); 126 );
126 } 127 }
128 bb_error_msg("%s: not a block device", filename);
129 G.exitcode |= 64; /* util-linux compat */
127 return NULL; 130 return NULL;
128} 131}
129 132
@@ -159,9 +162,7 @@ static char *read_str(const char *path, const char *name)
159 162
160 filename = concat_path_file(path, name); 163 filename = concat_path_file(path, name);
161 res = xmalloc_open_read_close(filename, NULL); 164 res = xmalloc_open_read_close(filename, NULL);
162#if 0 165//bb_error_msg("open_read_close('%s'):'%s'", filename, res);
163bb_error_msg("open_read_close('%s'):'%s'", filename, res);
164#endif
165 free(filename); 166 free(filename);
166 167
167 if (res) 168 if (res)
@@ -184,10 +185,10 @@ bb_error_msg("open_read_close('%s'):'%s'", filename, res);
184 * MAJMIN1=open("/sys/block/DEV/PART/dev")+read 185 * MAJMIN1=open("/sys/block/DEV/PART/dev")+read
185 * recurse into handling MAJMIN1 for this partition 186 * recurse into handling MAJMIN1 for this partition
186 */ 187 */
187static void process_SYS_BLOCK_entry(const char *path, const char *devname); 188static void process__sys_block_NAME(const char *path, const char *devname);
188 189
189/* Note: consumes malloc'ed majmin */ 190/* Note: consumes malloc'ed majmin */
190static void process_SYS_DEV_BLOCK_entry(const char *path, char *majmin, const char *devname) 191static void process__sys_dev_block_MAJMIN(const char *path, char *majmin, const char *devname)
191{ 192{
192 DIR *dir; 193 DIR *dir;
193 struct dirent *entry; 194 struct dirent *entry;
@@ -215,22 +216,24 @@ static void process_SYS_DEV_BLOCK_entry(const char *path, char *majmin, const ch
215 while ((entry = readdir(dir)) != NULL) { 216 while ((entry = readdir(dir)) != NULL) {
216 if (is_prefixed_with(entry->d_name, devname)) { 217 if (is_prefixed_with(entry->d_name, devname)) {
217 char *part = xasprintf("/sys/block/%s/%s", devname, entry->d_name); 218 char *part = xasprintf("/sys/block/%s/%s", devname, entry->d_name);
218 process_SYS_BLOCK_entry(part, entry->d_name); 219 process__sys_block_NAME(part, entry->d_name);
219 free(part); 220 free(part);
220 } 221 }
221 } 222 }
222 closedir(dir); 223 closedir(dir);
223} 224}
224static void process_SYS_BLOCK_entry(const char *path, const char *devname) 225static void process__sys_block_NAME(const char *path, const char *devname)
225{ 226{
226 char *majmin = read_str(path, "dev"); 227 char *majmin = read_str(path, "dev");
228//bb_error_msg("%s/dev:'%s'", path, majmin);
227 if (majmin /*&& majmin[0]*/) { 229 if (majmin /*&& majmin[0]*/) {
228 char *sys_dev_block_MAJMIN = concat_path_file("/sys/dev/block", majmin); 230 char *sys_dev_block_MAJMIN = concat_path_file("/sys/dev/block", majmin);
229 process_SYS_DEV_BLOCK_entry(sys_dev_block_MAJMIN, majmin, devname); 231 process__sys_dev_block_MAJMIN(sys_dev_block_MAJMIN, majmin, devname);
230 /* ^^^ consumes malloc'ed majmin */ 232 /* ^^^ consumes malloc'ed majmin */
231 free(sys_dev_block_MAJMIN); 233 free(sys_dev_block_MAJMIN);
232 } 234 }
233 /* WRONG: free(majmin); */ 235 /* WRONG: free(majmin); */
236// return !majmin; /* 1 if no PATH/dev was seen */
234} 237}
235 238
236static int compare_devices(const void *a, const void *b) 239static int compare_devices(const void *a, const void *b)
@@ -254,7 +257,6 @@ int lsblk_main(int argc UNUSED_PARAM, char **argv)
254 /* If specific devices are requested, process them */ 257 /* If specific devices are requested, process them */
255 if (*argv) { 258 if (*argv) {
256 while (*argv) { 259 while (*argv) {
257 char *devname = *argv++;
258 char *majmin; 260 char *majmin;
259 char *sys_dev_block_MAJMIN; 261 char *sys_dev_block_MAJMIN;
260 char *target; 262 char *target;
@@ -264,19 +266,36 @@ int lsblk_main(int argc UNUSED_PARAM, char **argv)
264 * cp -a /dev/DISK /tmp/bogusname; lsblk /tmp/bogusname 266 * cp -a /dev/DISK /tmp/bogusname; lsblk /tmp/bogusname
265 * ^^^^ should still show "DISK" as the name of blockdev, and show its partitions if any 267 * ^^^^ should still show "DISK" as the name of blockdev, and show its partitions if any
266 */ 268 */
267 majmin = get_majmin_from_stat(devname); 269 majmin = get_majmin_from_stat(*argv++);
270//bb_error_msg("get_majmin_from_stat('%s'):'%s'", argv[-1], majmin);
268 if (!majmin) 271 if (!majmin)
269 continue; 272 continue;
270 273
271 sys_dev_block_MAJMIN = concat_path_file("/sys/dev/block", majmin); 274 sys_dev_block_MAJMIN = concat_path_file("/sys/dev/block", majmin);
272 /* util-linux 2.41.1 gets the "real name" from the symlink's last component */ 275 /* util-linux 2.41.1 gets the "real name" from the symlink's last component */
273 target = xmalloc_readlink(sys_dev_block_MAJMIN); 276 target = xmalloc_readlink(sys_dev_block_MAJMIN);
277//bb_error_msg("target:'%s'", target);
274 if (target) { 278 if (target) {
275 name = strrchr(target, '/'); 279 name = strrchr(target, '/');
276 if (name && name[1]) { 280 if (name && *++name) {
277 char *sys_block_NAME = concat_path_file("/sys/block", ++name); 281 char *sys_block_NAME;
278 process_SYS_BLOCK_entry(sys_block_NAME, name); 282// Maybe there's a reason why util-linux tries /sys/block/NAME first.
279 free(sys_block_NAME); 283// In which case uncomment this, and explain.
284// int err;
285//
286// sys_block_NAME = concat_path_file("/sys/block", name);
287// err = process__sys_block_NAME(sys_block_NAME, name);
288// free(sys_block_NAME);
289// /* "/sys/block/NAME/dev" wasn't found? (Happens for "lsblk /dev/PARTITION") */
290// if (err) {
291 /* util-linux seems to test for existence of /sys/dev/block/MAJMIN/partition,
292 * if that exists, it *guesses* parent disk name (!!!).
293 * We just try /sys/class/block/NAME, which exists for partitions too.
294 */
295 sys_block_NAME = concat_path_file("/sys/class/block", name);
296 process__sys_block_NAME(sys_block_NAME, name);
297 free(sys_block_NAME);
298// }
280 } 299 }
281 free(target); 300 free(target);
282 } 301 }
@@ -294,12 +313,15 @@ int lsblk_main(int argc UNUSED_PARAM, char **argv)
294 if (DOT_OR_DOTDOT(entry->d_name)) 313 if (DOT_OR_DOTDOT(entry->d_name))
295 continue; 314 continue;
296 sys_block_NAME = concat_path_file("/sys/block", entry->d_name); 315 sys_block_NAME = concat_path_file("/sys/block", entry->d_name);
297 process_SYS_BLOCK_entry(sys_block_NAME, entry->d_name); 316 process__sys_block_NAME(sys_block_NAME, entry->d_name);
298 free(sys_block_NAME); 317 free(sys_block_NAME);
299 } 318 }
300 closedir(dir); 319 closedir(dir);
301 } 320 }
302 321
322 if (G.count == 0)
323 return 32; /* try "lsblk /dev/null DOES_NOT_EXIST" */
324
303 /* Sort devices by name */ 325 /* Sort devices by name */
304 qsort(G.list, G.count, sizeof(G.list[0]), compare_devices); 326 qsort(G.list, G.count, sizeof(G.list[0]), compare_devices);
305 327
@@ -321,5 +343,5 @@ int lsblk_main(int argc UNUSED_PARAM, char **argv)
321 ); 343 );
322 } 344 }
323 345
324 fflush_stdout_and_exit_SUCCESS(); 346 fflush_stdout_and_exit(G.exitcode);
325} 347}