From: Lennart Poettering Date: Fri, 15 May 2026 10:22:04 +0000 (+0200) Subject: sd-json: add sd_json_parse_fd() helper X-Git-Tag: v261-rc1~120^2~3 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=321df4885c710fdde45f931c79192b005ff93f31;p=thirdparty%2Fsystemd.git sd-json: add sd_json_parse_fd() helper --- diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 38ab92dea12..6afc11d91b3 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -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; diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index e95ff685228..1ba07da6f9b 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -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; diff --git a/src/systemd/sd-json.h b/src/systemd/sd-json.h index dc71871872e..5ad825f3c1a 100644 --- a/src/systemd/sd-json.h +++ b/src/systemd/sd-json.h @@ -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 */