]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-json: add sd_json_parse_fd() helper
authorLennart Poettering <lennart@amutable.com>
Fri, 15 May 2026 10:22:04 +0000 (12:22 +0200)
committerLennart Poettering <lennart@amutable.com>
Mon, 18 May 2026 06:51:09 +0000 (08:51 +0200)
src/libsystemd/libsystemd.sym
src/libsystemd/sd-json/sd-json.c
src/systemd/sd-json.h

index 38ab92dea124b25242d79ced8b39a985d8da80d5..6afc11d91b37469d9cf40c25271e4f6bc3677360 100644 (file)
@@ -1093,13 +1093,14 @@ global:
 
 LIBSYSTEMD_261 {
 global:
-        sd_varlink_call_and_upgrade;
-        sd_varlink_reply_and_upgrade;
-        sd_varlink_set_sentinel;
         sd_event_add_cpu_pressure;
-        sd_event_source_set_cpu_pressure_type;
-        sd_event_source_set_cpu_pressure_period;
         sd_event_add_io_pressure;
-        sd_event_source_set_io_pressure_type;
+        sd_event_source_set_cpu_pressure_period;
+        sd_event_source_set_cpu_pressure_type;
         sd_event_source_set_io_pressure_period;
+        sd_event_source_set_io_pressure_type;
+        sd_json_parse_fd;
+        sd_varlink_call_and_upgrade;
+        sd_varlink_reply_and_upgrade;
+        sd_varlink_set_sentinel;
 } LIBSYSTEMD_260;
index e95ff685228df7acd53e2ed348040d7ce1b2d04a..1ba07da6f9b4f5158d0dd92db37ec7f902fb97e1 100644 (file)
@@ -12,6 +12,7 @@
 #include "errno-util.h"
 #include "escape.h"
 #include "ether-addr-util.h"
+#include "fd-util.h"
 #include "fileio.h"
 #include "float.h"
 #include "hexdecoct.h"
@@ -3526,6 +3527,44 @@ _public_ int sd_json_parse_file(
         return sd_json_parse_file_at(f, AT_FDCWD, path, flags, ret, reterr_line, reterr_column);
 }
 
+_public_ int sd_json_parse_fd(
+                const char *path,
+                int fd,
+                sd_json_parse_flags_t flags,
+                sd_json_variant **ret,
+                unsigned *reterr_line,
+                unsigned *reterr_column) {
+
+        int r;
+
+        assert_return(fd >= 0, -EBADF);
+
+        _cleanup_close_ int our_fd = -EBADF;
+        if (FLAGS_SET(flags, SD_JSON_PARSE_REOPEN_FD)) {
+                assert_return(!FLAGS_SET(flags, SD_JSON_PARSE_DONATE_FD), -EINVAL);
+
+                our_fd = fd_reopen(fd, O_RDONLY|O_CLOEXEC);
+                if (our_fd < 0)
+                        return our_fd;
+
+                /* If we reopened the thing the file offset will be at the beginning anyway */
+                flags &= ~SD_JSON_PARSE_SEEK0;
+        } else if (FLAGS_SET(flags, SD_JSON_PARSE_DONATE_FD))
+                our_fd = fd;
+        else {
+                our_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+                if (our_fd < 0)
+                        return -errno;
+        }
+
+        _cleanup_fclose_ FILE *f = NULL;
+        r = take_fdopen_unlocked(&our_fd, "r", &f);
+        if (r < 0)
+                return r;
+
+        return sd_json_parse_file(f, path, flags, ret, reterr_line, reterr_column);
+}
+
 char *json_underscorify(char *p) {
         if (!p)
                 return NULL;
index dc71871872ec7294fb29c00aa376ee4aa6f2613b..5ad825f3c1a92ee448dfd86506d9da285d397a85 100644 (file)
@@ -185,6 +185,8 @@ __extension__ typedef enum _SD_ENUM_TYPE_S64(sd_json_parse_flags_t) {
         SD_JSON_PARSE_MUST_BE_OBJECT = 1 << 1, /* refuse parsing if top-level is not an object */
         SD_JSON_PARSE_MUST_BE_ARRAY  = 1 << 2, /* refuse parsing if top-level is not an array */
         SD_JSON_PARSE_SEEK0          = 1 << 3, /* seek to offset 0 before reading */
+        SD_JSON_PARSE_DONATE_FD      = 1 << 4, /* pass ownership of fd to call, incl. on failure */
+        SD_JSON_PARSE_REOPEN_FD      = 1 << 5, /* reopen the specified file descriptor */
         _SD_ENUM_FORCE_S64(JSON_PARSE_FLAGS)
 } sd_json_parse_flags_t;
 
@@ -194,6 +196,7 @@ int sd_json_parse(const char *string, sd_json_parse_flags_t flags, sd_json_varia
 int sd_json_parse_continue(const char **p, sd_json_parse_flags_t flags, sd_json_variant **ret, unsigned *reterr_line, unsigned *reterr_column);
 int sd_json_parse_file_at(FILE *f, int dir_fd, const char *path, sd_json_parse_flags_t flags, sd_json_variant **ret, unsigned *reterr_line, unsigned *reterr_column);
 int sd_json_parse_file(FILE *f, const char *path, sd_json_parse_flags_t flags, sd_json_variant **ret, unsigned *reterr_line, unsigned *reterr_column);
+int sd_json_parse_fd(const char *path, int fd, sd_json_parse_flags_t flags, sd_json_variant **ret, unsigned *reterr_line, unsigned *reterr_column);
 
 enum {
         /* Do not use these directly, use the SD_JSON_BUILD_*() macros below */