diff options
author | Michael Biebl <biebl@debian.org> | 2018-06-22 13:38:31 +0200 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2018-06-22 13:38:31 +0200 |
commit | b012e92123bdc9fa10c2f079ec5bd9313b23e21a (patch) | |
tree | 94b74f04796e0da187092db7c2487aaf30f0faf1 /src/libsystemd | |
parent | 98393f852f2f66a74f7370aa63c07b26d610343c (diff) | |
download | systemd-b012e92123bdc9fa10c2f079ec5bd9313b23e21a.tar.gz |
New upstream version 239
Diffstat (limited to 'src/libsystemd')
94 files changed, 1635 insertions, 2146 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 7ff5816180..1eec17db50 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -1,8 +1,6 @@ /*** SPDX-License-Identifier: LGPL-2.1+ - This file is part of systemd. - systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or @@ -555,3 +553,20 @@ global: sd_bus_get_n_queued_read; sd_bus_get_n_queued_write; } LIBSYSTEMD_237; + +LIBSYSTEMD_239 { +global: + sd_bus_open_with_description; + sd_bus_open_user_with_description; + sd_bus_open_system_with_description; + sd_bus_slot_get_floating; + sd_bus_slot_set_floating; + sd_bus_slot_get_destroy_callback; + sd_bus_slot_set_destroy_callback; + sd_bus_track_get_destroy_callback; + sd_bus_track_set_destroy_callback; + sd_event_add_inotify; + sd_event_source_get_inotify_mask; + sd_event_source_set_destroy_callback; + sd_event_source_get_destroy_callback; +} LIBSYSTEMD_238; diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index bd72e3d691..070fd6c633 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -1,19 +1,4 @@ # SPDX-License-Identifier: LGPL-2.1+ -# -# Copyright 2017 Zbigniew Jędrzejewski-Szmek -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# systemd is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with systemd; If not, see <http://www.gnu.org/licenses/>. id128_sources = files(''' sd-id128/id128-util.c @@ -95,15 +80,17 @@ libsystemd_sources = files(''' sd-utf8/sd-utf8.c '''.split()) + id128_sources + sd_daemon_c + sd_event_c + sd_login_c +libsystemd_c_args = ['-fvisibility=default'] + libsystemd_static = static_library( - 'systemd', + 'systemd_static', libsystemd_sources, install : false, include_directories : includes, link_with : libbasic, dependencies : [threads, librt], - c_args : ['-fvisibility=default']) + c_args : libsystemd_c_args) libsystemd_sym = 'src/libsystemd/libsystemd.sym' diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index 07a1f50047..ff0790bf5a 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2014 Zbigniew Jędrzejewski-Szmek - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <errno.h> @@ -31,6 +13,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, ENOENT), SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_EXISTS, EEXIST), SD_BUS_ERROR_MAP(BUS_ERROR_LOAD_FAILED, EIO), + SD_BUS_ERROR_MAP(BUS_ERROR_BAD_UNIT_SETTING, ENOEXEC), SD_BUS_ERROR_MAP(BUS_ERROR_JOB_FAILED, EREMOTEIO), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_JOB, ENOENT), SD_BUS_ERROR_MAP(BUS_ERROR_NOT_SUBSCRIBED, EINVAL), @@ -72,6 +55,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_SESSION_BUSY, EBUSY), SD_BUS_ERROR_MAP(BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, EALREADY), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_NTP_SUPPORT, EOPNOTSUPP), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_PROCESS, ESRCH), diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index 42c0f528f0..3945c7f6ac 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "bus-error.h" @@ -27,6 +11,7 @@ #define BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID "org.freedesktop.systemd1.NoUnitForInvocationID" #define BUS_ERROR_UNIT_EXISTS "org.freedesktop.systemd1.UnitExists" #define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed" +#define BUS_ERROR_BAD_UNIT_SETTING "org.freedesktop.systemd1.BadUnitSetting" #define BUS_ERROR_JOB_FAILED "org.freedesktop.systemd1.JobFailed" #define BUS_ERROR_NO_SUCH_JOB "org.freedesktop.systemd1.NoSuchJob" #define BUS_ERROR_NOT_SUBSCRIBED "org.freedesktop.systemd1.NotSubscribed" @@ -54,6 +39,8 @@ #define BUS_ERROR_NO_SUCH_USER_MAPPING "org.freedesktop.machine1.NoSuchUserMapping" #define BUS_ERROR_NO_SUCH_GROUP_MAPPING "org.freedesktop.machine1.NoSuchGroupMapping" +#define BUS_ERROR_NO_SUCH_PORTABLE_IMAGE "org.freedesktop.portable1.NoSuchImage" + #define BUS_ERROR_NO_SUCH_SESSION "org.freedesktop.login1.NoSuchSession" #define BUS_ERROR_NO_SESSION_FOR_PID "org.freedesktop.login1.NoSessionForPID" #define BUS_ERROR_NO_SUCH_USER "org.freedesktop.login1.NoSuchUser" @@ -68,6 +55,7 @@ #define BUS_ERROR_SESSION_BUSY "org.freedesktop.login1.SessionBusy" #define BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED "org.freedesktop.timedate1.AutomaticTimeSyncEnabled" +#define BUS_ERROR_NO_NTP_SUPPORT "org.freedesktop.timedate1.NoNTPSupport" #define BUS_ERROR_NO_SUCH_PROCESS "org.freedesktop.systemd1.NoSuchProcess" diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c index 477f7053ed..f50274a6a4 100644 --- a/src/libsystemd/sd-bus/bus-container.c +++ b/src/libsystemd/sd-bus/bus-container.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <fcntl.h> diff --git a/src/libsystemd/sd-bus/bus-container.h b/src/libsystemd/sd-bus/bus-container.h index 6921ffd52d..dd115b4e24 100644 --- a/src/libsystemd/sd-bus/bus-container.h +++ b/src/libsystemd/sd-bus/bus-container.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 9dd5274bf6..18a2cc2c9b 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #if HAVE_VALGRIND_MEMCHECK_H @@ -431,14 +415,11 @@ _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatabl if (r < 0) return r; - *activatable = y; - y = NULL; + *activatable = TAKE_PTR(y); } - if (acquired) { - *acquired = x; - x = NULL; - } + if (acquired) + *acquired = TAKE_PTR(x); return 0; } @@ -734,10 +715,8 @@ _public_ int sd_bus_get_name_creds( return r; } - if (creds) { - *creds = c; - c = NULL; - } + if (creds) + *creds = TAKE_PTR(c); return 0; } @@ -810,8 +789,8 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r if (r < 0) return r; - *ret = c; - c = NULL; + *ret = TAKE_PTR(c); + return 0; } diff --git a/src/libsystemd/sd-bus/bus-control.h b/src/libsystemd/sd-bus/bus-control.h index 3d9acebaf6..9017297496 100644 --- a/src/libsystemd/sd-bus/bus-control.h +++ b/src/libsystemd/sd-bus/bus-control.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 8da6640ca0..41910515db 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "bus-internal.h" diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index b6ef4a0fe5..aae9fcd58b 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <linux/capability.h> @@ -129,7 +113,6 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { sd_bus_message_unref(m); } - return NULL; } @@ -222,7 +205,6 @@ _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) { return 0; } - _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) { assert_return(c, -EINVAL); assert_return(fsuid, -EINVAL); @@ -1344,7 +1326,7 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) if (r < 0) return r; - *ret = n; - n = NULL; + *ret = TAKE_PTR(n); + return 0; } diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h index c4c60fa2d7..7b77a1d735 100644 --- a/src/libsystemd/sd-bus/bus-creds.h +++ b/src/libsystemd/sd-bus/bus-creds.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdbool.h> diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c index 2d93e1e437..3a28c7c6e3 100644 --- a/src/libsystemd/sd-bus/bus-dump.c +++ b/src/libsystemd/sd-bus/bus-dump.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "alloc-util.h" diff --git a/src/libsystemd/sd-bus/bus-dump.h b/src/libsystemd/sd-bus/bus-dump.h index ab3b039203..8e47411a45 100644 --- a/src/libsystemd/sd-bus/bus-dump.h +++ b/src/libsystemd/sd-bus/bus-dump.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdbool.h> diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 3939d0a4ef..ec359ac13c 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> @@ -108,6 +92,7 @@ static int bus_error_name_to_errno(const char *name) { } m = __start_BUS_ERROR_MAP; +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION while (m < __stop_BUS_ERROR_MAP) { /* For magic ELF error maps, the end marker might * appear in the middle of things, since multiple maps @@ -125,6 +110,7 @@ static int bus_error_name_to_errno(const char *name) { m++; } +#endif return EIO; } diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index 6181e37d81..93cb9acd91 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdbool.h> diff --git a/src/libsystemd/sd-bus/bus-gvariant.c b/src/libsystemd/sd-bus/bus-gvariant.c index e6ab984d1f..05b17589dd 100644 --- a/src/libsystemd/sd-bus/bus-gvariant.c +++ b/src/libsystemd/sd-bus/bus-gvariant.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> diff --git a/src/libsystemd/sd-bus/bus-gvariant.h b/src/libsystemd/sd-bus/bus-gvariant.h index 474e131566..40e3053ec6 100644 --- a/src/libsystemd/sd-bus/bus-gvariant.h +++ b/src/libsystemd/sd-bus/bus-gvariant.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "macro.h" diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index 05a022fbf3..7bb653338d 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "alloc-util.h" diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index b305c41622..2087ef8eeb 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <pthread.h> @@ -140,8 +124,17 @@ struct sd_bus_slot { unsigned n_ref; sd_bus *bus; void *userdata; + sd_bus_destroy_t destroy_callback; BusSlotType type:5; + + /* Slots can be "floating" or not. If they are not floating (the usual case) then they reference the bus object + * they are associated with. This means the bus object stays allocated at least as long as there is a slot + * around associated with it. If it is floating, then the slot's lifecycle is bound to the lifecycle of the + * bus: it will be disconnected from the bus when the bus is destroyed, and it keeping the slot reffed hence + * won't mean the bus stays reffed too. Internally this means the reference direction is reversed: floating + * slots objects are referenced by the bus object, and not vice versa. */ bool floating:1; + bool match_added:1; char *description; @@ -278,7 +271,7 @@ struct sd_bus { uint64_t creds_mask; int *fds; - unsigned n_fds; + size_t n_fds; char *exec_path; char **exec_argv; @@ -338,7 +331,7 @@ struct sd_bus { #define BUS_WQUEUE_MAX (192*1024) #define BUS_RQUEUE_MAX (192*1024) -#define BUS_MESSAGE_SIZE_MAX (64*1024*1024) +#define BUS_MESSAGE_SIZE_MAX (128*1024*1024) #define BUS_AUTH_SIZE_MAX (64*1024) #define BUS_CONTAINER_DEPTH 128 diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index 9bd2dadfde..cfcbd8b072 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdio_ext.h> diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h index 5d2d5a17dd..5dcaeace9d 100644 --- a/src/libsystemd/sd-bus/bus-introspect.h +++ b/src/libsystemd/sd-bus/bus-introspect.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdio.h> diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index b27b9d7d86..1f61bd3f95 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #if HAVE_VALGRIND_MEMCHECK_H diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h index fa78e5c80d..44c9a76311 100644 --- a/src/libsystemd/sd-bus/bus-kernel.h +++ b/src/libsystemd/sd-bus/bus-kernel.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c index 8d798c0a58..7d04cc4bd1 100644 --- a/src/libsystemd/sd-bus/bus-match.c +++ b/src/libsystemd/sd-bus/bus-match.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdio_ext.h> @@ -903,12 +887,10 @@ int bus_match_parse( } components[n_components].type = t; - components[n_components].value_str = value; + components[n_components].value_str = TAKE_PTR(value); components[n_components].value_u8 = u; n_components++; - value = NULL; - if (q[quoted] == 0) break; diff --git a/src/libsystemd/sd-bus/bus-match.h b/src/libsystemd/sd-bus/bus-match.h index ac2e51a422..050f4ba033 100644 --- a/src/libsystemd/sd-bus/bus-match.h +++ b/src/libsystemd/sd-bus/bus-match.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index c76f6e87ba..8d92bc2002 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> @@ -109,7 +93,7 @@ static void message_reset_containers(sd_bus_message *m) { m->root_container.index = 0; } -static void message_free(sd_bus_message *m) { +static sd_bus_message* message_free(sd_bus_message *m) { assert(m); if (m->free_header) @@ -134,9 +118,11 @@ static void message_free(sd_bus_message *m) { free(m->root_container.peeked_signature); bus_creds_done(&m->creds); - free(m); + return mfree(m); } +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, message_free); + static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) { void *op, *np; size_t old_size, new_size, start; @@ -412,7 +398,7 @@ int bus_message_from_header( size_t footer_accessible, size_t message_size, int *fds, - unsigned n_fds, + size_t n_fds, const char *label, size_t extra, sd_bus_message **ret) { @@ -513,8 +499,7 @@ int bus_message_from_header( } m->bus = sd_bus_ref(bus); - *ret = m; - m = NULL; + *ret = TAKE_PTR(m); return 0; } @@ -524,11 +509,11 @@ int bus_message_from_malloc( void *buffer, size_t length, int *fds, - unsigned n_fds, + size_t n_fds, const char *label, sd_bus_message **ret) { - sd_bus_message *m; + _cleanup_(message_freep) sd_bus_message *m = NULL; size_t sz; int r; @@ -559,18 +544,14 @@ int bus_message_from_malloc( r = bus_message_parse_fields(m); if (r < 0) - goto fail; + return r; /* We take possession of the memory and fds now */ m->free_header = true; m->free_fds = true; - *ret = m; + *ret = TAKE_PTR(m); return 0; - -fail: - message_free(m); - return r; } _public_ int sd_bus_message_new( @@ -612,7 +593,7 @@ _public_ int sd_bus_message_new_signal( const char *interface, const char *member) { - sd_bus_message *t; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL; int r; assert_return(bus, -ENOTCONN); @@ -632,20 +613,16 @@ _public_ int sd_bus_message_new_signal( r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path); if (r < 0) - goto fail; + return r; r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface); if (r < 0) - goto fail; + return r; r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member); if (r < 0) - goto fail; + return r; - *m = t; + *m = TAKE_PTR(t); return 0; - -fail: - sd_bus_message_unref(t); - return r; } _public_ int sd_bus_message_new_method_call( @@ -656,7 +633,7 @@ _public_ int sd_bus_message_new_method_call( const char *interface, const char *member) { - sd_bus_message *t; + _cleanup_(message_freep) sd_bus_message *t = NULL; int r; assert_return(bus, -ENOTCONN); @@ -675,29 +652,25 @@ _public_ int sd_bus_message_new_method_call( r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path); if (r < 0) - goto fail; + return r; r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member); if (r < 0) - goto fail; + return r; if (interface) { r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface); if (r < 0) - goto fail; + return r; } if (destination) { r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination); if (r < 0) - goto fail; + return r; } - *m = t; + *m = TAKE_PTR(t); return 0; - -fail: - message_free(t); - return r; } static int message_new_reply( @@ -705,7 +678,7 @@ static int message_new_reply( uint8_t type, sd_bus_message **m) { - sd_bus_message *t; + _cleanup_(message_freep) sd_bus_message *t = NULL; uint64_t cookie; int r; @@ -729,23 +702,19 @@ static int message_new_reply( t->reply_cookie = cookie; r = message_append_reply_cookie(t, t->reply_cookie); if (r < 0) - goto fail; + return r; if (call->sender) { r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination); if (r < 0) - goto fail; + return r; } t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED); t->enforced_reply_signature = call->enforced_reply_signature; - *m = t; + *m = TAKE_PTR(t); return 0; - -fail: - message_free(t); - return r; } _public_ int sd_bus_message_new_method_return( @@ -760,7 +729,7 @@ _public_ int sd_bus_message_new_method_error( sd_bus_message **m, const sd_bus_error *e) { - sd_bus_message *t; + _cleanup_(message_freep) sd_bus_message *t = NULL; int r; assert_return(sd_bus_error_is_set(e), -EINVAL); @@ -772,22 +741,18 @@ _public_ int sd_bus_message_new_method_error( r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name); if (r < 0) - goto fail; + return r; if (e->message) { r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message); if (r < 0) - goto fail; + return r; } t->error._need_free = -1; - *m = t; + *m = TAKE_PTR(t); return 0; - -fail: - message_free(t); - return r; } _public_ int sd_bus_message_new_method_errorf( @@ -867,7 +832,7 @@ int bus_message_new_synthetic_error( const sd_bus_error *e, sd_bus_message **m) { - sd_bus_message *t; + _cleanup_(message_freep) sd_bus_message *t = NULL; int r; assert(bus); @@ -885,34 +850,30 @@ int bus_message_new_synthetic_error( r = message_append_reply_cookie(t, t->reply_cookie); if (r < 0) - goto fail; + return r; if (bus && bus->unique_name) { r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination); if (r < 0) - goto fail; + return r; } r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name); if (r < 0) - goto fail; + return r; if (e->message) { r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message); if (r < 0) - goto fail; + return r; } t->error._need_free = -1; bus_message_set_sender_driver(bus, t); - *m = t; + *m = TAKE_PTR(t); return 0; - -fail: - message_free(t); - return r; } _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) { @@ -937,8 +898,7 @@ _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) { if (m->n_ref > 0) return NULL; - message_free(m); - return NULL; + return message_free(m); } _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) { @@ -1085,10 +1045,10 @@ _public_ int sd_bus_message_is_signal( if (m->header->type != SD_BUS_MESSAGE_SIGNAL) return 0; - if (interface && (!m->interface || !streq(m->interface, interface))) + if (interface && !streq_ptr(m->interface, interface)) return 0; - if (member && (!m->member || !streq(m->member, member))) + if (member && !streq_ptr(m->member, member)) return 0; return 1; @@ -1104,10 +1064,10 @@ _public_ int sd_bus_message_is_method_call( if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL) return 0; - if (interface && (!m->interface || !streq(m->interface, interface))) + if (interface && !streq_ptr(m->interface, interface)) return 0; - if (member && (!m->member || !streq(m->member, member))) + if (member && !streq_ptr(m->member, member)) return 0; return 1; @@ -1119,7 +1079,7 @@ _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR) return 0; - if (name && (!m->error.name || !streq(m->error.name, name))) + if (name && !streq_ptr(m->error.name, name)) return 0; return 1; @@ -1665,7 +1625,7 @@ _public_ int sd_bus_message_append_string_space( _public_ int sd_bus_message_append_string_iovec( sd_bus_message *m, const struct iovec *iov, - unsigned n) { + unsigned n /* should be size_t, but is API now… 😞 */) { size_t size; unsigned i; @@ -1991,7 +1951,7 @@ _public_ int sd_bus_message_open_container( struct bus_container *c, *w; uint32_t *array_size = NULL; - char *signature; + _cleanup_free_ char *signature = NULL; size_t before, begin = 0; bool need_offsets = false; int r; @@ -2030,16 +1990,13 @@ _public_ int sd_bus_message_open_container( r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets); else r = -EINVAL; - - if (r < 0) { - free(signature); + if (r < 0) return r; - } /* OK, let's fill it in */ w = m->containers + m->n_containers++; w->enclosing = type; - w->signature = signature; + w->signature = TAKE_PTR(signature); w->index = 0; w->array_size = array_size; w->before = before; @@ -2589,7 +2546,7 @@ _public_ int sd_bus_message_append_array_iovec( sd_bus_message *m, char type, const struct iovec *iov, - unsigned n) { + unsigned n /* should be size_t, but is API now… 😞 */) { size_t size; unsigned i; @@ -3235,7 +3192,6 @@ end: return 0; } - static int message_peek_body( sd_bus_message *m, size_t *rindex, @@ -4012,9 +3968,9 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m, const char *contents) { struct bus_container *c, *w; uint32_t *array_size = NULL; - char *signature; + _cleanup_free_ char *signature = NULL; size_t before; - size_t *offsets = NULL; + _cleanup_free_ size_t *offsets = NULL; size_t n_offsets = 0, item_size = 0; int r; @@ -4088,17 +4044,13 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m, r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets); else r = -EINVAL; - - if (r <= 0) { - free(signature); - free(offsets); + if (r <= 0) return r; - } /* OK, let's fill it in */ w = m->containers + m->n_containers++; w->enclosing = type; - w->signature = signature; + w->signature = TAKE_PTR(signature); w->peeked_signature = NULL; w->index = 0; @@ -4115,7 +4067,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m, w->array_size = array_size; w->item_size = item_size; - w->offsets = offsets; + w->offsets = TAKE_PTR(offsets); w->n_offsets = n_offsets; w->offset_index = 0; @@ -4384,7 +4336,7 @@ static int message_read_ap( /* Ideally, we'd just call ourselves recursively on every * complex type. However, the state of a va_list that is * passed to a function is undefined after that function - * returns. This means we need to docode the va_list linearly + * returns. This means we need to decode the va_list linearly * in a single stackframe. We hence implement our own * home-grown stack in an array. */ @@ -5329,7 +5281,6 @@ int bus_message_parse_fields(sd_bus_message *m) { break; - case BUS_MESSAGE_HEADER_SIGNATURE: { const char *s; char *c; @@ -5351,8 +5302,7 @@ int bus_message_parse_fields(sd_bus_message *m) { if (!c) return -ENOMEM; - free(m->root_container.signature); - m->root_container.signature = c; + free_and_replace(m->root_container.signature, c); break; } @@ -5501,7 +5451,7 @@ _public_ int sd_bus_message_set_sender(sd_bus_message *m, const char *sender) { int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) { size_t total; void *p, *e; - unsigned i; + size_t i; struct bus_body_part *part; assert(m); @@ -5553,7 +5503,7 @@ int bus_message_read_strv_extend(sd_bus_message *m, char ***l) { } _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) { - char **strv = NULL; + _cleanup_strv_free_ char **strv = NULL; int r; assert_return(m, -EINVAL); @@ -5561,12 +5511,10 @@ _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) { assert_return(l, -EINVAL); r = bus_message_read_strv_extend(m, &strv); - if (r <= 0) { - strv_free(strv); + if (r <= 0) return r; - } - *l = strv; + *l = TAKE_PTR(strv); return 1; } @@ -5869,8 +5817,7 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) { return r; sd_bus_message_unref(*m); - *m = n; - n = NULL; + *m = TAKE_PTR(n); return 0; } diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index 88998700d6..97f6060e30 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <byteswap.h> @@ -195,7 +179,7 @@ int bus_message_from_header( size_t footer_accessible, size_t message_size, int *fds, - unsigned n_fds, + size_t n_fds, const char *label, size_t extra, sd_bus_message **ret); @@ -205,7 +189,7 @@ int bus_message_from_malloc( void *buffer, size_t length, int *fds, - unsigned n_fds, + size_t n_fds, const char *label, sd_bus_message **ret); diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index 6e00255b20..9609834fa9 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "alloc-util.h" @@ -173,9 +157,9 @@ static int add_enumerated_to_set( enum { /* if set, add_subtree() works recursively */ - CHILDREN_RECURSIVE = (1U << 1), + CHILDREN_RECURSIVE = 1 << 0, /* if set, add_subtree() scans object-manager hierarchies recursively */ - CHILDREN_SUBHIERARCHIES = (1U << 0), + CHILDREN_SUBHIERARCHIES = 1 << 1, }; static int add_subtree_to_set( @@ -1470,8 +1454,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) { return NULL; n->parent = parent; - n->path = s; - s = NULL; /* do not free */ + n->path = TAKE_PTR(s); r = hashmap_put(bus->nodes, n->path, n); if (r < 0) { diff --git a/src/libsystemd/sd-bus/bus-objects.h b/src/libsystemd/sd-bus/bus-objects.h index 6bffeda726..e8e1a522cb 100644 --- a/src/libsystemd/sd-bus/bus-objects.h +++ b/src/libsystemd/sd-bus/bus-objects.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "bus-internal.h" diff --git a/src/libsystemd/sd-bus/bus-protocol.h b/src/libsystemd/sd-bus/bus-protocol.h index 0d5dfd9474..20d19d4022 100644 --- a/src/libsystemd/sd-bus/bus-protocol.h +++ b/src/libsystemd/sd-bus/bus-protocol.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <endian.h> diff --git a/src/libsystemd/sd-bus/bus-signature.c b/src/libsystemd/sd-bus/bus-signature.c index f3cd9bd0fa..18c91e8707 100644 --- a/src/libsystemd/sd-bus/bus-signature.c +++ b/src/libsystemd/sd-bus/bus-signature.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <util.h> @@ -109,7 +93,6 @@ static int signature_element_length_internal( return -EINVAL; } - int signature_element_length(const char *s, size_t *l) { return signature_element_length_internal(s, true, 0, 0, l); } diff --git a/src/libsystemd/sd-bus/bus-signature.h b/src/libsystemd/sd-bus/bus-signature.h index a6be1844e2..d4b43bac00 100644 --- a/src/libsystemd/sd-bus/bus-signature.h +++ b/src/libsystemd/sd-bus/bus-signature.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdbool.h> diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c index 9a56371715..fbf37320d3 100644 --- a/src/libsystemd/sd-bus/bus-slot.c +++ b/src/libsystemd/sd-bus/bus-slot.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" @@ -170,7 +154,6 @@ void bus_slot_disconnect(sd_bus_slot *slot) { key.interface = slot->node_vtable.interface; key.member = v->x.method.member; - x = hashmap_remove(slot->bus->vtable_properties, &key); break; }} @@ -217,6 +200,10 @@ _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) { } bus_slot_disconnect(slot); + + if (slot->destroy_callback) + slot->destroy_callback(slot->userdata); + free(slot->description); return mfree(slot); } @@ -244,6 +231,22 @@ _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) { return ret; } +_public_ int sd_bus_slot_set_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t callback) { + assert_return(slot, -EINVAL); + + slot->destroy_callback = callback; + return 0; +} + +_public_ int sd_bus_slot_get_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t *callback) { + assert_return(slot, -EINVAL); + + if (callback) + *callback = slot->destroy_callback; + + return !!slot->destroy_callback; +} + _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) { assert_return(slot, NULL); assert_return(slot->type >= 0, NULL); @@ -274,6 +277,37 @@ _public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) { return slot->bus->current_userdata; } +_public_ int sd_bus_slot_get_floating(sd_bus_slot *slot) { + assert_return(slot, -EINVAL); + + return slot->floating; +} + +_public_ int sd_bus_slot_set_floating(sd_bus_slot *slot, int b) { + assert_return(slot, -EINVAL); + + if (slot->floating == !!b) + return 0; + + if (!slot->bus) /* already disconnected slots can't be reconnected */ + return -ESTALE; + + slot->floating = b; + + /* When a slot is "floating" then the bus references the slot. Otherwise the slot references the bus. Hence, + * when we move from one to the other, let's increase one reference and decrease the other. */ + + if (b) { + sd_bus_slot_ref(slot); + sd_bus_unref(slot->bus); + } else { + sd_bus_ref(slot->bus); + sd_bus_slot_unref(slot); + } + + return 1; +} + _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) { assert_return(slot, -EINVAL); @@ -283,8 +317,13 @@ _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *descript _public_ int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description) { assert_return(slot, -EINVAL); assert_return(description, -EINVAL); - assert_return(slot->description, -ENXIO); - *description = slot->description; + if (slot->description) + *description = slot->description; + else if (slot->type == BUS_MATCH_CALLBACK) + *description = slot->match_callback.match_string; + else + return -ENXIO; + return 0; } diff --git a/src/libsystemd/sd-bus/bus-slot.h b/src/libsystemd/sd-bus/bus-slot.h index beebaa1670..f1e1e23ac6 100644 --- a/src/libsystemd/sd-bus/bus-slot.h +++ b/src/libsystemd/sd-bus/bus-slot.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index b5160cff6a..b147a3843a 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <endian.h> @@ -261,16 +245,13 @@ static bool line_equals(const char *s, size_t m, const char *line) { } static bool line_begins(const char *s, size_t m, const char *word) { - size_t l; - - l = strlen(word); - if (m < l) - return false; + const char *p; - if (memcmp(s, word, l) != 0) + p = memory_startswith(s, m, word); + if (!p) return false; - return m == l || (m > l && s[l] == ' '); + return IN_SET(*p, 0, ' '); } static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) { @@ -552,7 +533,7 @@ static int bus_socket_read_auth(sd_bus *b) { mh.msg_control = &control; mh.msg_controllen = sizeof(control); - k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); + k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); if (k < 0 && errno == ENOTSOCK) { b->prefer_readv = true; k = readv(b->input_fd, &iov, 1); @@ -790,7 +771,7 @@ static int bus_socket_inotify_setup(sd_bus *b) { if (IN_SET(errno, ENOENT, ELOOP)) break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */ - r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", isempty(prefix) ? "/" : prefix); + r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", empty_to_root(prefix)); goto fail; } else new_watches[n++] = wd; @@ -960,14 +941,9 @@ int bus_socket_exec(sd_bus *b) { if (r == 0) { /* Child */ - safe_close(s[0]); - if (rearrange_stdio(s[1], s[1], STDERR_FILENO) < 0) _exit(EXIT_FAILURE); - (void) fd_nonblock(STDIN_FILENO, false); - (void) fd_nonblock(STDOUT_FILENO, false); - if (b->exec_argv) execvp(b->exec_path, b->exec_argv); else { @@ -1187,7 +1163,7 @@ int bus_socket_read_message(sd_bus *bus) { mh.msg_control = &control; mh.msg_controllen = sizeof(control); - k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); + k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); if (k < 0 && errno == ENOTSOCK) { bus->prefer_readv = true; k = readv(bus->input_fd, &iov, 1); diff --git a/src/libsystemd/sd-bus/bus-socket.h b/src/libsystemd/sd-bus/bus-socket.h index c180562f98..d1118ca1d4 100644 --- a/src/libsystemd/sd-bus/bus-socket.h +++ b/src/libsystemd/sd-bus/bus-socket.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c index 5482d39a01..16bf615f50 100644 --- a/src/libsystemd/sd-bus/bus-track.c +++ b/src/libsystemd/sd-bus/bus-track.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" @@ -44,6 +28,7 @@ struct sd_bus_track { bool in_queue:1; /* In bus->track_queue? */ bool modified:1; bool recursive:1; + sd_bus_destroy_t destroy_callback; LIST_FIELDS(sd_bus_track, tracks); }; @@ -177,18 +162,21 @@ _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) { return NULL; assert(track->n_ref > 0); + track->n_ref--; - if (track->n_ref > 1) { - track->n_ref--; + if (track->n_ref > 0) return NULL; - } if (track->in_list) LIST_REMOVE(tracks, track->bus->tracks, track); bus_track_remove_from_queue(track); - hashmap_free_with_destructor(track->names, track_item_free); - sd_bus_unref(track->bus); + track->names = hashmap_free_with_destructor(track->names, track_item_free); + track->bus = sd_bus_unref(track->bus); + + if (track->destroy_callback) + track->destroy_callback(track->userdata); + return mfree(track); } @@ -452,6 +440,22 @@ _public_ void *sd_bus_track_set_userdata(sd_bus_track *track, void *userdata) { return ret; } +_public_ int sd_bus_track_set_destroy_callback(sd_bus_track *track, sd_bus_destroy_t callback) { + assert_return(track, -EINVAL); + + track->destroy_callback = callback; + return 0; +} + +_public_ int sd_bus_track_get_destroy_callback(sd_bus_track *track, sd_bus_destroy_t *ret) { + assert_return(track, -EINVAL); + + if (ret) + *ret = track->destroy_callback; + + return !!track->destroy_callback; +} + _public_ int sd_bus_track_set_recursive(sd_bus_track *track, int b) { assert_return(track, -EINVAL); diff --git a/src/libsystemd/sd-bus/bus-track.h b/src/libsystemd/sd-bus/bus-track.h index 0c5636b7e0..f9590265d7 100644 --- a/src/libsystemd/sd-bus/bus-track.h +++ b/src/libsystemd/sd-bus/bus-track.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ void bus_track_dispatch(sd_bus_track *track); diff --git a/src/libsystemd/sd-bus/bus-type.c b/src/libsystemd/sd-bus/bus-type.c index 980b35d8ea..bc6726f9cf 100644 --- a/src/libsystemd/sd-bus/bus-type.c +++ b/src/libsystemd/sd-bus/bus-type.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> diff --git a/src/libsystemd/sd-bus/bus-type.h b/src/libsystemd/sd-bus/bus-type.h index 834f09777a..cdac55c62e 100644 --- a/src/libsystemd/sd-bus/bus-type.h +++ b/src/libsystemd/sd-bus/bus-type.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdbool.h> diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 2f5e483ae2..089b51a6d9 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <endian.h> @@ -176,7 +160,7 @@ static void bus_reset_queues(sd_bus *b) { b->wqueue_allocated = 0; } -static void bus_free(sd_bus *b) { +static sd_bus* bus_free(sd_bus *b) { sd_bus_slot *s; assert(b); @@ -241,56 +225,47 @@ static void bus_free(sd_bus *b) { assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0); - free(b); + return mfree(b); } +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, bus_free); + _public_ int sd_bus_new(sd_bus **ret) { - sd_bus *r; + _cleanup_free_ sd_bus *b = NULL; assert_return(ret, -EINVAL); - r = new0(sd_bus, 1); - if (!r) + b = new0(sd_bus, 1); + if (!b) return -ENOMEM; - r->n_ref = REFCNT_INIT; - r->input_fd = r->output_fd = -1; - r->inotify_fd = -1; - r->message_version = 1; - r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; - r->accept_fd = true; - r->original_pid = getpid_cached(); - r->n_groups = (size_t) -1; - - assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0); - - /* We guarantee that wqueue always has space for at least one - * entry */ - if (!GREEDY_REALLOC(r->wqueue, r->wqueue_allocated, 1)) { - free(r); + b->n_ref = REFCNT_INIT; + b->input_fd = b->output_fd = -1; + b->inotify_fd = -1; + b->message_version = 1; + b->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; + b->accept_fd = true; + b->original_pid = getpid_cached(); + b->n_groups = (size_t) -1; + + assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0); + + /* We guarantee that wqueue always has space for at least one entry */ + if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1)) return -ENOMEM; - } - *ret = r; + *ret = TAKE_PTR(b); return 0; } _public_ int sd_bus_set_address(sd_bus *bus, const char *address) { - char *a; - assert_return(bus, -EINVAL); assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(address, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); - a = strdup(address); - if (!a) - return -ENOMEM; - - free_and_replace(bus->address, a); - - return 0; + return free_and_strdup(&bus->address, address); } _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) { @@ -307,7 +282,8 @@ _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) { } _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) { - char *p, **a; + _cleanup_strv_free_ char **a = NULL; + int r; assert_return(bus, -EINVAL); assert_return(bus = bus_resolve(bus), -ENOPKG); @@ -316,22 +292,15 @@ _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) assert_return(!strv_isempty(argv), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); - p = strdup(path); - if (!p) - return -ENOMEM; - a = strv_copy(argv); - if (!a) { - free(p); + if (!a) return -ENOMEM; - } - - free_and_replace(bus->exec_path, p); - strv_free(bus->exec_argv); - bus->exec_argv = a; + r = free_and_strdup(&bus->exec_path, path); + if (r < 0) + return r; - return 0; + return strv_free_and_replace(bus->exec_argv, a); } _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) { @@ -524,8 +493,7 @@ static int synthesize_connected_signal(sd_bus *bus) { /* Insert at the very front */ memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size); - bus->rqueue[0] = m; - m = NULL; + bus->rqueue[0] = TAKE_PTR(m); bus->rqueue_size++; return 0; @@ -556,7 +524,6 @@ void bus_set_state(sd_bus *bus, enum bus_state state) { static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { const char *s; - char *t; sd_bus *bus; int r; @@ -576,11 +543,9 @@ static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *e if (!service_name_is_valid(s) || s[0] != ':') return -EBADMSG; - t = strdup(s); - if (!t) - return -ENOMEM; - - free_and_replace(bus->unique_name, t); + r = free_and_strdup(&bus->unique_name, s); + if (r < 0) + return r; if (bus->state == BUS_HELLO) { bus_set_state(bus, BUS_RUNNING); @@ -1220,9 +1185,9 @@ _public_ int sd_bus_start(sd_bus *bus) { return bus_send_hello(bus); } -_public_ int sd_bus_open(sd_bus **ret) { +_public_ int sd_bus_open_with_description(sd_bus **ret, const char *description) { const char *e; - sd_bus *b; + _cleanup_(bus_freep) sd_bus *b = NULL; int r; assert_return(ret, -EINVAL); @@ -1234,17 +1199,17 @@ _public_ int sd_bus_open(sd_bus **ret) { e = secure_getenv("DBUS_STARTER_BUS_TYPE"); if (e) { if (streq(e, "system")) - return sd_bus_open_system(ret); + return sd_bus_open_system_with_description(ret, description); else if (STR_IN_SET(e, "session", "user")) - return sd_bus_open_user(ret); + return sd_bus_open_user_with_description(ret, description); } e = secure_getenv("DBUS_STARTER_ADDRESS"); if (!e) { if (cg_pid_get_owner_uid(0, NULL) >= 0) - return sd_bus_open_user(ret); + return sd_bus_open_user_with_description(ret, description); else - return sd_bus_open_system(ret); + return sd_bus_open_system_with_description(ret, description); } r = sd_bus_new(&b); @@ -1253,7 +1218,7 @@ _public_ int sd_bus_open(sd_bus **ret) { r = sd_bus_set_address(b, e); if (r < 0) - goto fail; + return r; b->bus_client = true; @@ -1265,14 +1230,14 @@ _public_ int sd_bus_open(sd_bus **ret) { r = sd_bus_start(b); if (r < 0) - goto fail; + return r; - *ret = b; + *ret = TAKE_PTR(b); return 0; +} -fail: - bus_free(b); - return r; +_public_ int sd_bus_open(sd_bus **ret) { + return sd_bus_open_with_description(ret, NULL); } int bus_set_address_system(sd_bus *b) { @@ -1286,8 +1251,8 @@ int bus_set_address_system(sd_bus *b) { return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS); } -_public_ int sd_bus_open_system(sd_bus **ret) { - sd_bus *b; +_public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *description) { + _cleanup_(bus_freep) sd_bus *b = NULL; int r; assert_return(ret, -EINVAL); @@ -1296,9 +1261,15 @@ _public_ int sd_bus_open_system(sd_bus **ret) { if (r < 0) return r; + if (description) { + r = sd_bus_set_description(b, description); + if (r < 0) + return r; + } + r = bus_set_address_system(b); if (r < 0) - goto fail; + return r; b->bus_client = true; b->is_system = true; @@ -1311,14 +1282,14 @@ _public_ int sd_bus_open_system(sd_bus **ret) { r = sd_bus_start(b); if (r < 0) - goto fail; + return r; - *ret = b; + *ret = TAKE_PTR(b); return 0; +} -fail: - bus_free(b); - return r; +_public_ int sd_bus_open_system(sd_bus **ret) { + return sd_bus_open_system_with_description(ret, NULL); } int bus_set_address_user(sd_bus *b) { @@ -1342,14 +1313,13 @@ int bus_set_address_user(sd_bus *b) { if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, ee) < 0) return -ENOMEM; - b->address = s; - s = NULL; + b->address = TAKE_PTR(s); return 0; } -_public_ int sd_bus_open_user(sd_bus **ret) { - sd_bus *b; +_public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *description) { + _cleanup_(bus_freep) sd_bus *b = NULL; int r; assert_return(ret, -EINVAL); @@ -1358,9 +1328,15 @@ _public_ int sd_bus_open_user(sd_bus **ret) { if (r < 0) return r; + if (description) { + r = sd_bus_set_description(b, description); + if (r < 0) + return r; + } + r = bus_set_address_user(b); if (r < 0) - goto fail; + return r; b->bus_client = true; b->is_user = true; @@ -1372,14 +1348,14 @@ _public_ int sd_bus_open_user(sd_bus **ret) { r = sd_bus_start(b); if (r < 0) - goto fail; + return r; - *ret = b; + *ret = TAKE_PTR(b); return 0; +} -fail: - bus_free(b); - return r; +_public_ int sd_bus_open_user(sd_bus **ret) { + return sd_bus_open_user_with_description(ret, NULL); } int bus_set_address_system_remote(sd_bus *b, const char *host) { @@ -1396,7 +1372,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) { /* Let's make sure this is not a port of some kind, * and is a valid machine name. */ - if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) { + if (!in_charset(m, DIGITS) && machine_name_is_valid(m)) { char *t; /* Cut out the host part */ @@ -1419,41 +1395,35 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) { if (!a) return -ENOMEM; - free_and_replace(b->address, a); - - return 0; - } + return free_and_replace(b->address, a); +} _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) { - sd_bus *bus; + _cleanup_(bus_freep) sd_bus *b = NULL; int r; assert_return(host, -EINVAL); assert_return(ret, -EINVAL); - r = sd_bus_new(&bus); + r = sd_bus_new(&b); if (r < 0) return r; - r = bus_set_address_system_remote(bus, host); + r = bus_set_address_system_remote(b, host); if (r < 0) - goto fail; + return r; - bus->bus_client = true; - bus->trusted = false; - bus->is_system = true; - bus->is_local = false; + b->bus_client = true; + b->trusted = false; + b->is_system = true; + b->is_local = false; - r = sd_bus_start(bus); + r = sd_bus_start(b); if (r < 0) - goto fail; + return r; - *ret = bus; + *ret = TAKE_PTR(b); return 0; - -fail: - bus_free(bus); - return r; } int bus_set_address_system_machine(sd_bus *b, const char *machine) { @@ -1471,46 +1441,39 @@ int bus_set_address_system_machine(sd_bus *b, const char *machine) { if (!a) return -ENOMEM; - free_and_replace(b->address, a); - - return 0; + return free_and_replace(b->address, a); } _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) { - sd_bus *bus; + _cleanup_(bus_freep) sd_bus *b = NULL; int r; assert_return(machine, -EINVAL); assert_return(ret, -EINVAL); assert_return(machine_name_is_valid(machine), -EINVAL); - r = sd_bus_new(&bus); + r = sd_bus_new(&b); if (r < 0) return r; - r = bus_set_address_system_machine(bus, machine); + r = bus_set_address_system_machine(b, machine); if (r < 0) - goto fail; + return r; - bus->bus_client = true; - bus->trusted = false; - bus->is_system = true; - bus->is_local = false; + b->bus_client = true; + b->trusted = false; + b->is_system = true; + b->is_local = false; - r = sd_bus_start(bus); + r = sd_bus_start(b); if (r < 0) - goto fail; + return r; - *ret = bus; + *ret = TAKE_PTR(b); return 0; - -fail: - bus_free(bus); - return r; } _public_ void sd_bus_close(sd_bus *bus) { - if (!bus) return; if (bus->state == BUS_CLOSED) @@ -1534,7 +1497,6 @@ _public_ void sd_bus_close(sd_bus *bus) { } _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) { - if (!bus) return NULL; @@ -1557,7 +1519,6 @@ void bus_enter_closing(sd_bus *bus) { } _public_ sd_bus *sd_bus_ref(sd_bus *bus) { - if (!bus) return NULL; @@ -1576,12 +1537,10 @@ _public_ sd_bus *sd_bus_unref(sd_bus *bus) { if (i > 0) return NULL; - bus_free(bus); - return NULL; + return bus_free(bus); } _public_ int sd_bus_is_open(sd_bus *bus) { - assert_return(bus, -EINVAL); assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2752,8 +2711,8 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd if (r < 0) return r; - *ret = m; - m = NULL; + *ret = TAKE_PTR(m); + return 1; } @@ -2912,10 +2871,8 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { bus->exit_triggered = true; (void) bus_exit_now(bus); - if (ret) { - *ret = m; - m = NULL; - } + if (ret) + *ret = TAKE_PTR(m); r = 1; @@ -3267,13 +3224,21 @@ static int bus_add_match_full( goto finish; } - if (asynchronous) + if (asynchronous) { r = bus_add_match_internal_async(bus, &s->match_callback.install_slot, s->match_callback.match_string, add_match_callback, s); - else + + if (r < 0) + return r; + + /* Make the slot of the match call floating now. We need the reference, but we don't + * want that this match pins the bus object, hence we first create it non-floating, but + * then make it floating. */ + r = sd_bus_slot_set_floating(s->match_callback.install_slot, true); + } else r = bus_add_match_internal(bus, s->match_callback.match_string); if (r < 0) goto finish; @@ -3670,7 +3635,6 @@ _public_ int sd_bus_default_system(sd_bus **ret) { return bus_default(sd_bus_open_system, &default_system_bus, ret); } - _public_ int sd_bus_default_user(sd_bus **ret) { return bus_default(sd_bus_open_user, &default_user_bus, ret); } diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c index bfd0f39372..8134abba2f 100644 --- a/src/libsystemd/sd-bus/test-bus-benchmark.c +++ b/src/libsystemd/sd-bus/test-bus-benchmark.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <sys/wait.h> diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index bd6721946a..1e25e94586 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <fcntl.h> @@ -64,11 +48,11 @@ static int server_init(sd_bus **_bus) { sd_bus *bus = NULL; sd_id128_t id; int r; - const char *unique; + const char *unique, *desc; assert_se(_bus); - r = sd_bus_open_user(&bus); + r = sd_bus_open_user_with_description(&bus, "my bus!"); if (r < 0) { log_error_errno(r, "Failed to connect to user bus: %m"); goto fail; @@ -86,6 +70,9 @@ static int server_init(sd_bus **_bus) { goto fail; } + r = sd_bus_get_description(bus, &desc); + assert_se(streq(desc, "my bus!")); + log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id)); log_info("Unique ID: %s", unique); log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h')); diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c index d5601fc57b..d1d962ebb2 100644 --- a/src/libsystemd/sd-bus/test-bus-cleanup.c +++ b/src/libsystemd/sd-bus/test-bus-cleanup.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Zbigniew Jędrzejewski-Szmek - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <stdio.h> diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c index f654692bf6..6746c0973e 100644 --- a/src/libsystemd/sd-bus/test-bus-creds.c +++ b/src/libsystemd/sd-bus/test-bus-creds.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c index 4e3f404e68..250657b18e 100644 --- a/src/libsystemd/sd-bus/test-bus-error.c +++ b/src/libsystemd/sd-bus/test-bus-error.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-bus.h" diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c index 4c372fd05a..75804f3458 100644 --- a/src/libsystemd/sd-bus/test-bus-gvariant.c +++ b/src/libsystemd/sd-bus/test-bus-gvariant.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #if HAVE_GLIB diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c index 8dee936768..00167cb643 100644 --- a/src/libsystemd/sd-bus/test-bus-introspect.c +++ b/src/libsystemd/sd-bus/test-bus-introspect.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "bus-introspect.h" diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c index ebf55e873c..c647f0ff12 100644 --- a/src/libsystemd/sd-bus/test-bus-marshal.c +++ b/src/libsystemd/sd-bus/test-bus-marshal.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <math.h> @@ -217,6 +201,7 @@ int main(int argc, char *argv[]) { free(h); #if HAVE_GLIB +#ifndef __SANITIZE_ADDRESS__ { GDBusMessage *g; char *p; @@ -232,6 +217,7 @@ int main(int argc, char *argv[]) { g_object_unref(g); } #endif +#endif #if HAVE_DBUS { diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c index 47b45647c2..2822a8f82a 100644 --- a/src/libsystemd/sd-bus/test-bus-match.c +++ b/src/libsystemd/sd-bus/test-bus-match.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "bus-match.h" diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c index 58ef8b6389..094dd6c8a0 100644 --- a/src/libsystemd/sd-bus/test-bus-objects.c +++ b/src/libsystemd/sd-bus/test-bus-objects.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <pthread.h> diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c index 245f5707e1..31b54e252c 100644 --- a/src/libsystemd/sd-bus/test-bus-server.c +++ b/src/libsystemd/sd-bus/test-bus-server.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <pthread.h> @@ -81,7 +65,8 @@ static void *server(void *p) { if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) { - assert_se((sd_bus_can_send(bus, 'h') >= 1) == (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds)); + assert_se((sd_bus_can_send(bus, 'h') >= 1) == + (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds)); r = sd_bus_message_new_method_return(m, &reply); if (r < 0) { diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c index aa6160d1c9..1ba1909198 100644 --- a/src/libsystemd/sd-bus/test-bus-signature.c +++ b/src/libsystemd/sd-bus/test-bus-signature.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "bus-internal.h" diff --git a/src/libsystemd/sd-bus/test-bus-track.c b/src/libsystemd/sd-bus/test-bus-track.c index 94c9d09de3..48d708b258 100644 --- a/src/libsystemd/sd-bus/test-bus-track.c +++ b/src/libsystemd/sd-bus/test-bus-track.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2016 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> diff --git a/src/libsystemd/sd-bus/test-bus-watch-bind.c b/src/libsystemd/sd-bus/test-bus-watch-bind.c index aef5ba9486..42a9ce5301 100644 --- a/src/libsystemd/sd-bus/test-bus-watch-bind.c +++ b/src/libsystemd/sd-bus/test-bus-watch-bind.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2017 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <pthread.h> diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 1334498ca4..9e9b115557 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> @@ -141,8 +125,7 @@ _public_ int sd_listen_fds_with_names(int unset_environment, char ***names) { return r; } - *names = l; - l = NULL; + *names = TAKE_PTR(l); return n_fds; } diff --git a/src/libsystemd/sd-device/device-enumerator-private.h b/src/libsystemd/sd-device/device-enumerator-private.h index 5a46ec5f2b..5d58ac93ca 100644 --- a/src/libsystemd/sd-device/device-enumerator-private.h +++ b/src/libsystemd/sd-device/device-enumerator-private.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2015 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-device.h" diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index cd9ec042bf..ee71fa8810 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -1,23 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2008-2012 Kay Sievers <kay@vrfy.org> - Copyright 2014-2015 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-device.h" @@ -71,8 +52,7 @@ _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) { enumerator->n_ref = 1; enumerator->type = _DEVICE_ENUMERATION_TYPE_INVALID; - *ret = enumerator; - enumerator = NULL; + *ret = TAKE_PTR(enumerator); return 0; } diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h index 6be84f9575..64da0501fe 100644 --- a/src/libsystemd/sd-device/device-internal.h +++ b/src/libsystemd/sd-device/device-internal.h @@ -1,25 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2008-2012 Kay Sievers <kay@vrfy.org> - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "hashmap.h" #include "set.h" diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index 77f0f4b2ee..d1f1b085ac 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -1,23 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2008-2012 Kay Sievers <kay@vrfy.org> - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <ctype.h> #include <net/if.h> @@ -586,8 +567,7 @@ int device_new_from_strv(sd_device **ret, char **strv) { if (r < 0) return r; - *ret = device; - device = NULL; + *ret = TAKE_PTR(device); return 0; } @@ -635,8 +615,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) { if (r < 0) return r; - *ret = device; - device = NULL; + *ret = TAKE_PTR(device); return 0; } @@ -812,8 +791,7 @@ int device_shallow_clone(sd_device *old_device, sd_device **new_device) { ret->devnum = old_device->devnum; - *new_device = ret; - ret = NULL; + *new_device = TAKE_PTR(ret); return 0; } @@ -835,8 +813,7 @@ int device_clone_with_db(sd_device *old_device, sd_device **new_device) { ret->sealed = true; - *new_device = ret; - ret = NULL; + *new_device = TAKE_PTR(ret); return 0; } @@ -861,8 +838,7 @@ int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, if (r < 0) return r; - *new_device = ret; - ret = NULL; + *new_device = TAKE_PTR(ret); return 0; } diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index 02d93c98f9..800c9ba7bd 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <inttypes.h> #include <stdbool.h> diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index d55b810d2a..6dcd2645e6 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2014-2015 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "util.h" diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 1297dfa911..be29053f8c 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1,23 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2008-2012 Kay Sievers <kay@vrfy.org> - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <ctype.h> #include <net/if.h> @@ -46,7 +27,7 @@ #include "util.h" int device_new_aux(sd_device **ret) { - _cleanup_(sd_device_unrefp) sd_device *device = NULL; + sd_device *device = NULL; assert(ret); @@ -58,7 +39,6 @@ int device_new_aux(sd_device **ret) { device->watch_handle = -1; *ret = device; - device = NULL; return 0; } @@ -168,12 +148,9 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { if (verify) { r = chase_symlinks(_syspath, NULL, 0, &syspath); if (r == -ENOENT) - /* the device does not exist (any more?) */ - return -ENODEV; - else if (r < 0) { - log_debug_errno(r, "sd-device: could not get target of '%s': %m", _syspath); - return r; - } + return -ENODEV; /* the device does not exist (any more?) */ + if (r < 0) + return log_debug_errno(r, "sd-device: could not get target of '%s': %m", _syspath); if (!path_startswith(syspath, "/sys")) { _cleanup_free_ char *real_sys = NULL, *new_syspath = NULL; @@ -195,7 +172,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { return log_oom(); free_and_replace(syspath, new_syspath); - path_kill_slashes(syspath); + path_simplify(syspath, false); } if (path_startswith(syspath, "/sys/devices/")) { @@ -250,8 +227,7 @@ _public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) { if (r < 0) return r; - *ret = device; - device = NULL; + *ret = TAKE_PTR(device); return 0; } @@ -662,8 +638,7 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) { if (ifr.ifr_ifindex != ifindex) return -ENODEV; - *ret = device; - device = NULL; + *ret = TAKE_PTR(device); return 0; } @@ -1297,8 +1272,7 @@ int device_get_id_filename(sd_device *device, const char **ret) { } } - device->id_filename = id; - id = NULL; + device->id_filename = TAKE_PTR(id); } *ret = device->id_filename; @@ -1837,8 +1811,7 @@ _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, if (r < 0) return r; - *_value = value; - value = NULL; + *_value = TAKE_PTR(value); return 0; } diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 7355921d30..d53b9a7026 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <sys/epoll.h> @@ -28,6 +12,7 @@ #include "alloc-util.h" #include "fd-util.h" +#include "fs-util.h" #include "hashmap.h" #include "list.h" #include "macro.h" @@ -56,6 +41,7 @@ typedef enum EventSourceType { SOURCE_POST, SOURCE_EXIT, SOURCE_WATCHDOG, + SOURCE_INOTIFY, _SOURCE_EVENT_SOURCE_TYPE_MAX, _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1 } EventSourceType; @@ -73,6 +59,7 @@ static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] [SOURCE_POST] = "post", [SOURCE_EXIT] = "exit", [SOURCE_WATCHDOG] = "watchdog", + [SOURCE_INOTIFY] = "inotify", }; DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int); @@ -84,12 +71,15 @@ typedef enum WakeupType { WAKEUP_EVENT_SOURCE, WAKEUP_CLOCK_DATA, WAKEUP_SIGNAL_DATA, + WAKEUP_INOTIFY_DATA, _WAKEUP_TYPE_MAX, _WAKEUP_TYPE_INVALID = -1, } WakeupType; #define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM) +struct inode_data; + struct sd_event_source { WakeupType wakeup; @@ -113,6 +103,8 @@ struct sd_event_source { uint64_t pending_iteration; uint64_t prepare_iteration; + sd_event_destroy_t destroy_callback; + LIST_FIELDS(sd_event_source, sources); union { @@ -151,6 +143,12 @@ struct sd_event_source { sd_event_handler_t callback; unsigned prioq_index; } exit; + struct { + sd_event_inotify_handler_t callback; + uint32_t mask; + struct inode_data *inode_data; + LIST_FIELDS(sd_event_source, by_inode_data); + } inotify; }; }; @@ -185,6 +183,64 @@ struct signal_data { sd_event_source *current; }; +/* A structure listing all event sources currently watching a specific inode */ +struct inode_data { + /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */ + ino_t ino; + dev_t dev; + + /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can + * rearrange the priority still until then, as we need the original inode to change the priority as we need to + * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the + * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of + * the sd-event object, so that it is efficient to close everything, before entering the next event loop + * iteration. */ + int fd; + + /* The inotify "watch descriptor" */ + int wd; + + /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has + * most recently been set on the watch descriptor. */ + uint32_t combined_mask; + + /* All event sources subscribed to this inode */ + LIST_HEAD(sd_event_source, event_sources); + + /* The inotify object we watch this inode with */ + struct inotify_data *inotify_data; + + /* A linked list of all inode data objects with fds to close (see above) */ + LIST_FIELDS(struct inode_data, to_close); +}; + +/* A structure encapsulating an inotify fd */ +struct inotify_data { + WakeupType wakeup; + + /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at + * a time */ + + int fd; + int64_t priority; + + Hashmap *inodes; /* The inode_data structures keyed by dev+ino */ + Hashmap *wd; /* The inode_data structures keyed by the watch descriptor for each */ + + /* The buffer we read inotify events into */ + union inotify_event_buffer buffer; + size_t buffer_filled; /* fill level of the buffer */ + + /* How many event sources are currently marked pending for this inotify. We won't read new events off the + * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing + * the events locally if they can't be coalesced). */ + unsigned n_pending; + + /* A linked list of all inotify objects with data already read, that still need processing. We keep this list + * to make it efficient to figure out what inotify objects to process data on next. */ + LIST_FIELDS(struct inotify_data, buffered); +}; + struct sd_event { unsigned n_ref; @@ -215,6 +271,14 @@ struct sd_event { Prioq *exit; + Hashmap *inotify_data; /* indexed by priority */ + + /* A list of inode structures that still have an fd open, that we need to close before the next loop iteration */ + LIST_HEAD(struct inode_data, inode_data_to_close); + + /* A list of inotify objects that already have events buffered which aren't processed yet */ + LIST_HEAD(struct inotify_data, inotify_data_buffered); + pid_t original_pid; uint64_t iteration; @@ -244,6 +308,7 @@ struct sd_event { static thread_local sd_event *default_event = NULL; static void source_disconnect(sd_event_source *s); +static void event_gc_inode_data(sd_event *e, struct inode_data *d); static sd_event *event_resolve(sd_event *e) { return e == SD_EVENT_DEFAULT ? default_event : e; @@ -425,6 +490,8 @@ static void event_free(sd_event *e) { free(e->signal_sources); hashmap_free(e->signal_data); + hashmap_free(e->inotify_data); + hashmap_free(e->child_sources); set_free(e->post_sources); free(e); @@ -436,16 +503,32 @@ _public_ int sd_event_new(sd_event** ret) { assert_return(ret, -EINVAL); - e = new0(sd_event, 1); + e = new(sd_event, 1); if (!e) return -ENOMEM; - e->n_ref = 1; - e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1; - e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY; - e->realtime.wakeup = e->boottime.wakeup = e->monotonic.wakeup = e->realtime_alarm.wakeup = e->boottime_alarm.wakeup = WAKEUP_CLOCK_DATA; - e->original_pid = getpid_cached(); - e->perturb = USEC_INFINITY; + *e = (sd_event) { + .n_ref = 1, + .epoll_fd = -1, + .watchdog_fd = -1, + .realtime.wakeup = WAKEUP_CLOCK_DATA, + .realtime.fd = -1, + .realtime.next = USEC_INFINITY, + .boottime.wakeup = WAKEUP_CLOCK_DATA, + .boottime.fd = -1, + .boottime.next = USEC_INFINITY, + .monotonic.wakeup = WAKEUP_CLOCK_DATA, + .monotonic.fd = -1, + .monotonic.next = USEC_INFINITY, + .realtime_alarm.wakeup = WAKEUP_CLOCK_DATA, + .realtime_alarm.fd = -1, + .realtime_alarm.next = USEC_INFINITY, + .boottime_alarm.wakeup = WAKEUP_CLOCK_DATA, + .boottime_alarm.fd = -1, + .boottime_alarm.next = USEC_INFINITY, + .perturb = USEC_INFINITY, + .original_pid = getpid_cached(), + }; r = prioq_ensure_allocated(&e->pending, pending_prioq_compare); if (r < 0) @@ -531,18 +614,17 @@ static int source_io_register( int enabled, uint32_t events) { - struct epoll_event ev = {}; + struct epoll_event ev; int r; assert(s); assert(s->type == SOURCE_IO); assert(enabled != SD_EVENT_OFF); - ev.events = events; - ev.data.ptr = s; - - if (enabled == SD_EVENT_ONESHOT) - ev.events |= EPOLLONESHOT; + ev = (struct epoll_event) { + .events = events | (enabled == SD_EVENT_ONESHOT ? EPOLLONESHOT : 0), + .data.ptr = s, + }; if (s->io.registered) r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->io.fd, &ev); @@ -634,7 +716,7 @@ static int event_make_signal_data( int sig, struct signal_data **ret) { - struct epoll_event ev = {}; + struct epoll_event ev; struct signal_data *d; bool added = false; sigset_t ss_copy; @@ -649,7 +731,7 @@ static int event_make_signal_data( if (e->signal_sources && e->signal_sources[sig]) priority = e->signal_sources[sig]->priority; else - priority = 0; + priority = SD_EVENT_PRIORITY_NORMAL; d = hashmap_get(e->signal_data, &priority); if (d) { @@ -663,13 +745,15 @@ static int event_make_signal_data( if (r < 0) return r; - d = new0(struct signal_data, 1); + d = new(struct signal_data, 1); if (!d) return -ENOMEM; - d->wakeup = WAKEUP_SIGNAL_DATA; - d->fd = -1; - d->priority = priority; + *d = (struct signal_data) { + .wakeup = WAKEUP_SIGNAL_DATA, + .fd = -1, + .priority = priority, + }; r = hashmap_put(e->signal_data, &d->priority, d); if (r < 0) { @@ -699,8 +783,10 @@ static int event_make_signal_data( d->fd = fd_move_above_stdio(r); - ev.events = EPOLLIN; - ev.data.ptr = d; + ev = (struct epoll_event) { + .events = EPOLLIN, + .data.ptr = d, + }; r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, d->fd, &ev); if (r < 0) { @@ -867,6 +953,41 @@ static void source_disconnect(sd_event_source *s) { prioq_remove(s->event->exit, s, &s->exit.prioq_index); break; + case SOURCE_INOTIFY: { + struct inode_data *inode_data; + + inode_data = s->inotify.inode_data; + if (inode_data) { + struct inotify_data *inotify_data; + assert_se(inotify_data = inode_data->inotify_data); + + /* Detach this event source from the inode object */ + LIST_REMOVE(inotify.by_inode_data, inode_data->event_sources, s); + s->inotify.inode_data = NULL; + + if (s->pending) { + assert(inotify_data->n_pending > 0); + inotify_data->n_pending--; + } + + /* Note that we don't reduce the inotify mask for the watch descriptor here if the inode is + * continued to being watched. That's because inotify doesn't really have an API for that: we + * can only change watch masks with access to the original inode either by fd or by path. But + * paths aren't stable, and keeping an O_PATH fd open all the time would mean wasting an fd + * continously and keeping the mount busy which we can't really do. We could reconstruct the + * original inode from /proc/self/fdinfo/$INOTIFY_FD (as all watch descriptors are listed + * there), but given the need for open_by_handle_at() which is privileged and not universally + * available this would be quite an incomplete solution. Hence we go the other way, leave the + * mask set, even if it is not minimized now, and ignore all events we aren't interested in + * anymore after reception. Yes, this sucks, but … Linux … */ + + /* Maybe release the inode data (and its inotify) */ + event_gc_inode_data(s->event, inode_data); + } + + break; + } + default: assert_not_reached("Wut? I shouldn't exist."); } @@ -894,7 +1015,10 @@ static void source_free(sd_event_source *s) { source_disconnect(s); if (s->type == SOURCE_IO && s->io.owned) - safe_close(s->io.fd); + s->io.fd = safe_close(s->io.fd); + + if (s->destroy_callback) + s->destroy_callback(s->userdata); free(s->description); free(s); @@ -941,6 +1065,19 @@ static int source_set_pending(sd_event_source *s, bool b) { d->current = NULL; } + if (s->type == SOURCE_INOTIFY) { + + assert(s->inotify.inode_data); + assert(s->inotify.inode_data->inotify_data); + + if (b) + s->inotify.inode_data->inotify_data->n_pending ++; + else { + assert(s->inotify.inode_data->inotify_data->n_pending > 0); + s->inotify.inode_data->inotify_data->n_pending --; + } + } + return 0; } @@ -949,15 +1086,18 @@ static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType t assert(e); - s = new0(sd_event_source, 1); + s = new(sd_event_source, 1); if (!s) return NULL; - s->n_ref = 1; - s->event = e; - s->floating = floating; - s->type = type; - s->pending_index = s->prepare_index = PRIOQ_IDX_NULL; + *s = (struct sd_event_source) { + .n_ref = 1, + .event = e, + .floating = floating, + .type = type, + .pending_index = PRIOQ_IDX_NULL, + .prepare_index = PRIOQ_IDX_NULL, + }; if (!floating) sd_event_ref(e); @@ -1034,7 +1174,7 @@ static int event_setup_timer_fd( struct clock_data *d, clockid_t clock) { - struct epoll_event ev = {}; + struct epoll_event ev; int r, fd; assert(e); @@ -1049,8 +1189,10 @@ static int event_setup_timer_fd( fd = fd_move_above_stdio(fd); - ev.events = EPOLLIN; - ev.data.ptr = d; + ev = (struct epoll_event) { + .events = EPOLLIN, + .data.ptr = d, + }; r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev); if (r < 0) { @@ -1387,6 +1529,405 @@ _public_ int sd_event_add_exit( return 0; } +static void event_free_inotify_data(sd_event *e, struct inotify_data *d) { + assert(e); + + if (!d) + return; + + assert(hashmap_isempty(d->inodes)); + assert(hashmap_isempty(d->wd)); + + if (d->buffer_filled > 0) + LIST_REMOVE(buffered, e->inotify_data_buffered, d); + + hashmap_free(d->inodes); + hashmap_free(d->wd); + + assert_se(hashmap_remove(e->inotify_data, &d->priority) == d); + + if (d->fd >= 0) { + if (epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, d->fd, NULL) < 0) + log_debug_errno(errno, "Failed to remove inotify fd from epoll, ignoring: %m"); + + safe_close(d->fd); + } + free(d); +} + +static int event_make_inotify_data( + sd_event *e, + int64_t priority, + struct inotify_data **ret) { + + _cleanup_close_ int fd = -1; + struct inotify_data *d; + struct epoll_event ev; + int r; + + assert(e); + + d = hashmap_get(e->inotify_data, &priority); + if (d) { + if (ret) + *ret = d; + return 0; + } + + fd = inotify_init1(IN_NONBLOCK|O_CLOEXEC); + if (fd < 0) + return -errno; + + fd = fd_move_above_stdio(fd); + + r = hashmap_ensure_allocated(&e->inotify_data, &uint64_hash_ops); + if (r < 0) + return r; + + d = new(struct inotify_data, 1); + if (!d) + return -ENOMEM; + + *d = (struct inotify_data) { + .wakeup = WAKEUP_INOTIFY_DATA, + .fd = TAKE_FD(fd), + .priority = priority, + }; + + r = hashmap_put(e->inotify_data, &d->priority, d); + if (r < 0) { + d->fd = safe_close(d->fd); + free(d); + return r; + } + + ev = (struct epoll_event) { + .events = EPOLLIN, + .data.ptr = d, + }; + + if (epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, d->fd, &ev) < 0) { + r = -errno; + d->fd = safe_close(d->fd); /* let's close this ourselves, as event_free_inotify_data() would otherwise + * remove the fd from the epoll first, which we don't want as we couldn't + * add it in the first place. */ + event_free_inotify_data(e, d); + return r; + } + + if (ret) + *ret = d; + + return 1; +} + +static int inode_data_compare(const void *a, const void *b) { + const struct inode_data *x = a, *y = b; + + assert(x); + assert(y); + + if (x->dev < y->dev) + return -1; + if (x->dev > y->dev) + return 1; + + if (x->ino < y->ino) + return -1; + if (x->ino > y->ino) + return 1; + + return 0; +} + +static void inode_data_hash_func(const void *p, struct siphash *state) { + const struct inode_data *d = p; + + assert(p); + + siphash24_compress(&d->dev, sizeof(d->dev), state); + siphash24_compress(&d->ino, sizeof(d->ino), state); +} + +const struct hash_ops inode_data_hash_ops = { + .hash = inode_data_hash_func, + .compare = inode_data_compare +}; + +static void event_free_inode_data( + sd_event *e, + struct inode_data *d) { + + assert(e); + + if (!d) + return; + + assert(!d->event_sources); + + if (d->fd >= 0) { + LIST_REMOVE(to_close, e->inode_data_to_close, d); + safe_close(d->fd); + } + + if (d->inotify_data) { + + if (d->wd >= 0) { + if (d->inotify_data->fd >= 0) { + /* So here's a problem. At the time this runs the watch descriptor might already be + * invalidated, because an IN_IGNORED event might be queued right the moment we enter + * the syscall. Hence, whenever we get EINVAL, ignore it entirely, since it's a very + * likely case to happen. */ + + if (inotify_rm_watch(d->inotify_data->fd, d->wd) < 0 && errno != EINVAL) + log_debug_errno(errno, "Failed to remove watch descriptor %i from inotify, ignoring: %m", d->wd); + } + + assert_se(hashmap_remove(d->inotify_data->wd, INT_TO_PTR(d->wd)) == d); + } + + assert_se(hashmap_remove(d->inotify_data->inodes, d) == d); + } + + free(d); +} + +static void event_gc_inode_data( + sd_event *e, + struct inode_data *d) { + + struct inotify_data *inotify_data; + + assert(e); + + if (!d) + return; + + if (d->event_sources) + return; + + inotify_data = d->inotify_data; + event_free_inode_data(e, d); + + if (inotify_data && hashmap_isempty(inotify_data->inodes)) + event_free_inotify_data(e, inotify_data); +} + +static int event_make_inode_data( + sd_event *e, + struct inotify_data *inotify_data, + dev_t dev, + ino_t ino, + struct inode_data **ret) { + + struct inode_data *d, key; + int r; + + assert(e); + assert(inotify_data); + + key = (struct inode_data) { + .ino = ino, + .dev = dev, + }; + + d = hashmap_get(inotify_data->inodes, &key); + if (d) { + if (ret) + *ret = d; + + return 0; + } + + r = hashmap_ensure_allocated(&inotify_data->inodes, &inode_data_hash_ops); + if (r < 0) + return r; + + d = new(struct inode_data, 1); + if (!d) + return -ENOMEM; + + *d = (struct inode_data) { + .dev = dev, + .ino = ino, + .wd = -1, + .fd = -1, + .inotify_data = inotify_data, + }; + + r = hashmap_put(inotify_data->inodes, d, d); + if (r < 0) { + free(d); + return r; + } + + if (ret) + *ret = d; + + return 1; +} + +static uint32_t inode_data_determine_mask(struct inode_data *d) { + bool excl_unlink = true; + uint32_t combined = 0; + sd_event_source *s; + + assert(d); + + /* Combines the watch masks of all event sources watching this inode. We generally just OR them together, but + * the IN_EXCL_UNLINK flag is ANDed instead. + * + * Note that we add all sources to the mask here, regardless whether enabled, disabled or oneshot. That's + * because we cannot change the mask anymore after the event source was created once, since the kernel has no + * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and supress + * events we don't care for client-side. */ + + LIST_FOREACH(inotify.by_inode_data, s, d->event_sources) { + + if ((s->inotify.mask & IN_EXCL_UNLINK) == 0) + excl_unlink = false; + + combined |= s->inotify.mask; + } + + return (combined & ~(IN_ONESHOT|IN_DONT_FOLLOW|IN_ONLYDIR|IN_EXCL_UNLINK)) | (excl_unlink ? IN_EXCL_UNLINK : 0); +} + +static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { + uint32_t combined_mask; + int wd, r; + + assert(d); + assert(d->fd >= 0); + + combined_mask = inode_data_determine_mask(d); + + if (d->wd >= 0 && combined_mask == d->combined_mask) + return 0; + + r = hashmap_ensure_allocated(&d->inotify_data->wd, NULL); + if (r < 0) + return r; + + wd = inotify_add_watch_fd(d->inotify_data->fd, d->fd, combined_mask); + if (wd < 0) + return -errno; + + if (d->wd < 0) { + r = hashmap_put(d->inotify_data->wd, INT_TO_PTR(wd), d); + if (r < 0) { + (void) inotify_rm_watch(d->inotify_data->fd, wd); + return r; + } + + d->wd = wd; + + } else if (d->wd != wd) { + + log_debug("Weird, the watch descriptor we already knew for this inode changed?"); + (void) inotify_rm_watch(d->fd, wd); + return -EINVAL; + } + + d->combined_mask = combined_mask; + return 1; +} + +_public_ int sd_event_add_inotify( + sd_event *e, + sd_event_source **ret, + const char *path, + uint32_t mask, + sd_event_inotify_handler_t callback, + void *userdata) { + + bool rm_inotify = false, rm_inode = false; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; + _cleanup_close_ int fd = -1; + sd_event_source *s; + struct stat st; + int r; + + assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); + assert_return(path, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(!event_pid_changed(e), -ECHILD); + + /* Refuse IN_MASK_ADD since we coalesce watches on the same inode, and hence really don't want to merge + * masks. Or in other words, this whole code exists only to manage IN_MASK_ADD type operations for you, hence + * the user can't use them for us. */ + if (mask & IN_MASK_ADD) + return -EINVAL; + + fd = open(path, O_PATH|O_CLOEXEC| + (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| + (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + return -errno; + + if (fstat(fd, &st) < 0) + return -errno; + + s = source_new(e, !ret, SOURCE_INOTIFY); + if (!s) + return -ENOMEM; + + s->enabled = mask & IN_ONESHOT ? SD_EVENT_ONESHOT : SD_EVENT_ON; + s->inotify.mask = mask; + s->inotify.callback = callback; + s->userdata = userdata; + + /* Allocate an inotify object for this priority, and an inode object within it */ + r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data); + if (r < 0) + goto fail; + rm_inotify = r > 0; + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); + if (r < 0) + goto fail; + rm_inode = r > 0; + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ + if (inode_data->fd < 0) { + inode_data->fd = TAKE_FD(fd); + LIST_PREPEND(to_close, e->inode_data_to_close, inode_data); + } + + /* Link our event source to the inode data object */ + LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s); + s->inotify.inode_data = inode_data; + + rm_inode = rm_inotify = false; + + /* Actually realize the watch now */ + r = inode_data_realize_watch(e, inode_data); + if (r < 0) + goto fail; + + (void) sd_event_source_set_description(s, path); + + if (ret) + *ret = s; + + return 0; + +fail: + source_free(s); + + if (rm_inode) + event_free_inode_data(e, inode_data); + + if (rm_inotify) + event_free_inotify_data(e, inotify_data); + + return r; +} + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { if (!s) @@ -1541,6 +2082,10 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) if (s->io.events == events && !(events & EPOLLET)) return 0; + r = source_set_pending(s, false); + if (r < 0) + return r; + if (s->enabled != SD_EVENT_OFF) { r = source_io_register(s, s->enabled, events); if (r < 0) @@ -1548,7 +2093,6 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) } s->io.events = events; - source_set_pending(s, false); return 0; } @@ -1581,6 +2125,9 @@ _public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) } _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) { + bool rm_inotify = false, rm_inode = false; + struct inotify_data *new_inotify_data = NULL; + struct inode_data *new_inode_data = NULL; int r; assert_return(s, -EINVAL); @@ -1590,7 +2137,59 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) if (s->priority == priority) return 0; - if (s->type == SOURCE_SIGNAL && s->enabled != SD_EVENT_OFF) { + if (s->type == SOURCE_INOTIFY) { + struct inode_data *old_inode_data; + + assert(s->inotify.inode_data); + old_inode_data = s->inotify.inode_data; + + /* We need the original fd to change the priority. If we don't have it we can't change the priority, + * anymore. Note that we close any fds when entering the next event loop iteration, i.e. for inotify + * events we allow priority changes only until the first following iteration. */ + if (old_inode_data->fd < 0) + return -EOPNOTSUPP; + + r = event_make_inotify_data(s->event, priority, &new_inotify_data); + if (r < 0) + return r; + rm_inotify = r > 0; + + r = event_make_inode_data(s->event, new_inotify_data, old_inode_data->dev, old_inode_data->ino, &new_inode_data); + if (r < 0) + goto fail; + rm_inode = r > 0; + + if (new_inode_data->fd < 0) { + /* Duplicate the fd for the new inode object if we don't have any yet */ + new_inode_data->fd = fcntl(old_inode_data->fd, F_DUPFD_CLOEXEC, 3); + if (new_inode_data->fd < 0) { + r = -errno; + goto fail; + } + + LIST_PREPEND(to_close, s->event->inode_data_to_close, new_inode_data); + } + + /* Move the event source to the new inode data structure */ + LIST_REMOVE(inotify.by_inode_data, old_inode_data->event_sources, s); + LIST_PREPEND(inotify.by_inode_data, new_inode_data->event_sources, s); + s->inotify.inode_data = new_inode_data; + + /* Now create the new watch */ + r = inode_data_realize_watch(s->event, new_inode_data); + if (r < 0) { + /* Move it back */ + LIST_REMOVE(inotify.by_inode_data, new_inode_data->event_sources, s); + LIST_PREPEND(inotify.by_inode_data, old_inode_data->event_sources, s); + s->inotify.inode_data = old_inode_data; + goto fail; + } + + s->priority = priority; + + event_gc_inode_data(s->event, old_inode_data); + + } else if (s->type == SOURCE_SIGNAL && s->enabled != SD_EVENT_OFF) { struct signal_data *old, *d; /* Move us from the signalfd belonging to the old @@ -1620,6 +2219,15 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); return 0; + +fail: + if (rm_inode) + event_free_inode_data(s->event, new_inode_data); + + if (rm_inotify) + event_free_inotify_data(s->event, new_inotify_data); + + return r; } _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) { @@ -1648,6 +2256,13 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { if (m == SD_EVENT_OFF) { + /* Unset the pending flag when this event source is disabled */ + if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { + r = source_set_pending(s, false); + if (r < 0) + return r; + } + switch (s->type) { case SOURCE_IO: @@ -1694,6 +2309,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { case SOURCE_DEFER: case SOURCE_POST: + case SOURCE_INOTIFY: s->enabled = m; break; @@ -1702,6 +2318,14 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { } } else { + + /* Unset the pending flag when this event source is enabled */ + if (s->enabled == SD_EVENT_OFF && !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { + r = source_set_pending(s, false); + if (r < 0) + return r; + } + switch (s->type) { case SOURCE_IO: @@ -1766,6 +2390,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { case SOURCE_DEFER: case SOURCE_POST: + case SOURCE_INOTIFY: s->enabled = m; break; @@ -1795,15 +2420,18 @@ _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) { _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { struct clock_data *d; + int r; assert_return(s, -EINVAL); assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(s->event), -ECHILD); - s->time.next = usec; + r = source_set_pending(s, false); + if (r < 0) + return r; - source_set_pending(s, false); + s->time.next = usec; d = event_get_clock_data(s->event, s->type); assert(d); @@ -1827,6 +2455,7 @@ _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *use _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) { struct clock_data *d; + int r; assert_return(s, -EINVAL); assert_return(usec != (uint64_t) -1, -EINVAL); @@ -1834,13 +2463,15 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(s->event), -ECHILD); + r = source_set_pending(s, false); + if (r < 0) + return r; + if (usec == 0) usec = DEFAULT_ACCURACY_USEC; s->time.accuracy = usec; - source_set_pending(s, false); - d = event_get_clock_data(s->event, s->type); assert(d); @@ -1870,6 +2501,16 @@ _public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) { return 0; } +_public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *mask) { + assert_return(s, -EINVAL); + assert_return(mask, -EINVAL); + assert_return(s->type == SOURCE_INOTIFY, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); + + *mask = s->inotify.mask; + return 0; +} + _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) { int r; @@ -2203,6 +2844,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { int r; assert(e); + assert(d); assert_return(events == EPOLLIN, -EIO); /* If there's a signal queued on this priority and SIGCHLD is @@ -2259,6 +2901,160 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { } } +static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t revents) { + ssize_t n; + + assert(e); + assert(d); + + assert_return(revents == EPOLLIN, -EIO); + + /* If there's already an event source pending for this priority, don't read another */ + if (d->n_pending > 0) + return 0; + + /* Is the read buffer non-empty? If so, let's not read more */ + if (d->buffer_filled > 0) + return 0; + + n = read(d->fd, &d->buffer, sizeof(d->buffer)); + if (n < 0) { + if (IN_SET(errno, EAGAIN, EINTR)) + return 0; + + return -errno; + } + + assert(n > 0); + d->buffer_filled = (size_t) n; + LIST_PREPEND(buffered, e->inotify_data_buffered, d); + + return 1; +} + +static void event_inotify_data_drop(sd_event *e, struct inotify_data *d, size_t sz) { + assert(e); + assert(d); + assert(sz <= d->buffer_filled); + + if (sz == 0) + return; + + /* Move the rest to the buffer to the front, in order to get things properly aligned again */ + memmove(d->buffer.raw, d->buffer.raw + sz, d->buffer_filled - sz); + d->buffer_filled -= sz; + + if (d->buffer_filled == 0) + LIST_REMOVE(buffered, e->inotify_data_buffered, d); +} + +static int event_inotify_data_process(sd_event *e, struct inotify_data *d) { + int r; + + assert(e); + assert(d); + + /* If there's already an event source pending for this priority, don't read another */ + if (d->n_pending > 0) + return 0; + + while (d->buffer_filled > 0) { + size_t sz; + + /* Let's validate that the event structures are complete */ + if (d->buffer_filled < offsetof(struct inotify_event, name)) + return -EIO; + + sz = offsetof(struct inotify_event, name) + d->buffer.ev.len; + if (d->buffer_filled < sz) + return -EIO; + + if (d->buffer.ev.mask & IN_Q_OVERFLOW) { + struct inode_data *inode_data; + Iterator i; + + /* The queue overran, let's pass this event to all event sources connected to this inotify + * object */ + + HASHMAP_FOREACH(inode_data, d->inodes, i) { + sd_event_source *s; + + LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) { + + if (s->enabled == SD_EVENT_OFF) + continue; + + r = source_set_pending(s, true); + if (r < 0) + return r; + } + } + } else { + struct inode_data *inode_data; + sd_event_source *s; + + /* Find the inode object for this watch descriptor. If IN_IGNORED is set we also remove it from + * our watch descriptor table. */ + if (d->buffer.ev.mask & IN_IGNORED) { + + inode_data = hashmap_remove(d->wd, INT_TO_PTR(d->buffer.ev.wd)); + if (!inode_data) { + event_inotify_data_drop(e, d, sz); + continue; + } + + /* The watch descriptor was removed by the kernel, let's drop it here too */ + inode_data->wd = -1; + } else { + inode_data = hashmap_get(d->wd, INT_TO_PTR(d->buffer.ev.wd)); + if (!inode_data) { + event_inotify_data_drop(e, d, sz); + continue; + } + } + + /* Trigger all event sources that are interested in these events. Also trigger all event + * sources if IN_IGNORED or IN_UNMOUNT is set. */ + LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) { + + if (s->enabled == SD_EVENT_OFF) + continue; + + if ((d->buffer.ev.mask & (IN_IGNORED|IN_UNMOUNT)) == 0 && + (s->inotify.mask & d->buffer.ev.mask & IN_ALL_EVENTS) == 0) + continue; + + r = source_set_pending(s, true); + if (r < 0) + return r; + } + } + + /* Something pending now? If so, let's finish, otherwise let's read more. */ + if (d->n_pending > 0) + return 1; + } + + return 0; +} + +static int process_inotify(sd_event *e) { + struct inotify_data *d; + int r, done = 0; + + assert(e); + + LIST_FOREACH(buffered, d, e->inotify_data_buffered) { + r = event_inotify_data_process(e, d); + if (r < 0) + return r; + if (r > 0) + done ++; + } + + return done; +} + static int source_dispatch(sd_event_source *s) { EventSourceType saved_type; int r = 0; @@ -2328,7 +3124,7 @@ static int source_dispatch(sd_event_source *s) { /* Now, reap the PID for good. */ if (zombie) - waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED); + (void) waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED); break; } @@ -2345,6 +3141,28 @@ static int source_dispatch(sd_event_source *s) { r = s->exit.callback(s, s->userdata); break; + case SOURCE_INOTIFY: { + struct sd_event *e = s->event; + struct inotify_data *d; + size_t sz; + + assert(s->inotify.inode_data); + assert_se(d = s->inotify.inode_data->inotify_data); + + assert(d->buffer_filled >= offsetof(struct inotify_event, name)); + sz = offsetof(struct inotify_event, name) + d->buffer.ev.len; + assert(d->buffer_filled >= sz); + + r = s->inotify.callback(s, &d->buffer.ev, s->userdata); + + /* When no event is pending anymore on this inotify object, then let's drop the event from the + * buffer. */ + if (d->n_pending == 0) + event_inotify_data_drop(e, d, sz); + + break; + } + case SOURCE_WATCHDOG: case _SOURCE_EVENT_SOURCE_TYPE_MAX: case _SOURCE_EVENT_SOURCE_TYPE_INVALID: @@ -2403,6 +3221,7 @@ static int event_prepare(sd_event *e) { static int dispatch_exit(sd_event *e) { sd_event_source *p; + _cleanup_(sd_event_unrefp) sd_event *ref = NULL; int r; assert(e); @@ -2413,15 +3232,11 @@ static int dispatch_exit(sd_event *e) { return 0; } - sd_event_ref(e); + ref = sd_event_ref(e); e->iteration++; e->state = SD_EVENT_EXITING; - r = source_dispatch(p); - e->state = SD_EVENT_INITIAL; - sd_event_unref(e); - return r; } @@ -2482,6 +3297,25 @@ static int process_watchdog(sd_event *e) { return arm_watchdog(e); } +static void event_close_inode_data_fds(sd_event *e) { + struct inode_data *d; + + assert(e); + + /* Close the fds pointing to the inodes to watch now. We need to close them as they might otherwise pin + * filesystems. But we can't close them right-away as we need them as long as the user still wants to make + * adjustments to the even source, such as changing the priority (which requires us to remove and readd a watch + * for the inode). Hence, let's close them when entering the first iteration after they were added, as a + * compromise. */ + + while ((d = e->inode_data_to_close)) { + assert(d->fd >= 0); + d->fd = safe_close(d->fd); + + LIST_REMOVE(to_close, e->inode_data_to_close, d); + } +} + _public_ int sd_event_prepare(sd_event *e) { int r; @@ -2522,6 +3356,8 @@ _public_ int sd_event_prepare(sd_event *e) { if (r < 0) return r; + event_close_inode_data_fds(e); + if (event_next_pending(e) || e->need_process_child) goto pending; @@ -2557,6 +3393,10 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { ev_queue_max = MAX(e->n_sources, 1u); ev_queue = newa(struct epoll_event, ev_queue_max); + /* If we still have inotify data buffered, then query the other fds, but don't wait on it */ + if (e->inotify_data_buffered) + timeout = 0; + m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max, timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC)); if (m < 0) { @@ -2594,6 +3434,10 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { r = process_signal(e, ev_queue[i].data.ptr, ev_queue[i].events); break; + case WAKEUP_INOTIFY_DATA: + r = event_inotify_data_read(e, ev_queue[i].data.ptr, ev_queue[i].events); + break; + default: assert_not_reached("Invalid wake-up pointer"); } @@ -2632,6 +3476,10 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { goto finish; } + r = process_inotify(e); + if (r < 0) + goto finish; + if (event_next_pending(e)) { e->state = SD_EVENT_PENDING; @@ -2661,14 +3509,12 @@ _public_ int sd_event_dispatch(sd_event *e) { p = event_next_pending(e); if (p) { - sd_event_ref(e); + _cleanup_(sd_event_unrefp) sd_event *ref = NULL; + ref = sd_event_ref(e); e->state = SD_EVENT_RUNNING; r = source_dispatch(p); e->state = SD_EVENT_INITIAL; - - sd_event_unref(e); - return r; } @@ -2735,6 +3581,7 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { } _public_ int sd_event_loop(sd_event *e) { + _cleanup_(sd_event_unrefp) sd_event *ref = NULL; int r; assert_return(e, -EINVAL); @@ -2742,19 +3589,15 @@ _public_ int sd_event_loop(sd_event *e) { assert_return(!event_pid_changed(e), -ECHILD); assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); - sd_event_ref(e); + ref = sd_event_ref(e); while (e->state != SD_EVENT_FINISHED) { r = sd_event_run(e, (uint64_t) -1); if (r < 0) - goto finish; + return r; } - r = e->exit_code; - -finish: - sd_event_unref(e); - return r; + return e->exit_code; } _public_ int sd_event_get_fd(sd_event *e) { @@ -2874,7 +3717,7 @@ _public_ int sd_event_set_watchdog(sd_event *e, int b) { return e->watchdog; if (b) { - struct epoll_event ev = {}; + struct epoll_event ev; r = sd_watchdog_enabled(false, &e->watchdog_period); if (r <= 0) @@ -2892,8 +3735,10 @@ _public_ int sd_event_set_watchdog(sd_event *e, int b) { if (r < 0) goto fail; - ev.events = EPOLLIN; - ev.data.ptr = INT_TO_PTR(SOURCE_WATCHDOG); + ev = (struct epoll_event) { + .events = EPOLLIN, + .data.ptr = INT_TO_PTR(SOURCE_WATCHDOG), + }; r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->watchdog_fd, &ev); if (r < 0) { @@ -2932,3 +3777,19 @@ _public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) { *ret = e->iteration; return 0; } + +_public_ int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback) { + assert_return(s, -EINVAL); + + s->destroy_callback = callback; + return 0; +} + +_public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret) { + assert_return(s, -EINVAL); + + if (ret) + *ret = s->destroy_callback; + + return !!s->destroy_callback; +} diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c index 9873ae4a58..bde00cf719 100644 --- a/src/libsystemd/sd-event/test-event.c +++ b/src/libsystemd/sd-event/test-event.c @@ -1,33 +1,24 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <sys/wait.h> #include "sd-event.h" +#include "alloc-util.h" #include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" #include "log.h" #include "macro.h" +#include "parse-util.h" +#include "process-util.h" +#include "rm-rf.h" #include "signal-util.h" +#include "stdio-util.h" +#include "string-util.h" #include "util.h" -#include "process-util.h" static int prepare_handler(sd_event_source *s, void *userdata) { log_info("preparing %c", PTR_TO_INT(userdata)); @@ -197,7 +188,7 @@ static void test_basic(void) { got_a = false, got_b = false, got_c = false, got_d = 0; - /* Add a oneshot handler, trigger it, re-enable it, and trigger + /* Add a oneshot handler, trigger it, reenable it, and trigger * it again. */ assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0); assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0); @@ -355,6 +346,142 @@ static void test_rtqueue(void) { sd_event_unref(e); } +#define CREATE_EVENTS_MAX (70000U) + +struct inotify_context { + bool delete_self_handler_called; + unsigned create_called[CREATE_EVENTS_MAX]; + unsigned create_overflow; + unsigned n_create_events; +}; + +static void maybe_exit(sd_event_source *s, struct inotify_context *c) { + unsigned n; + + assert(s); + assert(c); + + if (!c->delete_self_handler_called) + return; + + for (n = 0; n < 3; n++) { + unsigned i; + + if (c->create_overflow & (1U << n)) + continue; + + for (i = 0; i < c->n_create_events; i++) + if (!(c->create_called[i] & (1U << n))) + return; + } + + sd_event_exit(sd_event_source_get_event(s), 0); +} + +static int inotify_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) { + struct inotify_context *c = userdata; + const char *description; + unsigned bit, n; + + assert_se(sd_event_source_get_description(s, &description) >= 0); + assert_se(safe_atou(description, &n) >= 0); + + assert_se(n <= 3); + bit = 1U << n; + + if (ev->mask & IN_Q_OVERFLOW) { + log_info("inotify-handler <%s>: overflow", description); + c->create_overflow |= bit; + } else if (ev->mask & IN_CREATE) { + unsigned i; + + log_info("inotify-handler <%s>: create on %s", description, ev->name); + + if (!streq(ev->name, "sub")) { + assert_se(safe_atou(ev->name, &i) >= 0); + + assert_se(i < c->n_create_events); + c->create_called[i] |= bit; + } + } else if (ev->mask & IN_DELETE) { + log_info("inotify-handler <%s>: delete of %s", description, ev->name); + assert_se(streq(ev->name, "sub")); + } else + assert_not_reached("unexpected inotify event"); + + maybe_exit(s, c); + return 1; +} + +static int delete_self_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) { + struct inotify_context *c = userdata; + + if (ev->mask & IN_Q_OVERFLOW) { + log_info("delete-self-handler: overflow"); + c->delete_self_handler_called = true; + } else if (ev->mask & IN_DELETE_SELF) { + log_info("delete-self-handler: delete-self"); + c->delete_self_handler_called = true; + } else if (ev->mask & IN_IGNORED) { + log_info("delete-self-handler: ignore"); + } else + assert_not_reached("unexpected inotify event (delete-self)"); + + maybe_exit(s, c); + return 1; +} + +static void test_inotify(unsigned n_create_events) { + _cleanup_(rm_rf_physical_and_freep) char *p = NULL; + sd_event_source *a = NULL, *b = NULL, *c = NULL, *d = NULL; + struct inotify_context context = { + .n_create_events = n_create_events, + }; + sd_event *e = NULL; + const char *q; + unsigned i; + + assert_se(sd_event_default(&e) >= 0); + + assert_se(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &p) >= 0); + + assert_se(sd_event_add_inotify(e, &a, p, IN_CREATE|IN_ONLYDIR, inotify_handler, &context) >= 0); + assert_se(sd_event_add_inotify(e, &b, p, IN_CREATE|IN_DELETE|IN_DONT_FOLLOW, inotify_handler, &context) >= 0); + assert_se(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_IDLE) >= 0); + assert_se(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_NORMAL) >= 0); + assert_se(sd_event_add_inotify(e, &c, p, IN_CREATE|IN_DELETE|IN_EXCL_UNLINK, inotify_handler, &context) >= 0); + assert_se(sd_event_source_set_priority(c, SD_EVENT_PRIORITY_IDLE) >= 0); + + assert_se(sd_event_source_set_description(a, "0") >= 0); + assert_se(sd_event_source_set_description(b, "1") >= 0); + assert_se(sd_event_source_set_description(c, "2") >= 0); + + q = strjoina(p, "/sub"); + assert_se(touch(q) >= 0); + assert_se(sd_event_add_inotify(e, &d, q, IN_DELETE_SELF, delete_self_handler, &context) >= 0); + + for (i = 0; i < n_create_events; i++) { + char buf[DECIMAL_STR_MAX(unsigned)+1]; + _cleanup_free_ char *z; + + xsprintf(buf, "%u", i); + assert_se(z = strjoin(p, "/", buf)); + + assert_se(touch(z) >= 0); + } + + assert_se(unlink(q) >= 0); + + assert_se(sd_event_loop(e) >= 0); + + sd_event_source_unref(a); + sd_event_source_unref(b); + sd_event_source_unref(c); + sd_event_source_unref(d); + + sd_event_unref(e); +} + int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); @@ -364,5 +491,8 @@ int main(int argc, char *argv[]) { test_sd_event_now(); test_rtqueue(); + test_inotify(100); /* should work without overflow */ + test_inotify(33000); /* should trigger a q overflow */ + return 0; } diff --git a/src/libsystemd/sd-hwdb/hwdb-internal.h b/src/libsystemd/sd-hwdb/hwdb-internal.h index 36dae8c755..1fc6d31aed 100644 --- a/src/libsystemd/sd-hwdb/hwdb-internal.h +++ b/src/libsystemd/sd-hwdb/hwdb-internal.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2012 Kay Sievers <kay@vrfy.org> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sparse-endian.h" #include "util.h" diff --git a/src/libsystemd/sd-hwdb/hwdb-util.h b/src/libsystemd/sd-hwdb/hwdb-util.h index b3053524e7..2998249199 100644 --- a/src/libsystemd/sd-hwdb/hwdb-util.h +++ b/src/libsystemd/sd-hwdb/hwdb-util.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-hwdb.h" diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c index 9418e8cf38..5c612d9a2f 100644 --- a/src/libsystemd/sd-hwdb/sd-hwdb.c +++ b/src/libsystemd/sd-hwdb/sd-hwdb.c @@ -1,23 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2012 Kay Sievers <kay@vrfy.org> - Copyright 2008 Alan Jenkins <alan.christopher.jenkins@googlemail.com> - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. + Copyright © 2008 Alan Jenkins <alan.christopher.jenkins@googlemail.com> ***/ #include <errno.h> @@ -373,8 +356,7 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) { log_debug("strings %8"PRIu64" bytes", le64toh(hwdb->head->strings_len)); log_debug("nodes %8"PRIu64" bytes", le64toh(hwdb->head->nodes_len)); - *ret = hwdb; - hwdb = NULL; + *ret = TAKE_PTR(hwdb); return 0; } diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index 8ce012e35f..edee985e44 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2016 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h index 9f3340e581..f0b4eca581 100644 --- a/src/libsystemd/sd-id128/id128-util.h +++ b/src/libsystemd/sd-id128/id128-util.h @@ -2,22 +2,6 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2016 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <stdbool.h> diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c index 561bcdf4f1..b7123280f3 100644 --- a/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libsystemd/sd-id128/sd-id128.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> @@ -111,7 +95,7 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) { return r; if (sd_id128_is_null(saved_machine_id)) - return -EINVAL; + return -ENOMEDIUM; } *ret = saved_machine_id; diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 6601bcd6be..c2f7133e42 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> @@ -286,7 +270,7 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, "STATE", &s, NULL); if (r == -ENOENT) { free(s); s = strdup("offline"); @@ -317,7 +301,7 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, "DISPLAY", &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, "DISPLAY", &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -325,8 +309,7 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { if (isempty(s)) return -ENODATA; - *session = s; - s = NULL; + *session = TAKE_PTR(s); return 0; } @@ -355,8 +338,7 @@ static int file_of_seat(const char *seat, char **_p) { if (!p) return -ENOMEM; - *_p = p; - p = NULL; + *_p = TAKE_PTR(p); return 0; } @@ -374,7 +356,7 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) variable = require_active ? "ACTIVE_UID" : "UIDS"; - r = parse_env_file(p, NEWLINE, variable, &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, variable, &s, NULL); if (r == -ENOENT) return 0; if (r < 0) @@ -403,7 +385,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, variable, &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, variable, &s, NULL); if (r == -ENOENT || (r >= 0 && isempty(s))) { if (array) *array = NULL; @@ -417,7 +399,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { return -ENOMEM; strv_uniq(a); - r = strv_length(a); + r = (int) strv_length(a); if (array) *array = a; @@ -481,7 +463,7 @@ _public_ int sd_session_is_active(const char *session) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, "ACTIVE", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -500,7 +482,7 @@ _public_ int sd_session_is_remote(const char *session) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, "REMOTE", &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, "REMOTE", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -521,7 +503,7 @@ _public_ int sd_session_get_state(const char *session, char **state) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, "STATE", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -529,8 +511,7 @@ _public_ int sd_session_get_state(const char *session, char **state) { if (isempty(s)) return -EIO; - *state = s; - s = NULL; + *state = TAKE_PTR(s); return 0; } @@ -545,7 +526,7 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, "UID", &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, "UID", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -567,7 +548,7 @@ static int session_get_string(const char *session, const char *field, char **val if (r < 0) return r; - r = parse_env_file(p, NEWLINE, field, &s, NULL); + r = parse_env_file(NULL, p, NEWLINE, field, &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -575,8 +556,7 @@ static int session_get_string(const char *session, const char *field, char **val if (isempty(s)) return -ENODATA; - *value = s; - s = NULL; + *value = TAKE_PTR(s); return 0; } @@ -660,7 +640,7 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, + r = parse_env_file(NULL, p, NEWLINE, "ACTIVE", &s, "ACTIVE_UID", &t, NULL); @@ -681,10 +661,8 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { return r; } - if (session && s) { - *session = s; - s = NULL; - } + if (session && s) + *session = TAKE_PTR(s); return 0; } @@ -700,7 +678,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui if (r < 0) return r; - r = parse_env_file(p, NEWLINE, + r = parse_env_file(NULL, p, NEWLINE, "SESSIONS", &s, "UIDS", &t, NULL); @@ -745,17 +723,13 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui } } - r = strv_length(a); + r = (int) strv_length(a); - if (sessions) { - *sessions = a; - a = NULL; - } + if (sessions) + *sessions = TAKE_PTR(a); - if (uids) { - *uids = b; - b = NULL; - } + if (uids) + *uids = TAKE_PTR(b); if (n_uids) *n_uids = n; @@ -773,7 +747,7 @@ static int seat_get_can(const char *seat, const char *variable) { if (r < 0) return r; - r = parse_env_file(p, NEWLINE, + r = parse_env_file(NULL, p, NEWLINE, variable, &s, NULL); if (r == -ENOENT) @@ -870,10 +844,8 @@ _public_ int sd_get_uids(uid_t **users) { r++; } - if (users) { - *users = l; - l = NULL; - } + if (users) + *users = TAKE_PTR(l); return r; } @@ -909,10 +881,9 @@ _public_ int sd_get_machine_names(char ***machines) { *b = NULL; } - if (machines) { - *machines = l; - l = NULL; - } + if (machines) + *machines = TAKE_PTR(l); + return r; } @@ -925,7 +896,7 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { assert_return(class, -EINVAL); p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(p, NEWLINE, "CLASS", &c, NULL); + r = parse_env_file(NULL, p, NEWLINE, "CLASS", &c, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -933,8 +904,7 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { if (!c) return -EIO; - *class = c; - c = NULL; + *class = TAKE_PTR(c); return 0; } @@ -950,7 +920,7 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) { assert_return(ifindices, -EINVAL); p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(p, NEWLINE, "NETIF", &netif, NULL); + r = parse_env_file(NULL, p, NEWLINE, "NETIF", &netif, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c index 559529ecf6..ccb1905a46 100644 --- a/src/libsystemd/sd-login/test-login.c +++ b/src/libsystemd/sd-login/test-login.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <poll.h> diff --git a/src/libsystemd/sd-netlink/generic-netlink.c b/src/libsystemd/sd-netlink/generic-netlink.c index 771658d9ae..347bf4cbd5 100644 --- a/src/libsystemd/sd-netlink/generic-netlink.c +++ b/src/libsystemd/sd-netlink/generic-netlink.c @@ -58,8 +58,7 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family family, uint16_t nlms genl->cmd = cmd; genl->version = genl_families[family].version; - *ret = m; - m = NULL; + *ret = TAKE_PTR(m); return 0; } diff --git a/src/libsystemd/sd-netlink/local-addresses.c b/src/libsystemd/sd-netlink/local-addresses.c index 81e55b6d9f..5467ba432f 100644 --- a/src/libsystemd/sd-netlink/local-addresses.c +++ b/src/libsystemd/sd-netlink/local-addresses.c @@ -1,23 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2008-2011 Lennart Poettering - Copyright 2014 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-netlink.h" @@ -158,8 +139,7 @@ int local_addresses(sd_netlink *context, int ifindex, int af, struct local_addre qsort_safe(list, n_list, sizeof(struct local_address), address_compare); - *ret = list; - list = NULL; + *ret = TAKE_PTR(list); return (int) n_list; } @@ -271,8 +251,7 @@ int local_gateways(sd_netlink *context, int ifindex, int af, struct local_addres if (n_list > 0) qsort(list, n_list, sizeof(struct local_address), address_compare); - *ret = list; - list = NULL; + *ret = TAKE_PTR(list); return (int) n_list; } diff --git a/src/libsystemd/sd-netlink/local-addresses.h b/src/libsystemd/sd-netlink/local-addresses.h index f722242821..4fc3477e47 100644 --- a/src/libsystemd/sd-netlink/local-addresses.h +++ b/src/libsystemd/sd-netlink/local-addresses.h @@ -2,25 +2,8 @@ #pragma once /*** - This file is part of systemd. - - Copyright 2008-2011 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ - #include "sd-netlink.h" #include "in-addr-util.h" diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index dc553d708c..dd4fa9d2af 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <linux/netlink.h> diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index af3d13edcd..23907c8224 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <netinet/in.h> #include <stdbool.h> @@ -98,8 +80,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; - *ret = m; - m = NULL; + *ret = TAKE_PTR(m); return 0; } @@ -312,7 +293,6 @@ int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uin return 0; } - int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data) { int r; @@ -803,8 +783,7 @@ static int netlink_container_parse(sd_netlink_message *m, attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER; } - container->attributes = attributes; - attributes = NULL; + container->attributes = TAKE_PTR(attributes); container->n_attributes = count; return 0; diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 3474ad9ddb..f103cbedea 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <netinet/in.h> #include <stdbool.h> @@ -433,8 +415,7 @@ int socket_read_message(sd_netlink *rtnl) { /* push the message onto the multi-part message stack */ if (first) m->next = first; - first = m; - m = NULL; + first = TAKE_PTR(m); } if (len > 0) @@ -449,8 +430,7 @@ int socket_read_message(sd_netlink *rtnl) { if (r < 0) return r; - rtnl->rqueue[rtnl->rqueue_size++] = first; - first = NULL; + rtnl->rqueue[rtnl->rqueue_size++] = TAKE_PTR(first); if (multi_part && (i < rtnl->rqueue_partial_size)) { /* remove the message form the partial read queue */ @@ -464,15 +444,14 @@ int socket_read_message(sd_netlink *rtnl) { /* we only got a partial multi-part message, push it on the partial read queue */ if (i < rtnl->rqueue_partial_size) - rtnl->rqueue_partial[i] = first; + rtnl->rqueue_partial[i] = TAKE_PTR(first); else { r = rtnl_rqueue_partial_make_room(rtnl); if (r < 0) return r; - rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = first; + rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = TAKE_PTR(first); } - first = NULL; return 0; } diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 0ee7d6f0dc..c93fe9cb4c 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <netinet/in.h> #include <stdint.h> @@ -313,6 +295,11 @@ static const NLType rtnl_link_info_data_geneve_types[] = { [IFLA_GENEVE_LABEL] = { .type = NETLINK_TYPE_U32 }, }; +static const NLType rtnl_link_info_data_can_types[] = { + [IFLA_CAN_BITTIMING] = { .size = sizeof(struct can_bittiming) }, + [IFLA_CAN_RESTART_MS] = { .type = NETLINK_TYPE_U32 }, +}; + /* these strings must match the .kind entries in the kernel */ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_BOND] = "bond", @@ -338,6 +325,8 @@ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve", [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan", [NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard", + [NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim", + [NL_UNION_LINK_INFO_DATA_CAN] = "can", }; DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); @@ -383,6 +372,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = { .types = rtnl_link_info_data_geneve_types }, [NL_UNION_LINK_INFO_DATA_VXCAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types), .types = rtnl_link_info_data_vxcan_types }, + [NL_UNION_LINK_INFO_DATA_CAN] = { .count = ELEMENTSOF(rtnl_link_info_data_can_types), + .types = rtnl_link_info_data_can_types }, }; static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { @@ -582,7 +573,11 @@ static const NLType rtnl_route_types[] = { RTA_NEWDST, */ [RTA_PREF] = { .type = NETLINK_TYPE_U8 }, - +/* + RTA_ENCAP_TYPE, + RTA_ENCAP, + */ + [RTA_EXPIRES] = { .type = NETLINK_TYPE_U32 }, }; static const NLTypeSystem rtnl_route_type_system = { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index ea7f8d5e6c..d411ffa6c2 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "macro.h" @@ -95,6 +77,8 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_GENEVE, NL_UNION_LINK_INFO_DATA_VXCAN, NL_UNION_LINK_INFO_DATA_WIREGUARD, + NL_UNION_LINK_INFO_DATA_NETDEVSIM, + NL_UNION_LINK_INFO_DATA_CAN, _NL_UNION_LINK_INFO_DATA_MAX, _NL_UNION_LINK_INFO_DATA_INVALID = -1 } NLUnionLinkInfoData; diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 7680b30e70..3928dfbabf 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-netlink.h" @@ -53,7 +35,7 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { } int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, - const struct ether_addr *mac, unsigned mtu) { + const struct ether_addr *mac, uint32_t mtu) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; int r; @@ -85,7 +67,7 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, return r; } - if (mtu > 0) { + if (mtu != 0) { r = sd_netlink_message_append_u32(message, IFLA_MTU, mtu); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index 795e4dc15c..7c35a2cfa7 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-netlink.h" @@ -53,7 +35,7 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) { } int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name); -int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu); +int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu); int rtnl_log_parse_error(int r); int rtnl_log_create_error(int r); diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c index 24345c4298..4416e1720c 100644 --- a/src/libsystemd/sd-netlink/rtnl-message.c +++ b/src/libsystemd/sd-netlink/rtnl-message.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <netinet/in.h> #include <linux/if_addrlabel.h> diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 116e287bb6..a177f220ab 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <poll.h> #include <sys/socket.h> @@ -62,8 +44,7 @@ static int sd_netlink_new(sd_netlink **ret) { * responses with notifications from the kernel */ rtnl->serial = 1; - *ret = rtnl; - rtnl = NULL; + *ret = TAKE_PTR(rtnl); return 0; } @@ -90,8 +71,7 @@ int sd_netlink_new_from_netlink(sd_netlink **ret, int fd) { rtnl->fd = fd; - *ret = rtnl; - rtnl = NULL; + *ret = TAKE_PTR(rtnl); return 0; } @@ -133,8 +113,7 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) { return r; } - *ret = rtnl; - rtnl = NULL; + *ret = TAKE_PTR(rtnl); return 0; } @@ -425,8 +404,7 @@ static int process_running(sd_netlink *rtnl, sd_netlink_message **ret) { } if (ret) { - *ret = m; - m = NULL; + *ret = TAKE_PTR(m); return 1; } @@ -669,10 +647,8 @@ int sd_netlink_call(sd_netlink *rtnl, return 0; } - if (ret) { - *ret = incoming; - incoming = NULL; - } + if (ret) + *ret = TAKE_PTR(incoming); return 1; } diff --git a/src/libsystemd/sd-netlink/test-local-addresses.c b/src/libsystemd/sd-netlink/test-local-addresses.c index bf11042221..921ce289d4 100644 --- a/src/libsystemd/sd-netlink/test-local-addresses.c +++ b/src/libsystemd/sd-netlink/test-local-addresses.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "af-list.h" diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 9ccc8ea607..03773fb936 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <net/if.h> #include <netinet/ether.h> @@ -53,7 +35,7 @@ static void test_link_configure(sd_netlink *rtnl, int ifindex) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; const char *mac = "98:fe:94:3f:c6:18", *name = "test"; char buffer[ETHER_ADDR_TO_STRING_MAX]; - unsigned int mtu = 1450, mtu_out; + uint32_t mtu = 1450, mtu_out; const char *name_out; struct ether_addr mac_out; @@ -79,7 +61,7 @@ static void test_link_configure(sd_netlink *rtnl, int ifindex) { static void test_link_get(sd_netlink *rtnl, int ifindex) { sd_netlink_message *m; sd_netlink_message *r; - unsigned int mtu = 1500; + uint32_t mtu = 1500; const char *str_data; uint8_t u8_data; uint32_t u32_data; @@ -120,7 +102,6 @@ static void test_link_get(sd_netlink *rtnl, int ifindex) { assert_se((r = sd_netlink_message_unref(r)) == NULL); } - static void test_address_get(sd_netlink *rtnl, int ifindex) { sd_netlink_message *m; sd_netlink_message *r; diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c index 0957d593e0..256d4a27a5 100644 --- a/src/libsystemd/sd-network/network-util.c +++ b/src/libsystemd/sd-network/network-util.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "alloc-util.h" diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h index 9c6b3fc0f0..62260d09dd 100644 --- a/src/libsystemd/sd-network/network-util.h +++ b/src/libsystemd/sd-network/network-util.h @@ -1,24 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2014 Thomas Hindø Paabøl Andersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include "sd-network.h" diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 8f4814019e..3b8ce935b0 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -1,23 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering - Copyright 2014 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <errno.h> #include <poll.h> @@ -43,7 +24,7 @@ _public_ int sd_network_get_operational_state(char **state) { assert_return(state, -EINVAL); - r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL); + r = parse_env_file(NULL, "/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -51,8 +32,7 @@ _public_ int sd_network_get_operational_state(char **state) { if (isempty(s)) return -ENODATA; - *state = s; - s = NULL; + *state = TAKE_PTR(s); return 0; } @@ -64,7 +44,7 @@ static int network_get_strv(const char *key, char ***ret) { assert_return(ret, -EINVAL); - r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL); + r = parse_env_file(NULL, "/run/systemd/netif/state", NEWLINE, key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -79,10 +59,9 @@ static int network_get_strv(const char *key, char ***ret) { return -ENOMEM; strv_uniq(a); - r = strv_length(a); + r = (int) strv_length(a); - *ret = a; - a = NULL; + *ret = TAKE_PTR(a); return r; } @@ -113,7 +92,7 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) { xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(path, NEWLINE, field, &s, NULL); + r = parse_env_file(NULL, path, NEWLINE, field, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -121,8 +100,7 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) { if (isempty(s)) return -ENODATA; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 0; } @@ -137,7 +115,7 @@ static int network_link_get_strv(int ifindex, const char *key, char ***ret) { assert_return(ret, -EINVAL); xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(path, NEWLINE, key, &s, NULL); + r = parse_env_file(NULL, path, NEWLINE, key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -152,10 +130,9 @@ static int network_link_get_strv(int ifindex, const char *key, char ***ret) { return -ENOMEM; strv_uniq(a); - r = strv_length(a); + r = (int) strv_length(a); - *ret = a; - a = NULL; + *ret = TAKE_PTR(a); return r; } @@ -195,6 +172,10 @@ _public_ int sd_network_link_get_mdns(int ifindex, char **mdns) { return network_link_get_string(ifindex, "MDNS", mdns); } +_public_ int sd_network_link_get_dns_over_tls(int ifindex, char **dns_over_tls) { + return network_link_get_string(ifindex, "DNS_OVER_TLS", dns_over_tls); +} + _public_ int sd_network_link_get_dnssec(int ifindex, char **dnssec) { return network_link_get_string(ifindex, "DNSSEC", dnssec); } @@ -235,7 +216,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) { assert_return(ret, -EINVAL); xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(path, NEWLINE, key, &s, NULL); + r = parse_env_file(NULL, path, NEWLINE, key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -263,8 +244,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) { if (ifis) ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice */ - *ret = ifis; - ifis = NULL; + *ret = TAKE_PTR(ifis); return c; } diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c index 419c763668..2845f91e1b 100644 --- a/src/libsystemd/sd-path/sd-path.c +++ b/src/libsystemd/sd-path/sd-path.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-path.h" @@ -348,6 +332,7 @@ _public_ int sd_path_home(uint64_t type, const char *suffix, char **path) { if (IN_SET(type, SD_PATH_SEARCH_BINARIES, + SD_PATH_SEARCH_BINARIES_DEFAULT, SD_PATH_SEARCH_LIBRARY_PRIVATE, SD_PATH_SEARCH_LIBRARY_ARCH, SD_PATH_SEARCH_SHARED, @@ -566,19 +551,31 @@ static int get_search(uint64_t type, char ***list) { false, "/etc", NULL); - } + + case SD_PATH_SEARCH_BINARIES_DEFAULT: { + char **t; + + t = strv_split_nulstr(DEFAULT_PATH_NULSTR); + if (!t) + return -ENOMEM; + + *list = t; + return 0; + }} return -EOPNOTSUPP; } _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { - char **l, **i, **j, **n; + char **i, **j; + _cleanup_strv_free_ char **l = NULL, **n = NULL; int r; assert_return(paths, -EINVAL); if (!IN_SET(type, SD_PATH_SEARCH_BINARIES, + SD_PATH_SEARCH_BINARIES_DEFAULT, SD_PATH_SEARCH_LIBRARY_PRIVATE, SD_PATH_SEARCH_LIBRARY_ARCH, SD_PATH_SEARCH_SHARED, @@ -601,7 +598,7 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { l[0] = p; l[1] = NULL; - *paths = l; + *paths = TAKE_PTR(l); return 0; } @@ -610,15 +607,13 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { return r; if (!suffix) { - *paths = l; + *paths = TAKE_PTR(l); return 0; } n = new(char*, strv_length(l)+1); - if (!n) { - strv_free(l); + if (!n) return -ENOMEM; - } j = n; STRV_FOREACH(i, l) { @@ -628,16 +623,13 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { else *j = strjoin(*i, "/", suffix); - if (!*j) { - strv_free(l); - strv_free(n); + if (!*j) return -ENOMEM; - } j++; } *j = NULL; - *paths = n; + *paths = TAKE_PTR(n); return 0; } diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c index 1c68a96fec..a189f140f8 100644 --- a/src/libsystemd/sd-resolve/sd-resolve.c +++ b/src/libsystemd/sd-resolve/sd-resolve.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2005-2008 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include <errno.h> @@ -181,8 +165,15 @@ static void resolve_query_disconnect(sd_resolve_query *q); #define RESOLVE_DONT_DESTROY(resolve) \ _cleanup_(sd_resolve_unrefp) _unused_ sd_resolve *_dont_destroy_##resolve = sd_resolve_ref(resolve) -static int send_died(int out_fd) { +static void query_assign_errno(sd_resolve_query *q, int ret, int error, int h_error) { + assert(q); + q->ret = ret; + q->_errno = abs(error); + q->_h_errno = h_error; +} + +static int send_died(int out_fd) { RHeader rh = { .type = RESPONSE_DIED, .length = sizeof(RHeader), @@ -244,12 +235,12 @@ static int send_addrinfo_reply( ._h_errno = _h_errno, }; - struct msghdr mh = {}; - struct iovec iov[2]; union { AddrInfoSerialization ais; uint8_t space[BUFSIZE]; } buffer; + struct iovec iov[2]; + struct msghdr mh; assert(out_fd >= 0); @@ -272,8 +263,7 @@ static int send_addrinfo_reply( iov[0] = (struct iovec) { .iov_base = &resp, .iov_len = sizeof(AddrInfoResponse) }; iov[1] = (struct iovec) { .iov_base = &buffer, .iov_len = resp.header.length - sizeof(AddrInfoResponse) }; - mh.msg_iov = iov; - mh.msg_iovlen = ELEMENTSOF(iov); + mh = (struct msghdr) { .msg_iov = iov, .msg_iovlen = ELEMENTSOF(iov) }; if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0) return -errno; @@ -298,8 +288,8 @@ static int send_nameinfo_reply( ._h_errno = _h_errno, }; - struct msghdr mh = {}; struct iovec iov[3]; + struct msghdr mh; size_t hl, sl; assert(out_fd >= 0); @@ -315,8 +305,7 @@ static int send_nameinfo_reply( iov[1] = (struct iovec) { .iov_base = (void*) host, .iov_len = hl }; iov[2] = (struct iovec) { .iov_base = (void*) serv, .iov_len = sl }; - mh.msg_iov = iov; - mh.msg_iovlen = ELEMENTSOF(iov); + mh = (struct msghdr) { .msg_iov = iov, .msg_iovlen = ELEMENTSOF(iov) }; if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0) return -errno; @@ -332,32 +321,33 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) { req = &packet->rheader; - assert(length >= sizeof(RHeader)); - assert(length == req->length); + assert_return(length >= sizeof(RHeader), -EIO); + assert_return(length == req->length, -EIO); switch (req->type) { case REQUEST_ADDRINFO: { const AddrInfoRequest *ai_req = &packet->addrinfo_request; - struct addrinfo hints = {}, *result = NULL; + struct addrinfo hints, *result = NULL; const char *node, *service; int ret; - assert(length >= sizeof(AddrInfoRequest)); - assert(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len); + assert_return(length >= sizeof(AddrInfoRequest), -EBADMSG); + assert_return(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len, -EBADMSG); - hints.ai_flags = ai_req->ai_flags; - hints.ai_family = ai_req->ai_family; - hints.ai_socktype = ai_req->ai_socktype; - hints.ai_protocol = ai_req->ai_protocol; + hints = (struct addrinfo) { + .ai_flags = ai_req->ai_flags, + .ai_family = ai_req->ai_family, + .ai_socktype = ai_req->ai_socktype, + .ai_protocol = ai_req->ai_protocol, + }; node = ai_req->node_len ? (const char*) ai_req + sizeof(AddrInfoRequest) : NULL; service = ai_req->service_len ? (const char*) ai_req + sizeof(AddrInfoRequest) + ai_req->node_len : NULL; - ret = getaddrinfo( - node, service, - ai_req->hints_valid ? &hints : NULL, - &result); + ret = getaddrinfo(node, service, + ai_req->hints_valid ? &hints : NULL, + &result); /* send_addrinfo_reply() frees result */ return send_addrinfo_reply(out_fd, req->id, ret, result, errno, h_errno); @@ -369,21 +359,21 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) { union sockaddr_union sa; int ret; - assert(length >= sizeof(NameInfoRequest)); - assert(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len); - assert(sizeof(sa) >= ni_req->sockaddr_len); + assert_return(length >= sizeof(NameInfoRequest), -EBADMSG); + assert_return(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len, -EBADMSG); + assert_return(ni_req->sockaddr_len <= sizeof(sa), -EBADMSG); memcpy(&sa, (const uint8_t *) ni_req + sizeof(NameInfoRequest), ni_req->sockaddr_len); ret = getnameinfo(&sa.sa, ni_req->sockaddr_len, - ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0, - ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0, - ni_req->flags); + ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0, + ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0, + ni_req->flags); return send_nameinfo_reply(out_fd, req->id, ret, - ret == 0 && ni_req->gethost ? hostbuf : NULL, - ret == 0 && ni_req->getserv ? servbuf : NULL, - errno, h_errno); + ret == 0 && ni_req->gethost ? hostbuf : NULL, + ret == 0 && ni_req->getserv ? servbuf : NULL, + errno, h_errno); } case REQUEST_TERMINATE: @@ -410,7 +400,7 @@ static void* thread_worker(void *p) { } buf; ssize_t length; - length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof(buf), 0); + length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0); if (length < 0) { if (errno == EINTR) continue; @@ -420,9 +410,6 @@ static void* thread_worker(void *p) { if (length == 0) break; - if (resolve->dead) - break; - if (handle_request(resolve->fds[RESPONSE_SEND_FD], &buf.packet, (size_t) length) < 0) break; } @@ -450,7 +437,6 @@ static int start_threads(sd_resolve *resolve, unsigned extra) { n = CLAMP(n, WORKERS_MIN, WORKERS_MAX); while (resolve->n_valid_workers < n) { - r = pthread_create(&resolve->workers[resolve->n_valid_workers], NULL, thread_worker, resolve); if (r > 0) { r = -r; @@ -480,8 +466,8 @@ static bool resolve_pid_changed(sd_resolve *r) { } _public_ int sd_resolve_new(sd_resolve **ret) { - sd_resolve *resolve = NULL; - int i, r; + _cleanup_(sd_resolve_unrefp) sd_resolve *resolve = NULL; + int i; assert_return(ret, -EINVAL); @@ -495,17 +481,11 @@ _public_ int sd_resolve_new(sd_resolve **ret) { for (i = 0; i < _FD_MAX; i++) resolve->fds[i] = -1; - r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD); - if (r < 0) { - r = -errno; - goto fail; - } + if (socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD) < 0) + return -errno; - r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + RESPONSE_RECV_FD); - if (r < 0) { - r = -errno; - goto fail; - } + if (socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + RESPONSE_RECV_FD) < 0) + return -errno; for (i = 0; i < _FD_MAX; i++) resolve->fds[i] = fd_move_above_stdio(resolve->fds[i]); @@ -517,12 +497,8 @@ _public_ int sd_resolve_new(sd_resolve **ret) { (void) fd_nonblock(resolve->fds[RESPONSE_RECV_FD], true); - *ret = resolve; + *ret = TAKE_PTR(resolve); return 0; - -fail: - sd_resolve_unref(resolve); - return r; } _public_ int sd_resolve_default(sd_resolve **ret) { @@ -591,7 +567,7 @@ static void resolve_free(sd_resolve *resolve) { RHeader req = { .type = REQUEST_TERMINATE, - .length = sizeof(req) + .length = sizeof req, }; /* Send one termination packet for each worker */ @@ -619,7 +595,6 @@ _public_ sd_resolve* sd_resolve_ref(sd_resolve *resolve) { } _public_ sd_resolve* sd_resolve_unref(sd_resolve *resolve) { - if (!resolve) return NULL; @@ -765,11 +740,11 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len int r; assert(resolve); + assert(packet); resp = &packet->rheader; - assert(resp); - assert(length >= sizeof(RHeader)); - assert(length == resp->length); + assert_return(length >= sizeof(RHeader), -EIO); + assert_return(length == resp->length, -EIO); if (resp->type == RESPONSE_DIED) { resolve->dead = true; @@ -791,12 +766,10 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len size_t l; struct addrinfo *prev = NULL; - assert(length >= sizeof(AddrInfoResponse)); - assert(q->type == REQUEST_ADDRINFO); + assert_return(length >= sizeof(AddrInfoResponse), -EBADMSG); + assert_return(q->type == REQUEST_ADDRINFO, -EBADMSG); - q->ret = ai_resp->ret; - q->_errno = ai_resp->_errno; - q->_h_errno = ai_resp->_h_errno; + query_assign_errno(q, ai_resp->ret, ai_resp->_errno, ai_resp->_h_errno); l = length - sizeof(AddrInfoResponse); p = (const uint8_t*) resp + sizeof(AddrInfoResponse); @@ -806,9 +779,7 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len r = unserialize_addrinfo(&p, &l, &ai); if (r < 0) { - q->ret = EAI_SYSTEM; - q->_errno = -r; - q->_h_errno = 0; + query_assign_errno(q, EAI_SYSTEM, r, 0); freeaddrinfo(q->addrinfo); q->addrinfo = NULL; break; @@ -828,39 +799,28 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len case RESPONSE_NAMEINFO: { const NameInfoResponse *ni_resp = &packet->nameinfo_response; - assert(length >= sizeof(NameInfoResponse)); - assert(q->type == REQUEST_NAMEINFO); + assert_return(length >= sizeof(NameInfoResponse), -EBADMSG); + assert_return(q->type == REQUEST_NAMEINFO, -EBADMSG); if (ni_resp->hostlen > DNS_HOSTNAME_MAX || ni_resp->servlen > DNS_HOSTNAME_MAX || - sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length + 2) { - q->ret = EAI_SYSTEM; - q->_errno = -EIO; - q->_h_errno = 0; - - } else { - q->ret = ni_resp->ret; - q->_errno = ni_resp->_errno; - q->_h_errno = ni_resp->_h_errno; + sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length) + query_assign_errno(q, EAI_SYSTEM, EIO, 0); + else { + query_assign_errno(q, ni_resp->ret, ni_resp->_errno, ni_resp->_h_errno); if (ni_resp->hostlen > 0) { q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse), ni_resp->hostlen-1); - if (!q->host) { - q->ret = EAI_MEMORY; - q->_errno = ENOMEM; - q->_h_errno = 0; - } + if (!q->host) + query_assign_errno(q, EAI_MEMORY, ENOMEM, 0); } if (ni_resp->servlen > 0) { q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen, ni_resp->servlen-1); - if (!q->serv) { - q->ret = EAI_MEMORY; - q->_errno = ENOMEM; - q->_h_errno = 0; - } + if (!q->serv) + query_assign_errno(q, EAI_MEMORY, ENOMEM, 0); } } @@ -888,7 +848,7 @@ _public_ int sd_resolve_process(sd_resolve *resolve) { /* We don't allow recursively invoking sd_resolve_process(). */ assert_return(!resolve->current, -EBUSY); - l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof(buf), 0); + l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0); if (l < 0) { if (errno == EAGAIN) return 0; @@ -969,11 +929,12 @@ _public_ int sd_resolve_getaddrinfo( const struct addrinfo *hints, sd_resolve_getaddrinfo_handler_t callback, void *userdata) { - AddrInfoRequest req = {}; - struct msghdr mh = {}; + _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q = NULL; + AddrInfoRequest req; struct iovec iov[3]; - sd_resolve_query *q; + struct msghdr mh = {}; int r; + size_t node_len, service_len; assert_return(resolve, -EINVAL); assert_return(node || service, -EINVAL); @@ -988,20 +949,23 @@ _public_ int sd_resolve_getaddrinfo( q->getaddrinfo_handler = callback; q->userdata = userdata; - req.node_len = node ? strlen(node)+1 : 0; - req.service_len = service ? strlen(service)+1 : 0; + node_len = node ? strlen(node) + 1 : 0; + service_len = service ? strlen(service) + 1 : 0; - req.header.id = q->id; - req.header.type = REQUEST_ADDRINFO; - req.header.length = sizeof(AddrInfoRequest) + req.node_len + req.service_len; + req = (AddrInfoRequest) { + .node_len = node_len, + .service_len = service_len, - if (hints) { - req.hints_valid = true; - req.ai_flags = hints->ai_flags; - req.ai_family = hints->ai_family; - req.ai_socktype = hints->ai_socktype; - req.ai_protocol = hints->ai_protocol; - } + .header.id = q->id, + .header.type = REQUEST_ADDRINFO, + .header.length = sizeof(AddrInfoRequest) + node_len + service_len, + + .hints_valid = hints, + .ai_flags = hints ? hints->ai_flags : 0, + .ai_family = hints ? hints->ai_family : 0, + .ai_socktype = hints ? hints->ai_socktype : 0, + .ai_protocol = hints ? hints->ai_protocol : 0, + }; iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(AddrInfoRequest) }; if (node) @@ -1010,15 +974,14 @@ _public_ int sd_resolve_getaddrinfo( iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = (void*) service, .iov_len = req.service_len }; mh.msg_iov = iov; - if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) { - sd_resolve_query_unref(q); + if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) return -errno; - } resolve->n_outstanding++; if (_q) *_q = q; + TAKE_PTR(q); return 0; } @@ -1043,10 +1006,10 @@ _public_ int sd_resolve_getnameinfo( sd_resolve_getnameinfo_handler_t callback, void *userdata) { - NameInfoRequest req = {}; - struct msghdr mh = {}; + _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q = NULL; + NameInfoRequest req; struct iovec iov[2]; - sd_resolve_query *q; + struct msghdr mh; int r; assert_return(resolve, -EINVAL); @@ -1065,31 +1028,31 @@ _public_ int sd_resolve_getnameinfo( q->getnameinfo_handler = callback; q->userdata = userdata; - req.header.id = q->id; - req.header.type = REQUEST_NAMEINFO; - req.header.length = sizeof(NameInfoRequest) + salen; + req = (NameInfoRequest) { + .header.id = q->id, + .header.type = REQUEST_NAMEINFO, + .header.length = sizeof(NameInfoRequest) + salen, - req.flags = flags; - req.sockaddr_len = salen; - req.gethost = !!(get & SD_RESOLVE_GET_HOST); - req.getserv = !!(get & SD_RESOLVE_GET_SERVICE); + .flags = flags, + .sockaddr_len = salen, + .gethost = !!(get & SD_RESOLVE_GET_HOST), + .getserv = !!(get & SD_RESOLVE_GET_SERVICE), + }; iov[0] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(NameInfoRequest) }; iov[1] = (struct iovec) { .iov_base = (void*) sa, .iov_len = salen }; - mh.msg_iov = iov; - mh.msg_iovlen = 2; + mh = (struct msghdr) { .msg_iov = iov, .msg_iovlen = ELEMENTSOF(iov) }; - if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) { - sd_resolve_query_unref(q); + if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) return -errno; - } - - resolve->n_outstanding++; if (_q) *_q = q; + resolve->n_outstanding++; + TAKE_PTR(q); + return 0; } @@ -1100,7 +1063,7 @@ static int getnameinfo_done(sd_resolve_query *q) { assert(q->getnameinfo_handler); errno = q->_errno; - h_errno= q->_h_errno; + h_errno = q->_h_errno; return q->getnameinfo_handler(q, q->ret, q->host, q->serv, q->userdata); } diff --git a/src/libsystemd/sd-resolve/test-resolve.c b/src/libsystemd/sd-resolve/test-resolve.c index b728dee9dd..880d224a38 100644 --- a/src/libsystemd/sd-resolve/test-resolve.c +++ b/src/libsystemd/sd-resolve/test-resolve.c @@ -1,22 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2005-2008 Lennart Poettering - Copyright 2014 Daniel Buch - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. + Copyright © 2014 Daniel Buch ***/ #include <arpa/inet.h> @@ -116,7 +100,6 @@ int main(int argc, char *argv[]) { log_notice_errno(r, "sd_resolve_wait() timed out, but that's OK"); exit(EXIT_SUCCESS); - break; } if (r < 0) { log_error_errno(r, "sd_resolve_wait(): %m"); diff --git a/src/libsystemd/sd-utf8/sd-utf8.c b/src/libsystemd/sd-utf8/sd-utf8.c index b8db7eb093..79909c9af1 100644 --- a/src/libsystemd/sd-utf8/sd-utf8.c +++ b/src/libsystemd/sd-utf8/sd-utf8.c @@ -1,21 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ #include "sd-utf8.h" |