| File: | build-scan/../src/libsystemd/sd-device/device-private.c |
| Warning: | line 566, column 13 3rd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
| 2 | ||||
| 3 | #include <ctype.h> | |||
| 4 | #include <net/if.h> | |||
| 5 | #include <sys/types.h> | |||
| 6 | ||||
| 7 | #include "sd-device.h" | |||
| 8 | ||||
| 9 | #include "alloc-util.h" | |||
| 10 | #include "device-internal.h" | |||
| 11 | #include "device-private.h" | |||
| 12 | #include "device-util.h" | |||
| 13 | #include "fd-util.h" | |||
| 14 | #include "fileio.h" | |||
| 15 | #include "fs-util.h" | |||
| 16 | #include "hashmap.h" | |||
| 17 | #include "macro.h" | |||
| 18 | #include "mkdir.h" | |||
| 19 | #include "parse-util.h" | |||
| 20 | #include "path-util.h" | |||
| 21 | #include "refcnt.h" | |||
| 22 | #include "set.h" | |||
| 23 | #include "string-table.h" | |||
| 24 | #include "string-util.h" | |||
| 25 | #include "strv.h" | |||
| 26 | #include "strxcpyx.h" | |||
| 27 | #include "user-util.h" | |||
| 28 | #include "util.h" | |||
| 29 | ||||
| 30 | int device_add_property(sd_device *device, const char *key, const char *value) { | |||
| 31 | int r; | |||
| 32 | ||||
| 33 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 33, __PRETTY_FUNCTION__); } while (0); | |||
| 34 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd/sd-device/device-private.c" , 34, __PRETTY_FUNCTION__); } while (0); | |||
| 35 | ||||
| 36 | r = device_add_property_aux(device, key, value, false0); | |||
| 37 | if (r < 0) | |||
| 38 | return r; | |||
| 39 | ||||
| 40 | if (key[0] != '.') { | |||
| 41 | r = device_add_property_aux(device, key, value, true1); | |||
| 42 | if (r < 0) | |||
| 43 | return r; | |||
| 44 | } | |||
| 45 | ||||
| 46 | return 0; | |||
| 47 | } | |||
| 48 | ||||
| 49 | static int device_add_property_internal_from_string(sd_device *device, const char *str) { | |||
| 50 | _cleanup_free___attribute__((cleanup(freep))) char *key = NULL((void*)0); | |||
| 51 | char *value; | |||
| 52 | ||||
| 53 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 53, __PRETTY_FUNCTION__); } while (0); | |||
| 54 | assert(str)do { if ((__builtin_expect(!!(!(str)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("str"), "../src/libsystemd/sd-device/device-private.c" , 54, __PRETTY_FUNCTION__); } while (0); | |||
| 55 | ||||
| 56 | key = strdup(str); | |||
| 57 | if (!key) | |||
| 58 | return -ENOMEM12; | |||
| 59 | ||||
| 60 | value = strchr(key, '='); | |||
| 61 | if (!value) | |||
| 62 | return -EINVAL22; | |||
| 63 | ||||
| 64 | *value = '\0'; | |||
| 65 | ||||
| 66 | if (isempty(++value)) | |||
| 67 | value = NULL((void*)0); | |||
| 68 | ||||
| 69 | return device_add_property_internal(device, key, value); | |||
| 70 | } | |||
| 71 | ||||
| 72 | static int handle_db_line(sd_device *device, char key, const char *value) { | |||
| 73 | char *path; | |||
| 74 | int r; | |||
| 75 | ||||
| 76 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 76, __PRETTY_FUNCTION__); } while (0); | |||
| 77 | assert(value)do { if ((__builtin_expect(!!(!(value)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("value"), "../src/libsystemd/sd-device/device-private.c" , 77, __PRETTY_FUNCTION__); } while (0); | |||
| 78 | ||||
| 79 | switch (key) { | |||
| 80 | case 'S': | |||
| 81 | path = strjoina("/dev/", value)({ const char *_appendees_[] = { "/dev/", value }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 82 | r = device_add_devlink(device, path); | |||
| 83 | if (r < 0) | |||
| 84 | return r; | |||
| 85 | ||||
| 86 | break; | |||
| 87 | case 'L': | |||
| 88 | r = safe_atoi(value, &device->devlink_priority); | |||
| 89 | if (r < 0) | |||
| 90 | return r; | |||
| 91 | ||||
| 92 | break; | |||
| 93 | case 'E': | |||
| 94 | r = device_add_property_internal_from_string(device, value); | |||
| 95 | if (r < 0) | |||
| 96 | return r; | |||
| 97 | ||||
| 98 | break; | |||
| 99 | case 'G': | |||
| 100 | r = device_add_tag(device, value); | |||
| 101 | if (r < 0) | |||
| 102 | return r; | |||
| 103 | ||||
| 104 | break; | |||
| 105 | case 'W': | |||
| 106 | r = safe_atoi(value, &device->watch_handle); | |||
| 107 | if (r < 0) | |||
| 108 | return r; | |||
| 109 | ||||
| 110 | break; | |||
| 111 | case 'I': | |||
| 112 | r = device_set_usec_initialized(device, value); | |||
| 113 | if (r < 0) | |||
| 114 | return r; | |||
| 115 | ||||
| 116 | break; | |||
| 117 | default: | |||
| 118 | log_debug("device db: unknown key '%c'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 118, __func__ , "device db: unknown key '%c'", key) : -abs(_e); }); | |||
| 119 | } | |||
| 120 | ||||
| 121 | return 0; | |||
| 122 | } | |||
| 123 | ||||
| 124 | void device_set_devlink_priority(sd_device *device, int priority) { | |||
| 125 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 125, __PRETTY_FUNCTION__); } while (0); | |||
| 126 | ||||
| 127 | device->devlink_priority = priority; | |||
| 128 | } | |||
| 129 | ||||
| 130 | void device_set_is_initialized(sd_device *device) { | |||
| 131 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 131, __PRETTY_FUNCTION__); } while (0); | |||
| 132 | ||||
| 133 | device->is_initialized = true1; | |||
| 134 | } | |||
| 135 | ||||
| 136 | int device_ensure_usec_initialized(sd_device *device, sd_device *device_old) { | |||
| 137 | char num[DECIMAL_STR_MAX(usec_t)(2+(sizeof(usec_t) <= 1 ? 3 : sizeof(usec_t) <= 2 ? 5 : sizeof(usec_t) <= 4 ? 10 : sizeof(usec_t) <= 8 ? 20 : sizeof (int[-2*(sizeof(usec_t) > 8)])))]; | |||
| 138 | usec_t usec_initialized; | |||
| 139 | int r; | |||
| 140 | ||||
| 141 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 141, __PRETTY_FUNCTION__); } while (0); | |||
| 142 | ||||
| 143 | if (device_old && device_old->usec_initialized > 0) | |||
| 144 | usec_initialized = device_old->usec_initialized; | |||
| 145 | else | |||
| 146 | usec_initialized = now(CLOCK_MONOTONIC1); | |||
| 147 | ||||
| 148 | r = snprintf(num, sizeof(num), USEC_FMT"%" "l" "u", usec_initialized); | |||
| 149 | if (r < 0) | |||
| 150 | return -errno(*__errno_location ()); | |||
| 151 | ||||
| 152 | r = device_set_usec_initialized(device, num); | |||
| 153 | if (r < 0) | |||
| 154 | return r; | |||
| 155 | ||||
| 156 | return 0; | |||
| 157 | } | |||
| 158 | ||||
| 159 | static int device_read_db(sd_device *device) { | |||
| 160 | _cleanup_free___attribute__((cleanup(freep))) char *db = NULL((void*)0); | |||
| 161 | char *path; | |||
| 162 | const char *id, *value; | |||
| 163 | char key; | |||
| 164 | size_t db_len; | |||
| 165 | unsigned i; | |||
| 166 | int r; | |||
| 167 | ||||
| 168 | enum { | |||
| 169 | PRE_KEY, | |||
| 170 | KEY, | |||
| 171 | PRE_VALUE, | |||
| 172 | VALUE, | |||
| 173 | INVALID_LINE, | |||
| 174 | } state = PRE_KEY; | |||
| 175 | ||||
| 176 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 176, __PRETTY_FUNCTION__); } while (0); | |||
| 177 | ||||
| 178 | if (device->db_loaded || device->sealed) | |||
| 179 | return 0; | |||
| 180 | ||||
| 181 | r = device_get_id_filename(device, &id); | |||
| 182 | if (r < 0) | |||
| 183 | return r; | |||
| 184 | ||||
| 185 | path = strjoina("/run/udev/data/", id)({ const char *_appendees_[] = { "/run/udev/data/", id }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 186 | ||||
| 187 | r = read_full_file(path, &db, &db_len); | |||
| 188 | if (r < 0) { | |||
| 189 | if (r == -ENOENT2) | |||
| 190 | return 0; | |||
| 191 | else | |||
| 192 | return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 192, __func__ , "sd-device: failed to read db '%s': %m", path) : -abs(_e); } ); | |||
| 193 | } | |||
| 194 | ||||
| 195 | /* devices with a database entry are initialized */ | |||
| 196 | device_set_is_initialized(device); | |||
| 197 | ||||
| 198 | for (i = 0; i < db_len; i++) { | |||
| 199 | switch (state) { | |||
| 200 | case PRE_KEY: | |||
| 201 | if (!strchr(NEWLINE"\n\r", db[i])) { | |||
| 202 | key = db[i]; | |||
| 203 | ||||
| 204 | state = KEY; | |||
| 205 | } | |||
| 206 | ||||
| 207 | break; | |||
| 208 | case KEY: | |||
| 209 | if (db[i] != ':') { | |||
| 210 | log_debug("sd-device: ignoring invalid db entry with key '%c'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 210, __func__ , "sd-device: ignoring invalid db entry with key '%c'", key) : -abs(_e); }); | |||
| 211 | ||||
| 212 | state = INVALID_LINE; | |||
| 213 | } else { | |||
| 214 | db[i] = '\0'; | |||
| 215 | ||||
| 216 | state = PRE_VALUE; | |||
| 217 | } | |||
| 218 | ||||
| 219 | break; | |||
| 220 | case PRE_VALUE: | |||
| 221 | value = &db[i]; | |||
| 222 | ||||
| 223 | state = VALUE; | |||
| 224 | ||||
| 225 | break; | |||
| 226 | case INVALID_LINE: | |||
| 227 | if (strchr(NEWLINE"\n\r", db[i])) | |||
| 228 | state = PRE_KEY; | |||
| 229 | ||||
| 230 | break; | |||
| 231 | case VALUE: | |||
| 232 | if (strchr(NEWLINE"\n\r", db[i])) { | |||
| 233 | db[i] = '\0'; | |||
| 234 | r = handle_db_line(device, key, value); | |||
| 235 | if (r < 0) | |||
| 236 | log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 236, __func__ , "sd-device: failed to handle db entry '%c:%s': %m", key, value ) : -abs(_e); }); | |||
| 237 | ||||
| 238 | state = PRE_KEY; | |||
| 239 | } | |||
| 240 | ||||
| 241 | break; | |||
| 242 | default: | |||
| 243 | assert_not_reached("invalid state when parsing db")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "invalid state when parsing db"), "../src/libsystemd/sd-device/device-private.c" , 243, __PRETTY_FUNCTION__); } while (0); | |||
| 244 | } | |||
| 245 | } | |||
| 246 | ||||
| 247 | device->db_loaded = true1; | |||
| 248 | ||||
| 249 | return 0; | |||
| 250 | } | |||
| 251 | ||||
| 252 | uint64_t device_get_properties_generation(sd_device *device) { | |||
| 253 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 253, __PRETTY_FUNCTION__); } while (0); | |||
| 254 | ||||
| 255 | return device->properties_generation; | |||
| 256 | } | |||
| 257 | ||||
| 258 | uint64_t device_get_tags_generation(sd_device *device) { | |||
| 259 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 259, __PRETTY_FUNCTION__); } while (0); | |||
| 260 | ||||
| 261 | return device->tags_generation; | |||
| 262 | } | |||
| 263 | ||||
| 264 | uint64_t device_get_devlinks_generation(sd_device *device) { | |||
| 265 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 265, __PRETTY_FUNCTION__); } while (0); | |||
| 266 | ||||
| 267 | return device->devlinks_generation; | |||
| 268 | } | |||
| 269 | ||||
| 270 | int device_get_devnode_mode(sd_device *device, mode_t *mode) { | |||
| 271 | int r; | |||
| 272 | ||||
| 273 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 273, __PRETTY_FUNCTION__); } while (0); | |||
| 274 | assert(mode)do { if ((__builtin_expect(!!(!(mode)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("mode"), "../src/libsystemd/sd-device/device-private.c" , 274, __PRETTY_FUNCTION__); } while (0); | |||
| 275 | ||||
| 276 | r = device_read_db(device); | |||
| 277 | if (r < 0) | |||
| 278 | return r; | |||
| 279 | ||||
| 280 | *mode = device->devmode; | |||
| 281 | ||||
| 282 | return 0; | |||
| 283 | } | |||
| 284 | ||||
| 285 | int device_get_devnode_uid(sd_device *device, uid_t *uid) { | |||
| 286 | int r; | |||
| 287 | ||||
| 288 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 288, __PRETTY_FUNCTION__); } while (0); | |||
| 289 | assert(uid)do { if ((__builtin_expect(!!(!(uid)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-device/device-private.c" , 289, __PRETTY_FUNCTION__); } while (0); | |||
| 290 | ||||
| 291 | r = device_read_db(device); | |||
| 292 | if (r < 0) | |||
| 293 | return r; | |||
| 294 | ||||
| 295 | *uid = device->devuid; | |||
| 296 | ||||
| 297 | return 0; | |||
| 298 | } | |||
| 299 | ||||
| 300 | static int device_set_devuid(sd_device *device, const char *uid) { | |||
| 301 | unsigned u; | |||
| 302 | int r; | |||
| 303 | ||||
| 304 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 304, __PRETTY_FUNCTION__); } while (0); | |||
| 305 | assert(uid)do { if ((__builtin_expect(!!(!(uid)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-device/device-private.c" , 305, __PRETTY_FUNCTION__); } while (0); | |||
| 306 | ||||
| 307 | r = safe_atou(uid, &u); | |||
| 308 | if (r < 0) | |||
| 309 | return r; | |||
| 310 | ||||
| 311 | r = device_add_property_internal(device, "DEVUID", uid); | |||
| 312 | if (r < 0) | |||
| 313 | return r; | |||
| 314 | ||||
| 315 | device->devuid = u; | |||
| 316 | ||||
| 317 | return 0; | |||
| 318 | } | |||
| 319 | ||||
| 320 | int device_get_devnode_gid(sd_device *device, gid_t *gid) { | |||
| 321 | int r; | |||
| 322 | ||||
| 323 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 323, __PRETTY_FUNCTION__); } while (0); | |||
| 324 | assert(gid)do { if ((__builtin_expect(!!(!(gid)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("gid"), "../src/libsystemd/sd-device/device-private.c" , 324, __PRETTY_FUNCTION__); } while (0); | |||
| 325 | ||||
| 326 | r = device_read_db(device); | |||
| 327 | if (r < 0) | |||
| 328 | return r; | |||
| 329 | ||||
| 330 | *gid = device->devgid; | |||
| 331 | ||||
| 332 | return 0; | |||
| 333 | } | |||
| 334 | ||||
| 335 | static int device_set_devgid(sd_device *device, const char *gid) { | |||
| 336 | unsigned g; | |||
| 337 | int r; | |||
| 338 | ||||
| 339 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 339, __PRETTY_FUNCTION__); } while (0); | |||
| 340 | assert(gid)do { if ((__builtin_expect(!!(!(gid)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("gid"), "../src/libsystemd/sd-device/device-private.c" , 340, __PRETTY_FUNCTION__); } while (0); | |||
| 341 | ||||
| 342 | r = safe_atou(gid, &g); | |||
| 343 | if (r < 0) | |||
| 344 | return r; | |||
| 345 | ||||
| 346 | r = device_add_property_internal(device, "DEVGID", gid); | |||
| 347 | if (r < 0) | |||
| 348 | return r; | |||
| 349 | ||||
| 350 | device->devgid = g; | |||
| 351 | ||||
| 352 | return 0; | |||
| 353 | } | |||
| 354 | ||||
| 355 | static int device_amend(sd_device *device, const char *key, const char *value) { | |||
| 356 | int r; | |||
| 357 | ||||
| 358 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 358, __PRETTY_FUNCTION__); } while (0); | |||
| 359 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd/sd-device/device-private.c" , 359, __PRETTY_FUNCTION__); } while (0); | |||
| 360 | assert(value)do { if ((__builtin_expect(!!(!(value)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("value"), "../src/libsystemd/sd-device/device-private.c" , 360, __PRETTY_FUNCTION__); } while (0); | |||
| 361 | ||||
| 362 | if (streq(key, "DEVPATH")(strcmp((key),("DEVPATH")) == 0)) { | |||
| 363 | char *path; | |||
| 364 | ||||
| 365 | path = strjoina("/sys", value)({ const char *_appendees_[] = { "/sys", value }; char *_d_, * _p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 366 | ||||
| 367 | /* the caller must verify or trust this data (e.g., if it comes from the kernel) */ | |||
| 368 | r = device_set_syspath(device, path, false0); | |||
| 369 | if (r < 0) | |||
| 370 | return log_debug_errno(r, "sd-device: could not set syspath to '%s': %m", path)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 370, __func__ , "sd-device: could not set syspath to '%s': %m", path) : -abs (_e); }); | |||
| 371 | } else if (streq(key, "SUBSYSTEM")(strcmp((key),("SUBSYSTEM")) == 0)) { | |||
| 372 | r = device_set_subsystem(device, value); | |||
| 373 | if (r < 0) | |||
| 374 | return log_debug_errno(r, "sd-device: could not set subsystem to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 374, __func__ , "sd-device: could not set subsystem to '%s': %m", value) : - abs(_e); }); | |||
| 375 | } else if (streq(key, "DEVTYPE")(strcmp((key),("DEVTYPE")) == 0)) { | |||
| 376 | r = device_set_devtype(device, value); | |||
| 377 | if (r < 0) | |||
| 378 | return log_debug_errno(r, "sd-device: could not set devtype to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 378, __func__ , "sd-device: could not set devtype to '%s': %m", value) : -abs (_e); }); | |||
| 379 | } else if (streq(key, "DEVNAME")(strcmp((key),("DEVNAME")) == 0)) { | |||
| 380 | r = device_set_devname(device, value); | |||
| 381 | if (r < 0) | |||
| 382 | return log_debug_errno(r, "sd-device: could not set devname to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 382, __func__ , "sd-device: could not set devname to '%s': %m", value) : -abs (_e); }); | |||
| 383 | } else if (streq(key, "USEC_INITIALIZED")(strcmp((key),("USEC_INITIALIZED")) == 0)) { | |||
| 384 | r = device_set_usec_initialized(device, value); | |||
| 385 | if (r < 0) | |||
| 386 | return log_debug_errno(r, "sd-device: could not set usec-initialized to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 386, __func__ , "sd-device: could not set usec-initialized to '%s': %m", value ) : -abs(_e); }); | |||
| 387 | } else if (streq(key, "DRIVER")(strcmp((key),("DRIVER")) == 0)) { | |||
| 388 | r = device_set_driver(device, value); | |||
| 389 | if (r < 0) | |||
| 390 | return log_debug_errno(r, "sd-device: could not set driver to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 390, __func__ , "sd-device: could not set driver to '%s': %m", value) : -abs (_e); }); | |||
| 391 | } else if (streq(key, "IFINDEX")(strcmp((key),("IFINDEX")) == 0)) { | |||
| 392 | r = device_set_ifindex(device, value); | |||
| 393 | if (r < 0) | |||
| 394 | return log_debug_errno(r, "sd-device: could not set ifindex to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 394, __func__ , "sd-device: could not set ifindex to '%s': %m", value) : -abs (_e); }); | |||
| 395 | } else if (streq(key, "DEVMODE")(strcmp((key),("DEVMODE")) == 0)) { | |||
| 396 | r = device_set_devmode(device, value); | |||
| 397 | if (r < 0) | |||
| 398 | return log_debug_errno(r, "sd-device: could not set devmode to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 398, __func__ , "sd-device: could not set devmode to '%s': %m", value) : -abs (_e); }); | |||
| 399 | } else if (streq(key, "DEVUID")(strcmp((key),("DEVUID")) == 0)) { | |||
| 400 | r = device_set_devuid(device, value); | |||
| 401 | if (r < 0) | |||
| 402 | return log_debug_errno(r, "sd-device: could not set devuid to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 402, __func__ , "sd-device: could not set devuid to '%s': %m", value) : -abs (_e); }); | |||
| 403 | } else if (streq(key, "DEVGID")(strcmp((key),("DEVGID")) == 0)) { | |||
| 404 | r = device_set_devgid(device, value); | |||
| 405 | if (r < 0) | |||
| 406 | return log_debug_errno(r, "sd-device: could not set devgid to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 406, __func__ , "sd-device: could not set devgid to '%s': %m", value) : -abs (_e); }); | |||
| 407 | } else if (streq(key, "DEVLINKS")(strcmp((key),("DEVLINKS")) == 0)) { | |||
| 408 | const char *word, *state; | |||
| 409 | size_t l; | |||
| 410 | ||||
| 411 | FOREACH_WORD(word, l, value, state)for ((state) = (value), (word) = split(&(state), &(l) , (" \t\n\r"), (0)); (word); (word) = split(&(state), & (l), (" \t\n\r"), (0))) { | |||
| 412 | char devlink[l + 1]; | |||
| 413 | ||||
| 414 | strncpy(devlink, word, l); | |||
| 415 | devlink[l] = '\0'; | |||
| 416 | ||||
| 417 | r = device_add_devlink(device, devlink); | |||
| 418 | if (r < 0) | |||
| 419 | return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlink)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 419, __func__ , "sd-device: could not add devlink '%s': %m", devlink) : -abs (_e); }); | |||
| 420 | } | |||
| 421 | } else if (streq(key, "TAGS")(strcmp((key),("TAGS")) == 0)) { | |||
| 422 | const char *word, *state; | |||
| 423 | size_t l; | |||
| 424 | ||||
| 425 | FOREACH_WORD_SEPARATOR(word, l, value, ":", state)for ((state) = (value), (word) = split(&(state), &(l) , (":"), (0)); (word); (word) = split(&(state), &(l), (":"), (0))) { | |||
| 426 | char tag[l + 1]; | |||
| 427 | ||||
| 428 | (void)strncpy(tag, word, l); | |||
| 429 | tag[l] = '\0'; | |||
| 430 | ||||
| 431 | r = device_add_tag(device, tag); | |||
| 432 | if (r < 0) | |||
| 433 | return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tag)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 433, __func__ , "sd-device: could not add tag '%s': %m", tag) : -abs(_e); } ); | |||
| 434 | } | |||
| 435 | } else { | |||
| 436 | r = device_add_property_internal(device, key, value); | |||
| 437 | if (r < 0) | |||
| 438 | return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 438, __func__ , "sd-device: could not add property '%s=%s': %m", key, value ) : -abs(_e); }); | |||
| 439 | } | |||
| 440 | ||||
| 441 | return 0; | |||
| 442 | } | |||
| 443 | ||||
| 444 | static const char* const device_action_table[_DEVICE_ACTION_MAX] = { | |||
| 445 | [DEVICE_ACTION_ADD] = "add", | |||
| 446 | [DEVICE_ACTION_REMOVE] = "remove", | |||
| 447 | [DEVICE_ACTION_CHANGE] = "change", | |||
| 448 | [DEVICE_ACTION_MOVE] = "move", | |||
| 449 | [DEVICE_ACTION_ONLINE] = "online", | |||
| 450 | [DEVICE_ACTION_OFFLINE] = "offline", | |||
| 451 | [DEVICE_ACTION_BIND] = "bind", | |||
| 452 | [DEVICE_ACTION_UNBIND] = "unbind", | |||
| 453 | }; | |||
| 454 | ||||
| 455 | DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction)const char *device_action_to_string(DeviceAction i) { if (i < 0 || i >= (DeviceAction) __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(device_action_table), typeof (&*(device_action_table))), sizeof(device_action_table)/sizeof ((device_action_table)[0]), ((void)0)))) return ((void*)0); return device_action_table[i]; } DeviceAction device_action_from_string (const char *s) { return (DeviceAction) string_table_lookup(device_action_table , __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(device_action_table), typeof(&*(device_action_table ))), sizeof(device_action_table)/sizeof((device_action_table) [0]), ((void)0))), s); }; | |||
| 456 | ||||
| 457 | static int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum, | |||
| 458 | DeviceAction *_action) { | |||
| 459 | DeviceAction action = _DEVICE_ACTION_INVALID; | |||
| 460 | uint64_t seqnum = 0; | |||
| 461 | const char *major = NULL((void*)0), *minor = NULL((void*)0); | |||
| 462 | char *value; | |||
| 463 | int r; | |||
| 464 | ||||
| 465 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 465, __PRETTY_FUNCTION__); } while (0); | |||
| 466 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd/sd-device/device-private.c" , 466, __PRETTY_FUNCTION__); } while (0); | |||
| 467 | assert(_major)do { if ((__builtin_expect(!!(!(_major)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_major"), "../src/libsystemd/sd-device/device-private.c" , 467, __PRETTY_FUNCTION__); } while (0); | |||
| 468 | assert(_minor)do { if ((__builtin_expect(!!(!(_minor)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_minor"), "../src/libsystemd/sd-device/device-private.c" , 468, __PRETTY_FUNCTION__); } while (0); | |||
| 469 | assert(_seqnum)do { if ((__builtin_expect(!!(!(_seqnum)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_seqnum"), "../src/libsystemd/sd-device/device-private.c" , 469, __PRETTY_FUNCTION__); } while (0); | |||
| 470 | assert(_action)do { if ((__builtin_expect(!!(!(_action)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_action"), "../src/libsystemd/sd-device/device-private.c" , 470, __PRETTY_FUNCTION__); } while (0); | |||
| 471 | ||||
| 472 | value = strchr(key, '='); | |||
| 473 | if (!value) { | |||
| 474 | log_debug("sd-device: not a key-value pair: '%s'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 474, __func__ , "sd-device: not a key-value pair: '%s'", key) : -abs(_e); } ); | |||
| 475 | return -EINVAL22; | |||
| 476 | } | |||
| 477 | ||||
| 478 | *value = '\0'; | |||
| 479 | ||||
| 480 | value++; | |||
| 481 | ||||
| 482 | if (streq(key, "MAJOR")(strcmp((key),("MAJOR")) == 0)) | |||
| 483 | major = value; | |||
| 484 | else if (streq(key, "MINOR")(strcmp((key),("MINOR")) == 0)) | |||
| 485 | minor = value; | |||
| 486 | else { | |||
| 487 | if (streq(key, "ACTION")(strcmp((key),("ACTION")) == 0)) { | |||
| 488 | action = device_action_from_string(value); | |||
| 489 | if (action == _DEVICE_ACTION_INVALID) | |||
| 490 | return -EINVAL22; | |||
| 491 | } else if (streq(key, "SEQNUM")(strcmp((key),("SEQNUM")) == 0)) { | |||
| 492 | r = safe_atou64(value, &seqnum); | |||
| 493 | if (r < 0) | |||
| 494 | return r; | |||
| 495 | else if (seqnum == 0) | |||
| 496 | /* kernel only sends seqnum > 0 */ | |||
| 497 | return -EINVAL22; | |||
| 498 | } | |||
| 499 | ||||
| 500 | r = device_amend(device, key, value); | |||
| 501 | if (r < 0) | |||
| 502 | return r; | |||
| 503 | } | |||
| 504 | ||||
| 505 | if (major != 0) | |||
| 506 | *_major = major; | |||
| 507 | ||||
| 508 | if (minor != 0) | |||
| 509 | *_minor = minor; | |||
| 510 | ||||
| 511 | if (action != _DEVICE_ACTION_INVALID) | |||
| 512 | *_action = action; | |||
| 513 | ||||
| 514 | if (seqnum > 0) | |||
| 515 | *_seqnum = seqnum; | |||
| 516 | ||||
| 517 | return 0; | |||
| 518 | } | |||
| 519 | ||||
| 520 | void device_seal(sd_device *device) { | |||
| 521 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 521, __PRETTY_FUNCTION__); } while (0); | |||
| 522 | ||||
| 523 | device->sealed = true1; | |||
| 524 | } | |||
| 525 | ||||
| 526 | static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) { | |||
| 527 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 527, __PRETTY_FUNCTION__); } while (0); | |||
| 528 | ||||
| 529 | if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) { | |||
| 530 | log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 530, __func__ , "sd-device: device created from strv lacks devpath, subsystem, action or seqnum" ) : -abs(_e); }); | |||
| 531 | return -EINVAL22; | |||
| 532 | } | |||
| 533 | ||||
| 534 | device->sealed = true1; | |||
| 535 | ||||
| 536 | return 0; | |||
| 537 | } | |||
| 538 | ||||
| 539 | int device_new_from_strv(sd_device **ret, char **strv) { | |||
| 540 | _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *device = NULL((void*)0); | |||
| 541 | char **key; | |||
| 542 | const char *major = NULL((void*)0), *minor = NULL((void*)0); | |||
| 543 | DeviceAction action = _DEVICE_ACTION_INVALID; | |||
| 544 | uint64_t seqnum; | |||
| ||||
| 545 | int r; | |||
| 546 | ||||
| 547 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd/sd-device/device-private.c" , 547, __PRETTY_FUNCTION__); } while (0); | |||
| 548 | assert(strv)do { if ((__builtin_expect(!!(!(strv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("strv"), "../src/libsystemd/sd-device/device-private.c" , 548, __PRETTY_FUNCTION__); } while (0); | |||
| 549 | ||||
| 550 | r = device_new_aux(&device); | |||
| 551 | if (r < 0) | |||
| 552 | return r; | |||
| 553 | ||||
| 554 | STRV_FOREACH(key, strv)for ((key) = (strv); (key) && *(key); (key)++) { | |||
| 555 | r = device_append(device, *key, &major, &minor, &seqnum, &action); | |||
| 556 | if (r < 0) | |||
| 557 | return r; | |||
| 558 | } | |||
| 559 | ||||
| 560 | if (major
| |||
| 561 | r = device_set_devnum(device, major, minor); | |||
| 562 | if (r < 0) | |||
| 563 | return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 563, __func__ , "sd-device: could not set devnum %s:%s: %m", major, minor) : -abs(_e); }); | |||
| 564 | } | |||
| 565 | ||||
| 566 | r = device_verify(device, action, seqnum); | |||
| ||||
| 567 | if (r < 0) | |||
| 568 | return r; | |||
| 569 | ||||
| 570 | *ret = TAKE_PTR(device)({ typeof(device) _ptr_ = (device); (device) = ((void*)0); _ptr_ ; }); | |||
| 571 | ||||
| 572 | return 0; | |||
| 573 | } | |||
| 574 | ||||
| 575 | int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) { | |||
| 576 | _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *device = NULL((void*)0); | |||
| 577 | const char *major = NULL((void*)0), *minor = NULL((void*)0); | |||
| 578 | DeviceAction action = _DEVICE_ACTION_INVALID; | |||
| 579 | uint64_t seqnum; | |||
| 580 | unsigned i = 0; | |||
| 581 | int r; | |||
| 582 | ||||
| 583 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd/sd-device/device-private.c" , 583, __PRETTY_FUNCTION__); } while (0); | |||
| 584 | assert(nulstr)do { if ((__builtin_expect(!!(!(nulstr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("nulstr"), "../src/libsystemd/sd-device/device-private.c" , 584, __PRETTY_FUNCTION__); } while (0); | |||
| 585 | assert(len)do { if ((__builtin_expect(!!(!(len)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("len"), "../src/libsystemd/sd-device/device-private.c" , 585, __PRETTY_FUNCTION__); } while (0); | |||
| 586 | ||||
| 587 | r = device_new_aux(&device); | |||
| 588 | if (r < 0) | |||
| 589 | return r; | |||
| 590 | ||||
| 591 | while (i < len) { | |||
| 592 | char *key; | |||
| 593 | const char *end; | |||
| 594 | ||||
| 595 | key = (char*)&nulstr[i]; | |||
| 596 | end = memchr(key, '\0', len - i); | |||
| 597 | if (!end) { | |||
| 598 | log_debug("sd-device: failed to parse nulstr")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 598, __func__ , "sd-device: failed to parse nulstr") : -abs(_e); }); | |||
| 599 | return -EINVAL22; | |||
| 600 | } | |||
| 601 | i += end - key + 1; | |||
| 602 | ||||
| 603 | r = device_append(device, key, &major, &minor, &seqnum, &action); | |||
| 604 | if (r < 0) | |||
| 605 | return r; | |||
| 606 | } | |||
| 607 | ||||
| 608 | if (major) { | |||
| 609 | r = device_set_devnum(device, major, minor); | |||
| 610 | if (r < 0) | |||
| 611 | return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 611, __func__ , "sd-device: could not set devnum %s:%s: %m", major, minor) : -abs(_e); }); | |||
| 612 | } | |||
| 613 | ||||
| 614 | r = device_verify(device, action, seqnum); | |||
| 615 | if (r < 0) | |||
| 616 | return r; | |||
| 617 | ||||
| 618 | *ret = TAKE_PTR(device)({ typeof(device) _ptr_ = (device); (device) = ((void*)0); _ptr_ ; }); | |||
| 619 | ||||
| 620 | return 0; | |||
| 621 | } | |||
| 622 | ||||
| 623 | static int device_update_properties_bufs(sd_device *device) { | |||
| 624 | const char *val, *prop; | |||
| 625 | _cleanup_free___attribute__((cleanup(freep))) char **buf_strv = NULL((void*)0); | |||
| 626 | _cleanup_free___attribute__((cleanup(freep))) uint8_t *buf_nulstr = NULL((void*)0); | |||
| 627 | size_t allocated_nulstr = 0; | |||
| 628 | size_t nulstr_len = 0, num = 0, i = 0; | |||
| 629 | ||||
| 630 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 630, __PRETTY_FUNCTION__); } while (0); | |||
| 631 | ||||
| 632 | if (!device->properties_buf_outdated) | |||
| 633 | return 0; | |||
| 634 | ||||
| 635 | FOREACH_DEVICE_PROPERTY(device, prop, val)for (prop = sd_device_get_property_first(device, &(val)); prop; prop = sd_device_get_property_next(device, &(val)) ) { | |||
| 636 | size_t len = 0; | |||
| 637 | ||||
| 638 | len = strlen(prop) + 1 + strlen(val); | |||
| 639 | ||||
| 640 | buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2)greedy_realloc0((void**) &(buf_nulstr), &(allocated_nulstr ), (nulstr_len + len + 2), sizeof((buf_nulstr)[0])); | |||
| 641 | if (!buf_nulstr) | |||
| 642 | return -ENOMEM12; | |||
| 643 | ||||
| 644 | strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL((void*)0)); | |||
| 645 | nulstr_len += len + 1; | |||
| 646 | ++num; | |||
| 647 | } | |||
| 648 | ||||
| 649 | /* build buf_strv from buf_nulstr */ | |||
| 650 | buf_strv = new0(char *, num + 1)((char **) calloc((num + 1), sizeof(char *))); | |||
| 651 | if (!buf_strv) | |||
| 652 | return -ENOMEM12; | |||
| 653 | ||||
| 654 | NULSTR_FOREACH(val, (char*) buf_nulstr)for ((val) = ((char*) buf_nulstr); (val) && *(val); ( val) = strchr((val), 0)+1) { | |||
| 655 | buf_strv[i] = (char *) val; | |||
| 656 | assert(i < num)do { if ((__builtin_expect(!!(!(i < num)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i < num"), "../src/libsystemd/sd-device/device-private.c" , 656, __PRETTY_FUNCTION__); } while (0); | |||
| 657 | i++; | |||
| 658 | } | |||
| 659 | ||||
| 660 | free_and_replace(device->properties_nulstr, buf_nulstr)({ free(device->properties_nulstr); (device->properties_nulstr ) = (buf_nulstr); (buf_nulstr) = ((void*)0); 0; }); | |||
| 661 | device->properties_nulstr_len = nulstr_len; | |||
| 662 | free_and_replace(device->properties_strv, buf_strv)({ free(device->properties_strv); (device->properties_strv ) = (buf_strv); (buf_strv) = ((void*)0); 0; }); | |||
| 663 | ||||
| 664 | device->properties_buf_outdated = false0; | |||
| 665 | ||||
| 666 | return 0; | |||
| 667 | } | |||
| 668 | ||||
| 669 | int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) { | |||
| 670 | int r; | |||
| 671 | ||||
| 672 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 672, __PRETTY_FUNCTION__); } while (0); | |||
| 673 | assert(nulstr)do { if ((__builtin_expect(!!(!(nulstr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("nulstr"), "../src/libsystemd/sd-device/device-private.c" , 673, __PRETTY_FUNCTION__); } while (0); | |||
| 674 | assert(len)do { if ((__builtin_expect(!!(!(len)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("len"), "../src/libsystemd/sd-device/device-private.c" , 674, __PRETTY_FUNCTION__); } while (0); | |||
| 675 | ||||
| 676 | r = device_update_properties_bufs(device); | |||
| 677 | if (r < 0) | |||
| 678 | return r; | |||
| 679 | ||||
| 680 | *nulstr = device->properties_nulstr; | |||
| 681 | *len = device->properties_nulstr_len; | |||
| 682 | ||||
| 683 | return 0; | |||
| 684 | } | |||
| 685 | ||||
| 686 | int device_get_properties_strv(sd_device *device, char ***strv) { | |||
| 687 | int r; | |||
| 688 | ||||
| 689 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 689, __PRETTY_FUNCTION__); } while (0); | |||
| 690 | assert(strv)do { if ((__builtin_expect(!!(!(strv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("strv"), "../src/libsystemd/sd-device/device-private.c" , 690, __PRETTY_FUNCTION__); } while (0); | |||
| 691 | ||||
| 692 | r = device_update_properties_bufs(device); | |||
| 693 | if (r < 0) | |||
| 694 | return r; | |||
| 695 | ||||
| 696 | *strv = device->properties_strv; | |||
| 697 | ||||
| 698 | return 0; | |||
| 699 | } | |||
| 700 | ||||
| 701 | int device_get_devlink_priority(sd_device *device, int *priority) { | |||
| 702 | int r; | |||
| 703 | ||||
| 704 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 704, __PRETTY_FUNCTION__); } while (0); | |||
| 705 | assert(priority)do { if ((__builtin_expect(!!(!(priority)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("priority"), "../src/libsystemd/sd-device/device-private.c" , 705, __PRETTY_FUNCTION__); } while (0); | |||
| 706 | ||||
| 707 | r = device_read_db(device); | |||
| 708 | if (r < 0) | |||
| 709 | return r; | |||
| 710 | ||||
| 711 | *priority = device->devlink_priority; | |||
| 712 | ||||
| 713 | return 0; | |||
| 714 | } | |||
| 715 | ||||
| 716 | int device_get_watch_handle(sd_device *device, int *handle) { | |||
| 717 | int r; | |||
| 718 | ||||
| 719 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 719, __PRETTY_FUNCTION__); } while (0); | |||
| 720 | assert(handle)do { if ((__builtin_expect(!!(!(handle)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("handle"), "../src/libsystemd/sd-device/device-private.c" , 720, __PRETTY_FUNCTION__); } while (0); | |||
| 721 | ||||
| 722 | r = device_read_db(device); | |||
| 723 | if (r < 0) | |||
| 724 | return r; | |||
| 725 | ||||
| 726 | *handle = device->watch_handle; | |||
| 727 | ||||
| 728 | return 0; | |||
| 729 | } | |||
| 730 | ||||
| 731 | void device_set_watch_handle(sd_device *device, int handle) { | |||
| 732 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 732, __PRETTY_FUNCTION__); } while (0); | |||
| 733 | ||||
| 734 | device->watch_handle = handle; | |||
| 735 | } | |||
| 736 | ||||
| 737 | int device_rename(sd_device *device, const char *name) { | |||
| 738 | _cleanup_free___attribute__((cleanup(freep))) char *dirname = NULL((void*)0); | |||
| 739 | char *new_syspath; | |||
| 740 | const char *interface; | |||
| 741 | int r; | |||
| 742 | ||||
| 743 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 743, __PRETTY_FUNCTION__); } while (0); | |||
| 744 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/libsystemd/sd-device/device-private.c" , 744, __PRETTY_FUNCTION__); } while (0); | |||
| 745 | ||||
| 746 | dirname = dirname_malloc(device->syspath); | |||
| 747 | if (!dirname) | |||
| 748 | return -ENOMEM12; | |||
| 749 | ||||
| 750 | new_syspath = strjoina(dirname, "/", name)({ const char *_appendees_[] = { dirname, "/", name }; char * _d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 751 | ||||
| 752 | /* the user must trust that the new name is correct */ | |||
| 753 | r = device_set_syspath(device, new_syspath, false0); | |||
| 754 | if (r < 0) | |||
| 755 | return r; | |||
| 756 | ||||
| 757 | r = sd_device_get_property_value(device, "INTERFACE", &interface); | |||
| 758 | if (r >= 0) { | |||
| 759 | /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */ | |||
| 760 | r = device_add_property_internal(device, "INTERFACE_OLD", interface); | |||
| 761 | if (r < 0) | |||
| 762 | return r; | |||
| 763 | ||||
| 764 | r = device_add_property_internal(device, "INTERFACE", name); | |||
| 765 | if (r < 0) | |||
| 766 | return r; | |||
| 767 | } else if (r != -ENOENT2) | |||
| 768 | return r; | |||
| 769 | ||||
| 770 | return 0; | |||
| 771 | } | |||
| 772 | ||||
| 773 | int device_shallow_clone(sd_device *old_device, sd_device **new_device) { | |||
| 774 | _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *ret = NULL((void*)0); | |||
| 775 | int r; | |||
| 776 | ||||
| 777 | assert(old_device)do { if ((__builtin_expect(!!(!(old_device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("old_device"), "../src/libsystemd/sd-device/device-private.c" , 777, __PRETTY_FUNCTION__); } while (0); | |||
| 778 | assert(new_device)do { if ((__builtin_expect(!!(!(new_device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("new_device"), "../src/libsystemd/sd-device/device-private.c" , 778, __PRETTY_FUNCTION__); } while (0); | |||
| 779 | ||||
| 780 | r = device_new_aux(&ret); | |||
| 781 | if (r < 0) | |||
| 782 | return r; | |||
| 783 | ||||
| 784 | r = device_set_syspath(ret, old_device->syspath, false0); | |||
| 785 | if (r < 0) | |||
| 786 | return r; | |||
| 787 | ||||
| 788 | r = device_set_subsystem(ret, old_device->subsystem); | |||
| 789 | if (r < 0) | |||
| 790 | return r; | |||
| 791 | ||||
| 792 | ret->devnum = old_device->devnum; | |||
| 793 | ||||
| 794 | *new_device = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; }); | |||
| 795 | ||||
| 796 | return 0; | |||
| 797 | } | |||
| 798 | ||||
| 799 | int device_clone_with_db(sd_device *old_device, sd_device **new_device) { | |||
| 800 | _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *ret = NULL((void*)0); | |||
| 801 | int r; | |||
| 802 | ||||
| 803 | assert(old_device)do { if ((__builtin_expect(!!(!(old_device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("old_device"), "../src/libsystemd/sd-device/device-private.c" , 803, __PRETTY_FUNCTION__); } while (0); | |||
| 804 | assert(new_device)do { if ((__builtin_expect(!!(!(new_device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("new_device"), "../src/libsystemd/sd-device/device-private.c" , 804, __PRETTY_FUNCTION__); } while (0); | |||
| 805 | ||||
| 806 | r = device_shallow_clone(old_device, &ret); | |||
| 807 | if (r < 0) | |||
| 808 | return r; | |||
| 809 | ||||
| 810 | r = device_read_db(ret); | |||
| 811 | if (r < 0) | |||
| 812 | return r; | |||
| 813 | ||||
| 814 | ret->sealed = true1; | |||
| 815 | ||||
| 816 | *new_device = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; }); | |||
| 817 | ||||
| 818 | return 0; | |||
| 819 | } | |||
| 820 | ||||
| 821 | int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) { | |||
| 822 | _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *ret = NULL((void*)0); | |||
| 823 | int r; | |||
| 824 | ||||
| 825 | assert(new_device)do { if ((__builtin_expect(!!(!(new_device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("new_device"), "../src/libsystemd/sd-device/device-private.c" , 825, __PRETTY_FUNCTION__); } while (0); | |||
| 826 | assert(syspath)do { if ((__builtin_expect(!!(!(syspath)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("syspath"), "../src/libsystemd/sd-device/device-private.c" , 826, __PRETTY_FUNCTION__); } while (0); | |||
| 827 | assert(action)do { if ((__builtin_expect(!!(!(action)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("action"), "../src/libsystemd/sd-device/device-private.c" , 827, __PRETTY_FUNCTION__); } while (0); | |||
| 828 | ||||
| 829 | r = sd_device_new_from_syspath(&ret, syspath); | |||
| 830 | if (r < 0) | |||
| 831 | return r; | |||
| 832 | ||||
| 833 | r = device_read_uevent_file(ret); | |||
| 834 | if (r < 0) | |||
| 835 | return r; | |||
| 836 | ||||
| 837 | r = device_add_property_internal(ret, "ACTION", action); | |||
| 838 | if (r < 0) | |||
| 839 | return r; | |||
| 840 | ||||
| 841 | *new_device = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; }); | |||
| 842 | ||||
| 843 | return 0; | |||
| 844 | } | |||
| 845 | ||||
| 846 | int device_copy_properties(sd_device *device_dst, sd_device *device_src) { | |||
| 847 | const char *property, *value; | |||
| 848 | int r; | |||
| 849 | ||||
| 850 | assert(device_dst)do { if ((__builtin_expect(!!(!(device_dst)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device_dst"), "../src/libsystemd/sd-device/device-private.c" , 850, __PRETTY_FUNCTION__); } while (0); | |||
| 851 | assert(device_src)do { if ((__builtin_expect(!!(!(device_src)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device_src"), "../src/libsystemd/sd-device/device-private.c" , 851, __PRETTY_FUNCTION__); } while (0); | |||
| 852 | ||||
| 853 | FOREACH_DEVICE_PROPERTY(device_src, property, value)for (property = sd_device_get_property_first(device_src, & (value)); property; property = sd_device_get_property_next(device_src , &(value))) { | |||
| 854 | r = device_add_property(device_dst, property, value); | |||
| 855 | if (r < 0) | |||
| 856 | return r; | |||
| 857 | } | |||
| 858 | ||||
| 859 | return 0; | |||
| 860 | } | |||
| 861 | ||||
| 862 | void device_cleanup_tags(sd_device *device) { | |||
| 863 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 863, __PRETTY_FUNCTION__); } while (0); | |||
| 864 | ||||
| 865 | set_free_free(device->tags); | |||
| 866 | device->tags = NULL((void*)0); | |||
| 867 | device->property_tags_outdated = true1; | |||
| 868 | device->tags_generation++; | |||
| 869 | } | |||
| 870 | ||||
| 871 | void device_cleanup_devlinks(sd_device *device) { | |||
| 872 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 872, __PRETTY_FUNCTION__); } while (0); | |||
| 873 | ||||
| 874 | set_free_free(device->devlinks); | |||
| 875 | device->devlinks = NULL((void*)0); | |||
| 876 | device->property_devlinks_outdated = true1; | |||
| 877 | device->devlinks_generation++; | |||
| 878 | } | |||
| 879 | ||||
| 880 | void device_remove_tag(sd_device *device, const char *tag) { | |||
| 881 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 881, __PRETTY_FUNCTION__); } while (0); | |||
| 882 | assert(tag)do { if ((__builtin_expect(!!(!(tag)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("tag"), "../src/libsystemd/sd-device/device-private.c" , 882, __PRETTY_FUNCTION__); } while (0); | |||
| 883 | ||||
| 884 | free(set_remove(device->tags, tag)); | |||
| 885 | device->property_tags_outdated = true1; | |||
| 886 | device->tags_generation++; | |||
| 887 | } | |||
| 888 | ||||
| 889 | static int device_tag(sd_device *device, const char *tag, bool_Bool add) { | |||
| 890 | const char *id; | |||
| 891 | char *path; | |||
| 892 | int r; | |||
| 893 | ||||
| 894 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 894, __PRETTY_FUNCTION__); } while (0); | |||
| 895 | assert(tag)do { if ((__builtin_expect(!!(!(tag)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("tag"), "../src/libsystemd/sd-device/device-private.c" , 895, __PRETTY_FUNCTION__); } while (0); | |||
| 896 | ||||
| 897 | r = device_get_id_filename(device, &id); | |||
| 898 | if (r < 0) | |||
| 899 | return r; | |||
| 900 | ||||
| 901 | path = strjoina("/run/udev/tags/", tag, "/", id)({ const char *_appendees_[] = { "/run/udev/tags/", tag, "/", id }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 902 | ||||
| 903 | if (add) { | |||
| 904 | r = touch_file(path, true1, USEC_INFINITY((usec_t) -1), UID_INVALID((uid_t) -1), GID_INVALID((gid_t) -1), 0444); | |||
| 905 | if (r < 0) | |||
| 906 | return r; | |||
| 907 | } else { | |||
| 908 | r = unlink(path); | |||
| 909 | if (r < 0 && errno(*__errno_location ()) != ENOENT2) | |||
| 910 | return -errno(*__errno_location ()); | |||
| 911 | } | |||
| 912 | ||||
| 913 | return 0; | |||
| 914 | } | |||
| 915 | ||||
| 916 | int device_tag_index(sd_device *device, sd_device *device_old, bool_Bool add) { | |||
| 917 | const char *tag; | |||
| 918 | int r = 0, k; | |||
| 919 | ||||
| 920 | if (add && device_old) { | |||
| 921 | /* delete possible left-over tags */ | |||
| 922 | FOREACH_DEVICE_TAG(device_old, tag)for (tag = sd_device_get_tag_first(device_old); tag; tag = sd_device_get_tag_next (device_old)) { | |||
| 923 | if (!sd_device_has_tag(device, tag)) { | |||
| 924 | k = device_tag(device_old, tag, false0); | |||
| 925 | if (r >= 0 && k < 0) | |||
| 926 | r = k; | |||
| 927 | } | |||
| 928 | } | |||
| 929 | } | |||
| 930 | ||||
| 931 | FOREACH_DEVICE_TAG(device, tag)for (tag = sd_device_get_tag_first(device); tag; tag = sd_device_get_tag_next (device)) { | |||
| 932 | k = device_tag(device, tag, add); | |||
| 933 | if (r >= 0 && k < 0) | |||
| 934 | r = k; | |||
| 935 | } | |||
| 936 | ||||
| 937 | return r; | |||
| 938 | } | |||
| 939 | ||||
| 940 | static bool_Bool device_has_info(sd_device *device) { | |||
| 941 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 941, __PRETTY_FUNCTION__); } while (0); | |||
| 942 | ||||
| 943 | if (!set_isempty(device->devlinks)) | |||
| 944 | return true1; | |||
| 945 | ||||
| 946 | if (device->devlink_priority != 0) | |||
| 947 | return true1; | |||
| 948 | ||||
| 949 | if (!ordered_hashmap_isempty(device->properties_db)) | |||
| 950 | return true1; | |||
| 951 | ||||
| 952 | if (!set_isempty(device->tags)) | |||
| 953 | return true1; | |||
| 954 | ||||
| 955 | if (device->watch_handle >= 0) | |||
| 956 | return true1; | |||
| 957 | ||||
| 958 | return false0; | |||
| 959 | } | |||
| 960 | ||||
| 961 | void device_set_db_persist(sd_device *device) { | |||
| 962 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 962, __PRETTY_FUNCTION__); } while (0); | |||
| 963 | ||||
| 964 | device->db_persist = true1; | |||
| 965 | } | |||
| 966 | ||||
| 967 | int device_update_db(sd_device *device) { | |||
| 968 | const char *id; | |||
| 969 | char *path; | |||
| 970 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 971 | _cleanup_free___attribute__((cleanup(freep))) char *path_tmp = NULL((void*)0); | |||
| 972 | bool_Bool has_info; | |||
| 973 | int r; | |||
| 974 | ||||
| 975 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 975, __PRETTY_FUNCTION__); } while (0); | |||
| 976 | ||||
| 977 | has_info = device_has_info(device); | |||
| 978 | ||||
| 979 | r = device_get_id_filename(device, &id); | |||
| 980 | if (r < 0) | |||
| 981 | return r; | |||
| 982 | ||||
| 983 | path = strjoina("/run/udev/data/", id)({ const char *_appendees_[] = { "/run/udev/data/", id }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 984 | ||||
| 985 | /* do not store anything for otherwise empty devices */ | |||
| 986 | if (!has_info && major(device->devnum)gnu_dev_major (device->devnum) == 0 && device->ifindex == 0) { | |||
| 987 | r = unlink(path); | |||
| 988 | if (r < 0 && errno(*__errno_location ()) != ENOENT2) | |||
| 989 | return -errno(*__errno_location ()); | |||
| 990 | ||||
| 991 | return 0; | |||
| 992 | } | |||
| 993 | ||||
| 994 | /* write a database file */ | |||
| 995 | r = mkdir_parents(path, 0755); | |||
| 996 | if (r < 0) | |||
| 997 | return r; | |||
| 998 | ||||
| 999 | r = fopen_temporary(path, &f, &path_tmp); | |||
| 1000 | if (r < 0) | |||
| 1001 | return r; | |||
| 1002 | ||||
| 1003 | /* | |||
| 1004 | * set 'sticky' bit to indicate that we should not clean the | |||
| 1005 | * database when we transition from initramfs to the real root | |||
| 1006 | */ | |||
| 1007 | if (device->db_persist) { | |||
| 1008 | r = fchmod(fileno(f), 01644); | |||
| 1009 | if (r < 0) { | |||
| 1010 | r = -errno(*__errno_location ()); | |||
| 1011 | goto fail; | |||
| 1012 | } | |||
| 1013 | } else { | |||
| 1014 | r = fchmod(fileno(f), 0644); | |||
| 1015 | if (r < 0) { | |||
| 1016 | r = -errno(*__errno_location ()); | |||
| 1017 | goto fail; | |||
| 1018 | } | |||
| 1019 | } | |||
| 1020 | ||||
| 1021 | if (has_info) { | |||
| 1022 | const char *property, *value, *tag; | |||
| 1023 | Iterator i; | |||
| 1024 | ||||
| 1025 | if (major(device->devnum)gnu_dev_major (device->devnum) > 0) { | |||
| 1026 | const char *devlink; | |||
| 1027 | ||||
| 1028 | FOREACH_DEVICE_DEVLINK(device, devlink)for (devlink = sd_device_get_devlink_first(device); devlink; devlink = sd_device_get_devlink_next(device)) | |||
| 1029 | fprintf(f, "S:%s\n", devlink + STRLEN("/dev/")(sizeof("""/dev/""") - 1)); | |||
| 1030 | ||||
| 1031 | if (device->devlink_priority != 0) | |||
| 1032 | fprintf(f, "L:%i\n", device->devlink_priority); | |||
| 1033 | ||||
| 1034 | if (device->watch_handle >= 0) | |||
| 1035 | fprintf(f, "W:%i\n", device->watch_handle); | |||
| 1036 | } | |||
| 1037 | ||||
| 1038 | if (device->usec_initialized > 0) | |||
| 1039 | fprintf(f, "I:"USEC_FMT"%" "l" "u""\n", device->usec_initialized); | |||
| 1040 | ||||
| 1041 | ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); ordered_hashmap_iterate((device-> properties_db), &(i), (void**)&(value), (const void** ) &(property)); ) | |||
| 1042 | fprintf(f, "E:%s=%s\n", property, value); | |||
| 1043 | ||||
| 1044 | FOREACH_DEVICE_TAG(device, tag)for (tag = sd_device_get_tag_first(device); tag; tag = sd_device_get_tag_next (device)) | |||
| 1045 | fprintf(f, "G:%s\n", tag); | |||
| 1046 | } | |||
| 1047 | ||||
| 1048 | r = fflush_and_check(f); | |||
| 1049 | if (r < 0) | |||
| 1050 | goto fail; | |||
| 1051 | ||||
| 1052 | r = rename(path_tmp, path); | |||
| 1053 | if (r < 0) { | |||
| 1054 | r = -errno(*__errno_location ()); | |||
| 1055 | goto fail; | |||
| 1056 | } | |||
| 1057 | ||||
| 1058 | log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 1059, __func__ , "created %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath) : -abs(_e); }) | |||
| 1059 | path, device->devpath)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 1059, __func__ , "created %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath) : -abs(_e); }); | |||
| 1060 | ||||
| 1061 | return 0; | |||
| 1062 | ||||
| 1063 | fail: | |||
| 1064 | (void) unlink(path); | |||
| 1065 | (void) unlink(path_tmp); | |||
| 1066 | ||||
| 1067 | return log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/libsystemd/sd-device/device-private.c", 1067, __func__ , "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath) : -abs(_e); }); | |||
| 1068 | } | |||
| 1069 | ||||
| 1070 | int device_delete_db(sd_device *device) { | |||
| 1071 | const char *id; | |||
| 1072 | char *path; | |||
| 1073 | int r; | |||
| 1074 | ||||
| 1075 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 1075, __PRETTY_FUNCTION__); } while (0); | |||
| 1076 | ||||
| 1077 | r = device_get_id_filename(device, &id); | |||
| 1078 | if (r < 0) | |||
| 1079 | return r; | |||
| 1080 | ||||
| 1081 | path = strjoina("/run/udev/data/", id)({ const char *_appendees_[] = { "/run/udev/data/", id }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 1082 | ||||
| 1083 | r = unlink(path); | |||
| 1084 | if (r < 0 && errno(*__errno_location ()) != ENOENT2) | |||
| 1085 | return -errno(*__errno_location ()); | |||
| 1086 | ||||
| 1087 | return 0; | |||
| 1088 | } | |||
| 1089 | ||||
| 1090 | int device_read_db_force(sd_device *device) { | |||
| 1091 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c" , 1091, __PRETTY_FUNCTION__); } while (0); | |||
| 1092 | ||||
| 1093 | return device_read_db_aux(device, true1); | |||
| 1094 | } |