~ubuntu-branches/ubuntu/maverick/udev/maverick

« back to all changes in this revision

Viewing changes to libudev/libudev-device.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-08-21 10:07:44 UTC
  • Revision ID: james.westby@ubuntu.com-20100821100744-otqi1fk1v4y584ux
Tags: 161+git20100820-1
* New upstream release 161, plus fixes from git head: (LP: #620977)
  - udevadm trigger now defaults to change instead of add.
  - modem modeswitch removed, use usb_modeswitch instead (see LP #521578)
  - NAME= now ignored
  - udevd creates device nodes itself on startup based on modules.udevname
  - default device permission is 0600
  - lots of bug fixes 
  - updated keymaps (LP: #271706, #554066, #569815, #592371)
  - update udev(7) to point out naming of rules files (LP: #616108)
  - cdrom_id: fix media state detection of DVD-RW/DVD+RWs (LP: #581925)
  - cdrom_id: fix media state detection on older hardware (LP: #502143)
* debian/libudev0.symbols: Add new symbols from upstream version.
* debian/udev.initramfs-hook: Drop 64-device-mapper.rules, it was removed
  upstream.
* debian/control: Drop obsolete (pre-lucid) Breaks and Conflicts.
* debian/rules: Replace obsolete dh_clean -k with dh_prep.
* debian/control: Slightly more generously version libselinux1-dev build
  dependency (thanks lintian).
* debian/control: Replace obsolete ${Source-Version} with ${binary:Version}.
* debian/control: Update Standards-Version to 3.9.1.
* debian/control: Add Homepage field.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * libudev - interface to udev device information
3
3
 *
4
 
 * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org>
 
4
 * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
5
5
 *
6
6
 * This library is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU Lesser General Public
13
13
#include <stdlib.h>
14
14
#include <stddef.h>
15
15
#include <unistd.h>
 
16
#include <stdbool.h>
16
17
#include <errno.h>
17
18
#include <string.h>
18
19
#include <dirent.h>
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;
63
65
        int event_timeout;
64
66
        int timeout;
65
 
        int num_fake_partitions;
66
67
        int devlink_priority;
67
68
        int refcount;
68
69
        dev_t devnum;
69
70
        int watch_handle;
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;
 
71
        int maj, min;
 
72
        bool parent_set;
 
73
        bool subsystem_set;
 
74
        bool devtype_set;
 
75
        bool devlinks_uptodate;
 
76
        bool envp_uptodate;
 
77
        bool tags_uptodate;
 
78
        bool driver_set;
 
79
        bool info_loaded;
 
80
        bool db_loaded;
 
81
        bool uevent_loaded;
78
82
};
79
83
 
 
84
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
 
85
{
 
86
        udev_device->envp_uptodate = false;
 
87
        if (value == NULL) {
 
88
                struct udev_list_entry *list_entry;
 
89
 
 
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);
 
94
                return NULL;
 
95
        }
 
96
        return udev_list_entry_add(udev_device->udev, &udev_device->properties_list, key, value, 1, 0);
 
97
}
 
98
 
 
99
static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
 
100
{
 
101
        char name[UTIL_LINE_SIZE];
 
102
        char *val;
 
103
 
 
104
        util_strscpy(name, sizeof(name), property);
 
105
        val = strchr(name, '=');
 
106
        if (val == NULL)
 
107
                return NULL;
 
108
        val[0] = '\0';
 
109
        val = &val[1];
 
110
        if (val[0] == '\0')
 
111
                val = NULL;
 
112
        return udev_device_add_property(udev_device, name, val);
 
113
}
 
114
 
 
115
/*
 
116
 * parse property string, and if needed, update internal values accordingly
 
117
 *
 
118
 * udev_device_add_property_from_string_parse_finish() needs to be
 
119
 * called after adding properties, and its return value checked
 
120
 *
 
121
 * udev_device_set_info_loaded() needs to be set, to avoid trying
 
122
 * to use a device without a DEVPATH set
 
123
 */
 
124
void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property)
 
125
{
 
126
        if (strncmp(property, "DEVPATH=", 8) == 0) {
 
127
                char path[UTIL_PATH_SIZE];
 
128
 
 
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]);
 
138
                else
 
139
                        udev_device_set_knodename(udev_device, &property[8]);
 
140
        } else if (strncmp(property, "DEVLINKS=", 9) == 0) {
 
141
                char devlinks[UTIL_PATH_SIZE];
 
142
                char *slink;
 
143
                char *next;
 
144
 
 
145
                util_strscpy(devlinks, sizeof(devlinks), &property[9]);
 
146
                slink = devlinks;
 
147
                next = strchr(slink, ' ');
 
148
                while (next != NULL) {
 
149
                        next[0] = '\0';
 
150
                        udev_device_add_devlink(udev_device, slink, 0);
 
151
                        slink = &next[1];
 
152
                        next = strchr(slink, ' ');
 
153
                }
 
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];
 
158
                char *next;
 
159
 
 
160
                util_strscpy(tags, sizeof(tags), &property[5]);
 
161
                next = strchr(tags, ':');
 
162
                if (next != NULL) {
 
163
                        next++;
 
164
                        while (next[0] != '\0') {
 
165
                                char *tag;
 
166
 
 
167
                                tag = next;
 
168
                                next = strchr(tag, ':');
 
169
                                if (next == NULL)
 
170
                                        break;
 
171
                                next[0] = '\0';
 
172
                                next++;
 
173
                                udev_device_add_tag(udev_device, tag);
 
174
                        }
 
175
                }
 
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));
 
190
        } else {
 
191
                udev_device_add_property_from_string(udev_device, property);
 
192
        }
 
193
}
 
194
 
 
195
int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device)
 
196
{
 
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;
 
201
 
 
202
        if (udev_device->devpath == NULL || udev_device->subsystem == NULL)
 
203
                return -EINVAL;
 
204
        return 0;
 
205
}
 
206
 
 
207
/**
 
208
 * udev_device_get_property_value:
 
209
 * @udev_device: udev device
 
210
 * @key: property name
 
211
 *
 
212
 * Returns: the value of a device property, or #NULL if there is no such property.
 
213
 **/
 
214
const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
 
215
{
 
216
        struct udev_list_entry *list_entry;
 
217
 
 
218
        if (udev_device == NULL)
 
219
                return NULL;
 
220
        if (key == NULL)
 
221
                return NULL;
 
222
 
 
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);
 
226
}
 
227
 
80
228
int udev_device_read_db(struct udev_device *udev_device)
81
229
{
82
230
        struct stat stats;
84
232
        char line[UTIL_LINE_SIZE];
85
233
        FILE *f;
86
234
 
 
235
        if (udev_device->db_loaded)
 
236
                return 0;
 
237
 
87
238
        util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/.udev/db/",
88
239
                      udev_device_get_subsystem(udev_device), ":", udev_device_get_sysname(udev_device), NULL);
89
240
 
98
249
                char *next;
99
250
 
100
251
                target_len = readlink(filename, target, sizeof(target));
101
 
                if (target_len > 0)
102
 
                        target[target_len] = '\0';
103
 
                else {
104
 
                        dbg(udev_device->udev, "error reading db link %s: %m\n", filename);
 
252
                if (target_len <= 0 || target_len == sizeof(target)) {
 
253
                        info(udev_device->udev, "error reading db link %s: %m\n", filename);
105
254
                        return -1;
106
255
                }
 
256
                target[target_len] = '\0';
107
257
 
108
258
                next = strchr(target, ' ');
109
259
                if (next != NULL) {
129
279
                return 0;
130
280
        }
131
281
 
132
 
        f = fopen(filename, "r");
 
282
        f = fopen(filename, "re");
133
283
        if (f == NULL) {
134
284
                dbg(udev_device->udev, "error reading db file %s: %m\n", filename);
135
285
                return -1;
136
286
        }
 
287
        udev_device->db_loaded = true;
 
288
 
137
289
        while (fgets(line, sizeof(line), f)) {
138
290
                ssize_t len;
139
291
                const char *val;
158
310
                case 'T':
159
311
                        udev_device_set_event_timeout(udev_device, atoi(val));
160
312
                        break;
161
 
                case 'A':
162
 
                        udev_device_set_num_fake_partitions(udev_device, atoi(val));
163
 
                        break;
164
 
                case 'R':
165
 
                        udev_device_set_ignore_remove(udev_device, atoi(val));
166
 
                        break;
167
313
                case 'E':
168
314
                        udev_device_add_property_from_string(udev_device, val);
169
315
                        break;
 
316
                case 'G':
 
317
                        udev_device_add_tag(udev_device, val);
 
318
                        break;
170
319
                case 'W':
171
320
                        udev_device_set_watch_handle(udev_device, atoi(val));
172
321
                        break;
186
335
        int maj = 0;
187
336
        int min = 0;
188
337
 
 
338
        if (udev_device->uevent_loaded)
 
339
                return 0;
 
340
 
189
341
        util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL);
190
 
        f = fopen(filename, "r");
 
342
        f = fopen(filename, "re");
191
343
        if (f == NULL)
192
344
                return -1;
 
345
        udev_device->uevent_loaded = true;
193
346
 
194
347
        while (fgets(line, sizeof(line), f)) {
195
348
                char *pos;
212
365
        }
213
366
 
214
367
        udev_device->devnum = makedev(maj, min);
215
 
 
216
368
        fclose(f);
217
369
        return 0;
218
370
}
219
371
 
220
 
static void device_load_info(struct udev_device *device)
221
 
{
222
 
        device->info_loaded = 1;
223
 
        udev_device_read_uevent_file(device);
224
 
        udev_device_read_db(device);
225
 
}
226
 
 
227
372
void udev_device_set_info_loaded(struct udev_device *device)
228
373
{
229
 
        device->info_loaded = 1;
 
374
        device->info_loaded = true;
230
375
}
231
376
 
232
377
struct udev_device *udev_device_new(struct udev *udev)
245
390
        udev_list_init(&udev_device->devlinks_list);
246
391
        udev_list_init(&udev_device->properties_list);
247
392
        udev_list_init(&udev_device->sysattr_list);
 
393
        udev_list_init(&udev_device->tags_list);
248
394
        udev_device->event_timeout = -1;
249
395
        udev_device->watch_handle = -1;
250
396
        /* copy global properties */
303
449
        util_strscpy(path, sizeof(path), syspath);
304
450
        util_resolve_sys_link(udev, path, sizeof(path));
305
451
 
306
 
        if (strncmp(&syspath[len], "/devices/", 9) == 0) {
 
452
        if (strncmp(&path[len], "/devices/", 9) == 0) {
307
453
                char file[UTIL_PATH_SIZE];
308
454
 
309
455
                /* all "devices" require a "uevent" file */
337
483
 * @devnum: device major/minor number
338
484
 *
339
485
 * Create new udev device, and fill in information from the sys
340
 
 * device and the udev database entry. The device is looked up
341
 
 * by its major/minor number. Character and block device numbers
342
 
 * are not unique across the two types, they do not share the same
343
 
 * range of numbers.
 
486
 * device and the udev database entry. The device is looked-up
 
487
 * by its major/minor number and type. Character and block device
 
488
 * numbers are not unique across the two types.
344
489
 *
345
490
 * The initial refcount is 1, and needs to be decremented to
346
491
 * release the resources of the udev device.
371
516
 * @subsystem: the subsystem of the device
372
517
 * @sysname: the name of the device
373
518
 *
374
 
 * Create new udev device, and fill in information from the sys
375
 
 * device and the udev database entry. The device is looked up
376
 
 * by the subsystem and name string of the device, like "mem",
377
 
 * "zero", or "block", "sda".
 
519
 * Create new udev device, and fill in information from the sys device
 
520
 * and the udev database entry. The device is looked up by the subsystem
 
521
 * and name string of the device, like "mem" / "zero", or "block" / "sda".
378
522
 *
379
523
 * The initial refcount is 1, and needs to be decremented to
380
524
 * release the resources of the udev device.
451
595
        return udev_device_new_from_syspath(udev, path_full);
452
596
}
453
597
 
 
598
/**
 
599
 * udev_device_new_from_environment
 
600
 * @udev: udev library context
 
601
 *
 
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.
 
606
 *
 
607
 * The initial refcount is 1, and needs to be decremented to
 
608
 * release the resources of the udev device.
 
609
 *
 
610
 * Returns: a new udev device, or #NULL, if it does not exist
 
611
 **/
 
612
struct udev_device *udev_device_new_from_environment(struct udev *udev)
 
613
{
 
614
        int i;
 
615
        struct udev_device *udev_device;
 
616
 
 
617
        udev_device = udev_device_new(udev);
 
618
        if (udev_device == NULL)
 
619
                return NULL;
 
620
        udev_device_set_info_loaded(udev_device);
 
621
 
 
622
        for (i = 0; environ[i] != NULL; i++)
 
623
                udev_device_add_property_from_string_parse(udev_device, environ[i]);
 
624
 
 
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);
 
628
                udev_device = NULL;
 
629
        }
 
630
 
 
631
        return udev_device;
 
632
}
 
633
 
454
634
static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
455
635
{
456
636
        struct udev_device *udev_device_parent = NULL;
497
677
        if (udev_device == NULL)
498
678
                return NULL;
499
679
        if (!udev_device->parent_set) {
500
 
                udev_device->parent_set = 1;
 
680
                udev_device->parent_set = true;
501
681
                udev_device->parent_device = device_new_from_parent(udev_device);
502
682
        }
503
683
        if (udev_device->parent_device != NULL)
607
787
        free(udev_device->devtype);
608
788
        udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
609
789
        udev_list_cleanup_entries(udev_device->udev, &udev_device->properties_list);
 
790
        udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list);
 
791
        udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
610
792
        free(udev_device->action);
611
793
        free(udev_device->driver);
612
794
        free(udev_device->devpath_old);
613
795
        free(udev_device->sysname_old);
614
796
        free(udev_device->knodename);
615
 
        udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list);
616
797
        free(udev_device->envp);
617
798
        free(udev_device->monitor_buf);
618
799
        dbg(udev_device->udev, "udev_device: %p released\n", udev_device);
691
872
        if (udev_device == NULL)
692
873
                return NULL;
693
874
        if (!udev_device->info_loaded)
694
 
                device_load_info(udev_device);
 
875
                udev_device_read_db(udev_device);
695
876
        return udev_device->devnode;
696
877
}
697
878
 
711
892
        if (udev_device == NULL)
712
893
                return NULL;
713
894
        if (!udev_device->subsystem_set) {
714
 
                udev_device->subsystem_set = 1;
 
895
                udev_device->subsystem_set = true;
715
896
                /* read "subsystem" link */
716
897
                if (util_get_sys_subsystem(udev_device->udev, udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
717
898
                        udev_device_set_subsystem(udev_device, subsystem);
749
930
        if (udev_device == NULL)
750
931
                return NULL;
751
932
        if (!udev_device->devtype_set) {
752
 
                udev_device->devtype_set = 1;
753
 
                if (!udev_device->info_loaded)
754
 
                        udev_device_read_uevent_file(udev_device);
 
933
                udev_device->devtype_set = true;
 
934
                udev_device_read_uevent_file(udev_device);
755
935
        }
756
936
        return udev_device->devtype;
757
937
}
774
954
        if (udev_device == NULL)
775
955
                return NULL;
776
956
        if (!udev_device->info_loaded)
777
 
                device_load_info(udev_device);
 
957
                udev_device_read_db(udev_device);
778
958
        return udev_list_get_entry(&udev_device->devlinks_list);
779
959
}
780
960
 
781
961
void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
782
962
{
783
 
        udev_device->devlinks_uptodate = 0;
 
963
        udev_device->devlinks_uptodate = false;
784
964
        udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
785
965
}
786
966
 
800
980
{
801
981
        if (udev_device == NULL)
802
982
                return NULL;
803
 
        if (!udev_device->info_loaded)
804
 
                device_load_info(udev_device);
 
983
        if (!udev_device->info_loaded) {
 
984
                udev_device_read_uevent_file(udev_device);
 
985
                udev_device_read_db(udev_device);
 
986
        }
805
987
        if (!udev_device->devlinks_uptodate) {
806
988
                char symlinks[UTIL_PATH_SIZE];
807
989
                struct udev_list_entry *list_entry;
808
990
 
809
 
                udev_device->devlinks_uptodate = 1;
 
991
                udev_device->devlinks_uptodate = true;
810
992
                list_entry = udev_device_get_devlinks_list_entry(udev_device);
811
993
                if (list_entry != NULL) {
812
994
                        char *s;
819
1001
                        udev_device_add_property(udev_device, "DEVLINKS", symlinks);
820
1002
                }
821
1003
        }
 
1004
        if (!udev_device->tags_uptodate) {
 
1005
                udev_device->tags_uptodate = true;
 
1006
                if (udev_device_get_tags_list_entry(udev_device) != NULL) {
 
1007
                        char tags[UTIL_PATH_SIZE];
 
1008
                        struct udev_list_entry *list_entry;
 
1009
                        char *s;
 
1010
                        size_t l;
 
1011
 
 
1012
                        s = tags;
 
1013
                        l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
 
1014
                        udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
 
1015
                                l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
 
1016
                        udev_device_add_property(udev_device, "TAGS", tags);
 
1017
                }
 
1018
        }
822
1019
        return udev_list_get_entry(&udev_device->properties_list);
823
1020
}
824
1021
 
835
1032
        if (udev_device == NULL)
836
1033
                return NULL;
837
1034
        if (!udev_device->driver_set) {
838
 
                udev_device->driver_set = 1;
 
1035
                udev_device->driver_set = true;
839
1036
                if (util_get_sys_driver(udev_device->udev, udev_device->syspath, driver, sizeof(driver)) > 0)
840
1037
                        udev_device->driver = strdup(driver);
841
1038
        }
853
1050
        if (udev_device == NULL)
854
1051
                return makedev(0, 0);
855
1052
        if (!udev_device->info_loaded)
856
 
                device_load_info(udev_device);
 
1053
                udev_device_read_uevent_file(udev_device);
857
1054
        return udev_device->devnum;
858
1055
}
859
1056
 
943
1140
                        goto out;
944
1141
 
945
1142
                len = readlink(path, target, sizeof(target));
946
 
                if (len > 0) {
947
 
                        target[len] = '\0';
948
 
                        pos = strrchr(target, '/');
949
 
                        if (pos != NULL) {
950
 
                                pos = &pos[1];
951
 
                                dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos);
952
 
                                list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0);
953
 
                                val = udev_list_entry_get_value(list_entry);
954
 
                        }
 
1143
                if (len <= 0 || len == sizeof(target))
 
1144
                        goto out;
 
1145
                target[len] = '\0';
 
1146
 
 
1147
                pos = strrchr(target, '/');
 
1148
                if (pos != NULL) {
 
1149
                        pos = &pos[1];
 
1150
                        dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos);
 
1151
                        list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0);
 
1152
                        val = udev_list_entry_get_value(list_entry);
955
1153
                }
 
1154
 
956
1155
                goto out;
957
1156
        }
958
1157
 
965
1164
                goto out;
966
1165
 
967
1166
        /* read attribute value */
968
 
        fd = open(path, O_RDONLY);
 
1167
        fd = open(path, O_RDONLY|O_CLOEXEC);
969
1168
        if (fd < 0) {
970
1169
                dbg(udev_device->udev, "attribute '%s' can not be opened\n", path);
971
1170
                goto out;
1031
1230
        udev_device->subsystem = strdup(subsystem);
1032
1231
        if (udev_device->subsystem == NULL)
1033
1232
                return -ENOMEM;
1034
 
        udev_device->subsystem_set = 1;
 
1233
        udev_device->subsystem_set = true;
1035
1234
        udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
1036
1235
        return 0;
1037
1236
}
1042
1241
        udev_device->devtype = strdup(devtype);
1043
1242
        if (udev_device->devtype == NULL)
1044
1243
                return -ENOMEM;
1045
 
        udev_device->devtype_set = 1;
 
1244
        udev_device->devtype_set = true;
1046
1245
        udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
1047
1246
        return 0;
1048
1247
}
1063
1262
{
1064
1263
        struct udev_list_entry *list_entry;
1065
1264
 
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;
1070
1269
        if (unique)
1071
 
                udev_list_entry_set_flag(list_entry, 1);
 
1270
                udev_list_entry_set_flags(list_entry, 1);
1072
1271
        return 0;
1073
1272
}
1074
1273
 
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)
1076
1275
{
1077
 
        udev_device->envp_uptodate = 0;
1078
 
        if (value == NULL) {
1079
 
                struct udev_list_entry *list_entry;
1080
 
 
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);
1085
 
                return NULL;
1086
 
        }
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)
 
1277
                return -EINVAL;
 
1278
        udev_device->tags_uptodate = false;
 
1279
        if (udev_list_entry_add(udev_device->udev, &udev_device->tags_list, tag, NULL, 1, 0) != NULL)
 
1280
                return 0;
 
1281
        return -ENOMEM;
1088
1282
}
1089
1283
 
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)
1091
1285
{
1092
 
        char name[UTIL_PATH_SIZE];
1093
 
        char *val;
1094
 
 
1095
 
        util_strscpy(name, sizeof(name), property);
1096
 
        val = strchr(name, '=');
1097
 
        if (val == NULL)
1098
 
                return NULL;
1099
 
        val[0] = '\0';
1100
 
        val = &val[1];
1101
 
        if (val[0] == '\0')
1102
 
                val = NULL;
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);
1104
1288
}
1105
1289
 
1106
1290
/**
1107
 
 * udev_device_get_property_value:
 
1291
 * udev_device_get_tags_list_entry:
1108
1292
 * @udev_device: udev device
1109
 
 * @key: property name
1110
 
 *
1111
 
 * Returns: the value of a device property, or #NULL if there is no such property.
 
1293
 *
 
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().
 
1298
 *
 
1299
 * Returns: the first entry of the tag list
1112
1300
 **/
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)
 
1302
{
 
1303
        if (udev_device == NULL)
 
1304
                return NULL;
 
1305
        return udev_list_get_entry(&udev_device->tags_list);
 
1306
}
 
1307
 
 
1308
int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
1114
1309
{
1115
1310
        struct udev_list_entry *list_entry;
1116
1311
 
1117
 
        if (udev_device == NULL)
1118
 
                return NULL;
1119
 
        if (key == NULL)
1120
 
                return NULL;
1121
 
 
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)
 
1317
                return 1;
 
1318
        return 0;
1125
1319
}
1126
1320
 
1127
1321
#define ENVP_SIZE                       128
1172
1366
        }
1173
1367
        udev_device->envp[i] = NULL;
1174
1368
        udev_device->monitor_buf_len = s - udev_device->monitor_buf;
1175
 
        udev_device->envp_uptodate = 1;
 
1369
        udev_device->envp_uptodate = true;
1176
1370
        dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n",
1177
1371
            i, udev_device->monitor_buf_len);
1178
1372
        return 0;
1211
1405
        udev_device->driver = strdup(driver);
1212
1406
        if (udev_device->driver == NULL)
1213
1407
                return -ENOMEM;
1214
 
        udev_device->driver_set = 1;
 
1408
        udev_device->driver_set = true;
1215
1409
        udev_device_add_property(udev_device, "DRIVER", udev_device->driver);
1216
1410
        return 0;
1217
1411
}
1284
1478
int udev_device_get_event_timeout(struct udev_device *udev_device)
1285
1479
{
1286
1480
        if (!udev_device->info_loaded)
1287
 
                device_load_info(udev_device);
 
1481
                udev_device_read_db(udev_device);
1288
1482
        return udev_device->event_timeout;
1289
1483
}
1290
1484
 
1317
1511
        return 0;
1318
1512
}
1319
1513
 
1320
 
int udev_device_get_num_fake_partitions(struct udev_device *udev_device)
1321
 
{
1322
 
        if (!udev_device->info_loaded)
1323
 
                device_load_info(udev_device);
1324
 
        return udev_device->num_fake_partitions;
1325
 
}
1326
 
 
1327
 
int udev_device_set_num_fake_partitions(struct udev_device *udev_device, int num)
1328
 
{
1329
 
        udev_device->num_fake_partitions = num;
1330
 
        return 0;
1331
 
}
1332
 
 
1333
1514
int udev_device_get_devlink_priority(struct udev_device *udev_device)
1334
1515
{
1335
1516
        if (!udev_device->info_loaded)
1336
 
                device_load_info(udev_device);
 
1517
                udev_device_read_db(udev_device);
1337
1518
        return udev_device->devlink_priority;
1338
1519
}
1339
1520
 
1343
1524
        return 0;
1344
1525
}
1345
1526
 
1346
 
int udev_device_get_ignore_remove(struct udev_device *udev_device)
1347
 
{
1348
 
        if (!udev_device->info_loaded)
1349
 
                device_load_info(udev_device);
1350
 
        return udev_device->ignore_remove;
1351
 
}
1352
 
 
1353
 
int udev_device_set_ignore_remove(struct udev_device *udev_device, int ignore)
1354
 
{
1355
 
        udev_device->ignore_remove = ignore;
1356
 
        return 0;
1357
 
}
1358
 
 
1359
1527
int udev_device_get_watch_handle(struct udev_device *udev_device)
1360
1528
{
1361
1529
        if (!udev_device->info_loaded)
1362
 
                device_load_info(udev_device);
 
1530
                udev_device_read_db(udev_device);
1363
1531
        return udev_device->watch_handle;
1364
1532
}
1365
1533