59
60
struct udev_list_node devlinks_list;
60
61
struct udev_list_node properties_list;
61
62
struct udev_list_node sysattr_list;
63
struct udev_list_node tags_list;
62
64
unsigned long long int seqnum;
65
int num_fake_partitions;
66
67
int devlink_priority;
70
unsigned int parent_set:1;
71
unsigned int subsystem_set:1;
72
unsigned int devtype_set:1;
73
unsigned int devlinks_uptodate:1;
74
unsigned int envp_uptodate:1;
75
unsigned int driver_set:1;
76
unsigned int info_loaded:1;
77
unsigned int ignore_remove:1;
75
bool devlinks_uptodate;
84
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
86
udev_device->envp_uptodate = false;
88
struct udev_list_entry *list_entry;
90
list_entry = udev_device_get_properties_list_entry(udev_device);
91
list_entry = udev_list_entry_get_by_name(list_entry, key);
92
if (list_entry != NULL)
93
udev_list_entry_delete(list_entry);
96
return udev_list_entry_add(udev_device->udev, &udev_device->properties_list, key, value, 1, 0);
99
static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
101
char name[UTIL_LINE_SIZE];
104
util_strscpy(name, sizeof(name), property);
105
val = strchr(name, '=');
112
return udev_device_add_property(udev_device, name, val);
116
* parse property string, and if needed, update internal values accordingly
118
* udev_device_add_property_from_string_parse_finish() needs to be
119
* called after adding properties, and its return value checked
121
* udev_device_set_info_loaded() needs to be set, to avoid trying
122
* to use a device without a DEVPATH set
124
void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property)
126
if (strncmp(property, "DEVPATH=", 8) == 0) {
127
char path[UTIL_PATH_SIZE];
129
util_strscpyl(path, sizeof(path), udev_get_sys_path(udev_device->udev), &property[8], NULL);
130
udev_device_set_syspath(udev_device, path);
131
} else if (strncmp(property, "SUBSYSTEM=", 10) == 0) {
132
udev_device_set_subsystem(udev_device, &property[10]);
133
} else if (strncmp(property, "DEVTYPE=", 8) == 0) {
134
udev_device_set_devtype(udev_device, &property[8]);
135
} else if (strncmp(property, "DEVNAME=", 8) == 0) {
136
if (property[8] == '/')
137
udev_device_set_devnode(udev_device, &property[8]);
139
udev_device_set_knodename(udev_device, &property[8]);
140
} else if (strncmp(property, "DEVLINKS=", 9) == 0) {
141
char devlinks[UTIL_PATH_SIZE];
145
util_strscpy(devlinks, sizeof(devlinks), &property[9]);
147
next = strchr(slink, ' ');
148
while (next != NULL) {
150
udev_device_add_devlink(udev_device, slink, 0);
152
next = strchr(slink, ' ');
154
if (slink[0] != '\0')
155
udev_device_add_devlink(udev_device, slink, 0);
156
} else if (strncmp(property, "TAGS=", 5) == 0) {
157
char tags[UTIL_PATH_SIZE];
160
util_strscpy(tags, sizeof(tags), &property[5]);
161
next = strchr(tags, ':');
164
while (next[0] != '\0') {
168
next = strchr(tag, ':');
173
udev_device_add_tag(udev_device, tag);
176
} else if (strncmp(property, "DRIVER=", 7) == 0) {
177
udev_device_set_driver(udev_device, &property[7]);
178
} else if (strncmp(property, "ACTION=", 7) == 0) {
179
udev_device_set_action(udev_device, &property[7]);
180
} else if (strncmp(property, "MAJOR=", 6) == 0) {
181
udev_device->maj = strtoull(&property[6], NULL, 10);
182
} else if (strncmp(property, "MINOR=", 6) == 0) {
183
udev_device->min = strtoull(&property[6], NULL, 10);
184
} else if (strncmp(property, "DEVPATH_OLD=", 12) == 0) {
185
udev_device_set_devpath_old(udev_device, &property[12]);
186
} else if (strncmp(property, "SEQNUM=", 7) == 0) {
187
udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10));
188
} else if (strncmp(property, "TIMEOUT=", 8) == 0) {
189
udev_device_set_timeout(udev_device, strtoull(&property[8], NULL, 10));
191
udev_device_add_property_from_string(udev_device, property);
195
int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device)
197
if (udev_device->maj > 0)
198
udev_device_set_devnum(udev_device, makedev(udev_device->maj, udev_device->min));
199
udev_device->maj = 0;
200
udev_device->min = 0;
202
if (udev_device->devpath == NULL || udev_device->subsystem == NULL)
208
* udev_device_get_property_value:
209
* @udev_device: udev device
210
* @key: property name
212
* Returns: the value of a device property, or #NULL if there is no such property.
214
const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
216
struct udev_list_entry *list_entry;
218
if (udev_device == NULL)
223
list_entry = udev_device_get_properties_list_entry(udev_device);
224
list_entry = udev_list_entry_get_by_name(list_entry, key);
225
return udev_list_entry_get_value(list_entry);
80
228
int udev_device_read_db(struct udev_device *udev_device)
82
230
struct stat stats;
451
595
return udev_device_new_from_syspath(udev, path_full);
599
* udev_device_new_from_environment
600
* @udev: udev library context
602
* Create new udev device, and fill in information from the
603
* current process environment. This only works reliable if
604
* the process is called from a udev rule. It is usually used
605
* for tools executed from IMPORT= rules.
607
* The initial refcount is 1, and needs to be decremented to
608
* release the resources of the udev device.
610
* Returns: a new udev device, or #NULL, if it does not exist
612
struct udev_device *udev_device_new_from_environment(struct udev *udev)
615
struct udev_device *udev_device;
617
udev_device = udev_device_new(udev);
618
if (udev_device == NULL)
620
udev_device_set_info_loaded(udev_device);
622
for (i = 0; environ[i] != NULL; i++)
623
udev_device_add_property_from_string_parse(udev_device, environ[i]);
625
if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
626
info(udev, "missing values, invalid device\n");
627
udev_device_unref(udev_device);
454
634
static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
456
636
struct udev_device *udev_device_parent = NULL;
1064
1263
struct udev_list_entry *list_entry;
1066
udev_device->devlinks_uptodate = 0;
1265
udev_device->devlinks_uptodate = false;
1067
1266
list_entry = udev_list_entry_add(udev_device->udev, &udev_device->devlinks_list, devlink, NULL, 1, 0);
1068
1267
if (list_entry == NULL)
1069
1268
return -ENOMEM;
1071
udev_list_entry_set_flag(list_entry, 1);
1270
udev_list_entry_set_flags(list_entry, 1);
1075
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
1274
int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
1077
udev_device->envp_uptodate = 0;
1078
if (value == NULL) {
1079
struct udev_list_entry *list_entry;
1081
list_entry = udev_device_get_properties_list_entry(udev_device);
1082
list_entry = udev_list_entry_get_by_name(list_entry, key);
1083
if (list_entry != NULL)
1084
udev_list_entry_delete(list_entry);
1087
return udev_list_entry_add(udev_device->udev, &udev_device->properties_list, key, value, 1, 0);
1276
if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
1278
udev_device->tags_uptodate = false;
1279
if (udev_list_entry_add(udev_device->udev, &udev_device->tags_list, tag, NULL, 1, 0) != NULL)
1090
struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
1284
void udev_device_cleanup_tags_list(struct udev_device *udev_device)
1092
char name[UTIL_PATH_SIZE];
1095
util_strscpy(name, sizeof(name), property);
1096
val = strchr(name, '=');
1103
return udev_device_add_property(udev_device, name, val);
1286
udev_device->tags_uptodate = false;
1287
udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
1107
* udev_device_get_property_value:
1291
* udev_device_get_tags_list_entry:
1108
1292
* @udev_device: udev device
1109
* @key: property name
1111
* Returns: the value of a device property, or #NULL if there is no such property.
1294
* Retrieve the list of tags attached to the udev device. The next
1295
* list entry can be retrieved with udev_list_entry_next(),
1296
* which returns #NULL if no more entries exist. The tag string
1297
* can be retrieved from the list entry by udev_list_get_name().
1299
* Returns: the first entry of the tag list
1113
const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
1301
struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
1303
if (udev_device == NULL)
1305
return udev_list_get_entry(&udev_device->tags_list);
1308
int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
1115
1310
struct udev_list_entry *list_entry;
1117
if (udev_device == NULL)
1122
list_entry = udev_device_get_properties_list_entry(udev_device);
1123
list_entry = udev_list_entry_get_by_name(list_entry, key);
1124
return udev_list_entry_get_value(list_entry);
1312
if (!udev_device->info_loaded)
1313
udev_device_read_db(udev_device);
1314
list_entry = udev_device_get_tags_list_entry(udev_device);
1315
list_entry = udev_list_entry_get_by_name(list_entry, tag);
1316
if (list_entry != NULL)
1127
1321
#define ENVP_SIZE 128