Commit Diff


commit - 191a6a0e432bc77ff58dff1e4800ef5b8bf6e6da
commit + 5691dc7beee507ca2ad0613a57614a4b3ca27778
blob - 8e50a14952c1ad2f7fede9fe4a9dd1a10efd62a3
blob + 10c92f0d6fdfa6daf4c5dccf63f1bb0e395991a2
--- ChangeLog.md
+++ ChangeLog.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http
 
 ## [1.2] - TBD
 ### Added
+- Accept "disk" arguments.
 - Options:
   - `-a` print all fields
   - `-i` don't print fancy unicode characters
blob - aa9edd8049a073d6831f4a319c73e2404659461a
blob + 1ef83eb3d61e0e09ef7275d2d68b570e933fa988
--- README.md
+++ README.md
@@ -18,6 +18,7 @@ doas make unroot
   Workaround: `make unroot`
 
 ## TODO
-- [ ] `lsblk sd0`
+- [-] `lsblk sd0`
+- [ ] `lsblk sd0a`
 - [ ] Add an option to make the output script-friendly (like -c for CSV).
 - [ ] Maybe: Display the child device of a RAID partition
blob - 2dfb9afa94e135119b69a482672e1fc6d8122f44
blob + 97fe11442ac141c1fe3c9ba8438c3fa3c2a948f2
--- lsblk.8
+++ lsblk.8
@@ -11,15 +11,21 @@
 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.TH LSBLK 8 lsblk-@VERSION@ 2023-05-04
+.TH LSBLK 8 lsblk-@VERSION@ 2023-05-05
 .SH NAME
 lsblk \- list block devices
 .SH SYNOPSIS
-.B lsblk [-Vainu]
+.B lsblk
+[\fB-Vainu\fR]
+[\fIdisk ...\fR]
 .SH DESCRIPTION
 The
 .B lsblk
 utility can be used to examine block devices attached to the system.
+If passed
+.I disk
+operands it lists the specified devices.
+Otherwise it lists all attached block devices.
 .SH OPTIONS
 .TP
 .B \-V
@@ -38,9 +44,44 @@ don't print the header.
 also print the filesystem usage of each partition
 and the disklabel usage of each disk.
 
-Note: The disklabel usage is calculated by summing the size of all (except "c") partitions.
+Note: The disklabel usage is calculated by
+summing the size of all (except "c") partitions.
 
-Note 2: There is some error in the filesystem usage, please consult df(1) for more correct numbers.
+Note 2: There may be a small deviance in the filesystem usage,
+please consult df(1) for more correct numbers.
+
+.SH EXIT STATUS
+The
+.B lsblk
+utility exits 0 on success, and >0 if an error occurs.
+
+.SH EXAMPLES
+The following line lists all block devices:
+.PP
+.RS 5
+lsblk
+
+.RE
+The following line lists all fields of sd0:
+.PP
+.RS 5
+lsblk -a sd0
+
 .SH SEE ALSO
 .BR disklabel (8) ,
 .BR df (1)
+
+.SH HISTORY
+The
+.B lsblk(8)
+utility was originally written by the
+.B util-linux
+project.
+This is an
+.I incompatible
+clone of the original \fBlsblk\fR.
+It is incompatible because it doesn't support
+the same set of options as the original
+and because of differences in the output.
+More incompatibilities are caused by specific features only being available
+on either Linux or OpenBSD.
blob - 595f3ae1dbb7c2cad091fd15065ebf43a03bd271
blob + 84187fdbb1200e69cf048b6cc320cc0c799e7432
--- lsblk.c
+++ lsblk.c
@@ -31,6 +31,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <libgen.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -278,18 +279,20 @@ static struct my_diskinfo read_disk (const char *name)
     bzero (&disk, sizeof disk);
 
     {   // Read disklabel.
-        char path[5 + 4 + 1];
+        char *path = NULL;
         int fd;
 
-        snprintf (path, sizeof path, "/dev/%.3sc", name);
+        asprintf (&path, "/dev/%sc", name);
         fd = open (path, O_RDONLY);
         if (fd < 0)
             die ("open(%s)", path);
         if (ioctl (fd, DIOCGDINFO, &label) < 0)
             die ("ioctl(%s, DIOCGDINFO)", path);
         close (fd);
+        free (path);
     }
 
+
     memcpy (disk.name, name, 3);
     disk.name[3] = '\0';
     disk.size = DL_GETDSIZE (&label) * label.d_secsize;
@@ -336,7 +339,7 @@ static struct my_diskinfo read_disk (const char *name)
 
 static int usage (void)
 {
-    fputs ("Usage: lsblk [-Vainu]\n", stderr);
+    fputs ("Usage: lsblk [-Vainu] [disk...]\n", stderr);
     return 1;
 }
 
@@ -374,24 +377,41 @@ int main (int argc, char *argv[])
         }
     }
 
-    if (argc != optind)
-        return usage ();
+    argv += optind;
+    argc -= optind;
 
-    char *names = disknames ();
+    char *names = argc == 0 ? disknames () : NULL;
 
     if (pledge ("stdio rpath disklabel", NULL) == -1)
         die ("pledge()");
 
-    size_t cap_disks = 10;
-    size_t num_disks = 0;
+    size_t cap_disks;
+    if (argc == 0) {
+        const char *s = names;
+        cap_disks = 0;
+        while ((s = strchr (s, ',')) != NULL)
+            ++cap_disks, ++s;
+    } else {
+        cap_disks = argc;
+    }
+
     struct my_diskinfo *disks = calloc (cap_disks, sizeof (struct my_diskinfo));
+    size_t num_disks = 0;
 
-    for (char *disk; (disk = strsep (&names, ",")) != NULL; ) {
-        if (num_disks == cap_disks) {
-            cap_disks = cap_disks * 13 / 8;
-            disks = reallocarray (disks, cap_disks, sizeof (struct my_diskinfo));
+    if (argc == 0) {
+        for (char *disk; (disk = strsep (&names, ",")) != NULL; ) {
+            char *colon = strchr (disk, ':');
+            if (colon)
+                *colon = '\0';
+            disks[num_disks++] = read_disk (disk);
+            if (colon)
+                *colon = ':';
         }
-        disks[num_disks++] = read_disk (disk);
+    } else {
+        for (int i = 0; i < argc; ++i) {
+            char *disk = basename (argv[i]);
+            disks[num_disks++] = read_disk (disk);
+        }
     }
 
     free (names);
@@ -402,5 +422,6 @@ int main (int argc, char *argv[])
     for (size_t i = 0; i < num_disks; ++i) {
         print_disk (&disks[i], fields, options);
     }
+
     return 0;
 }