aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bash-completion/blkid2
-rw-r--r--misc-utils/blkid.8.adoc2
-rw-r--r--misc-utils/blkid.c38
-rw-r--r--tests/expected/blkid/output-json-cache4
-rw-r--r--tests/expected/blkid/output-json-probe8
-rwxr-xr-xtests/ts/blkid/output2
6 files changed, 50 insertions, 6 deletions
diff --git a/bash-completion/blkid b/bash-completion/blkid
index 74de34284c..581a90d3d2 100644
--- a/bash-completion/blkid
+++ b/bash-completion/blkid
@@ -13,7 +13,7 @@ _blkid_module()
return 0
;;
'-o'|'--output')
- COMPREPLY=( $(compgen -W "value device export full" -- $cur) )
+ COMPREPLY=( $(compgen -W "value device export full json" -- $cur) )
return 0
;;
'-s'|'--match-tag')
diff --git a/misc-utils/blkid.8.adoc b/misc-utils/blkid.8.adoc
index 5e8002d73d..3386f47ef3 100644
--- a/misc-utils/blkid.8.adoc
+++ b/misc-utils/blkid.8.adoc
@@ -111,6 +111,8 @@ This output format is *DEPRECATED*.
print key=value pairs for easy import into the environment; this output format is automatically enabled when I/O Limits (*--info* option) are requested.
+
The non-printing characters are encoded by ^ and M- notation and all potentially unsafe characters are escaped.
+*json*;;
+Print the tags entries in JSON objects.
*-O*, *--offset* _offset_::
Probe at the given _offset_ (only useful with *--probe*). This option can be used together with the *--info* option.
diff --git a/misc-utils/blkid.c b/misc-utils/blkid.c
index bea5778fd9..5381d14f72 100644
--- a/misc-utils/blkid.c
+++ b/misc-utils/blkid.c
@@ -25,6 +25,7 @@
#define OUTPUT_PRETTY_LIST (1 << 3) /* deprecated */
#define OUTPUT_UDEV_LIST (1 << 4) /* deprecated */
#define OUTPUT_EXPORT_LIST (1 << 5)
+#define OUTPUT_JSON (1 << 6)
#define BLKID_EXIT_NOTFOUND 2 /* token or device not found */
#define BLKID_EXIT_OTHER 4 /* bad usage or other error */
@@ -47,12 +48,14 @@
#include "xalloc.h"
#include "sysfs.h"
+#include "jsonwrt.h"
struct blkid_control {
int output;
uintmax_t offset;
uintmax_t size;
char *show[128];
+ struct ul_jsonwrt *json_fmt;
unsigned int
eval:1,
gc:1,
@@ -81,7 +84,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_( " -d, --no-encoding don't encode non-printing characters\n"), out);
fputs(_( " -g, --garbage-collect garbage collect the blkid cache\n"), out);
fputs(_( " -o, --output <format> output format; can be one of:\n"
- " value, device, export or full; (default: full)\n"), out);
+ " value, device, export, json or full; (default: full)\n"), out);
fputs(_( " -k, --list-filesystems list all known filesystems/RAIDs and exit\n"), out);
fputs(_( " -s, --match-tag <tag> show specified tag(s) (default show all tags)\n"), out);
fputs(_( " -t, --match-token <token> find device with a specific token (NAME=value pair)\n"), out);
@@ -333,6 +336,9 @@ static void print_value(const struct blkid_control *ctl, int num,
safe_print(ctl, value, valsz, " \\\"'$`<>");
fputs("\n", stdout);
+ } else if (ctl->output & OUTPUT_JSON) {
+ ul_jsonwrt_value_s_sized(ctl->json_fmt, name, value, valsz);
+
} else {
if (num == 1 && devname)
printf("%s:", devname);
@@ -366,6 +372,11 @@ static void print_tags(const struct blkid_control *ctl, blkid_dev dev)
return;
}
+ if (ctl->output == OUTPUT_JSON) {
+ ul_jsonwrt_init(ctl->json_fmt, stdout, 0);
+ ul_jsonwrt_open(ctl->json_fmt, NULL, UL_JSON_OBJECT);
+ }
+
iter = blkid_tag_iterate_begin(dev);
while (blkid_tag_next(iter, &type, &value) == 0) {
if (ctl->show[0] && !has_item(ctl, type))
@@ -380,9 +391,13 @@ static void print_tags(const struct blkid_control *ctl, blkid_dev dev)
}
blkid_tag_iterate_end(iter);
+ if (ctl->output == OUTPUT_JSON)
+ ul_jsonwrt_close(ctl->json_fmt, UL_JSON_OBJECT);
+
if (num > 1) {
if (!(ctl->output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST |
- OUTPUT_EXPORT_LIST)))
+ OUTPUT_EXPORT_LIST |
+ OUTPUT_JSON)))
printf("\n");
first = 0;
}
@@ -539,6 +554,11 @@ static int lowprobe_device(blkid_probe pr, const char *devname,
/* add extra line between output from devices */
fputc('\n', stdout);
+ if (ctl->output == OUTPUT_JSON) {
+ ul_jsonwrt_init(ctl->json_fmt, stdout, 0);
+ ul_jsonwrt_open(ctl->json_fmt, NULL, UL_JSON_OBJECT);
+ }
+
if (nvals && (ctl->output & OUTPUT_DEVICE_ONLY)) {
printf("%s\n", devname);
goto done;
@@ -557,8 +577,12 @@ static int lowprobe_device(blkid_probe pr, const char *devname,
first = 0;
if (nvals >= 1 && !(ctl->output & (OUTPUT_VALUE_ONLY |
- OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST)))
+ OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST |
+ OUTPUT_JSON)))
printf("\n");
+
+ if (ctl->output == OUTPUT_JSON)
+ ul_jsonwrt_close(ctl->json_fmt, UL_JSON_OBJECT);
done:
if (rc == -2) {
if (ctl->output & OUTPUT_UDEV_LIST)
@@ -664,7 +688,11 @@ static void free_types_list(char *list[])
int main(int argc, char **argv)
{
- struct blkid_control ctl = { .output = OUTPUT_FULL, 0 };
+ struct ul_jsonwrt json_fmt;
+ struct blkid_control ctl = {
+ .output = OUTPUT_FULL,
+ .json_fmt = &json_fmt,
+ };
blkid_cache cache = NULL;
char **devices = NULL;
char *search_type = NULL, *search_value = NULL;
@@ -777,6 +805,8 @@ int main(int argc, char **argv)
ctl.output = OUTPUT_UDEV_LIST;
else if (!strcmp(optarg, "export"))
ctl.output = OUTPUT_EXPORT_LIST;
+ else if (!strcmp(optarg, "json"))
+ ctl.output = OUTPUT_JSON;
else if (!strcmp(optarg, "full"))
ctl.output = 0;
else
diff --git a/tests/expected/blkid/output-json-cache b/tests/expected/blkid/output-json-cache
new file mode 100644
index 0000000000..3d3c782d11
--- /dev/null
+++ b/tests/expected/blkid/output-json-cache
@@ -0,0 +1,4 @@
+{
+ "label": "tés\"'\n t",
+ "type": "cramfs"
+}
diff --git a/tests/expected/blkid/output-json-probe b/tests/expected/blkid/output-json-probe
new file mode 100644
index 0000000000..b1c124849b
--- /dev/null
+++ b/tests/expected/blkid/output-json-probe
@@ -0,0 +1,8 @@
+{
+ "label": "tés\"'\n t",
+ "fssize": "4096",
+ "version": "2",
+ "endianness": "LITTLE",
+ "type": "cramfs",
+ "usage": "filesystem"
+}
diff --git a/tests/ts/blkid/output b/tests/ts/blkid/output
index ff77f1dbe2..d9dab58596 100755
--- a/tests/ts/blkid/output
+++ b/tests/ts/blkid/output
@@ -33,7 +33,7 @@ _blkid() {
"$TS_CMD_BLKID" --cache-file "$TS_OUTDIR"/blkid.cache "$@" "$outimg" | sed -e "s#$TS_OUTDIR/##"
}
-for format in value udev export full device; do
+for format in value udev export full device json; do
ts_init_subtest "$format-probe"
_blkid --probe --output "$format" >> "$TS_OUTPUT"
ts_finalize_subtest