• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 23966986054

03 Apr 2026 09:22PM UTC coverage: 72.107% (-0.3%) from 72.362%
23966986054

push

github

daandemeyer
fd-util: Add missing assert()

1 of 1 new or added line in 1 file covered. (100.0%)

7891 existing lines in 120 files now uncovered.

318256 of 441368 relevant lines covered (72.11%)

1186882.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.44
/src/basic/devnum-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <string.h>
4
#include <sys/stat.h>
5
#include <sys/sysmacros.h>
6

7
#include "alloc-util.h"
8
#include "chase.h"
9
#include "devnum-util.h"
10
#include "parse-util.h"
11
#include "path-util.h"
12
#include "stdio-util.h"
13
#include "string-util.h"
14

15
int parse_devnum(const char *s, dev_t *ret) {
15,609✔
16
        const char *major;
15,609✔
17
        unsigned x, y;
15,609✔
18
        size_t n;
15,609✔
19
        int r;
15,609✔
20

21
        assert(ret);
15,609✔
22

23
        n = strspn(s, DIGITS);
15,609✔
24
        if (n == 0)
15,609✔
25
                return -EINVAL;
15,609✔
26
        if (n > DECIMAL_STR_MAX(dev_t))
15,605✔
27
                return -EINVAL;
28
        if (s[n] != ':')
15,605✔
29
                return -EINVAL;
30

31
        major = strndupa_safe(s, n);
15,603✔
32
        r = safe_atou(major, &x);
15,603✔
33
        if (r < 0)
15,603✔
34
                return r;
35

36
        r = safe_atou(s + n + 1, &y);
15,603✔
37
        if (r < 0)
15,603✔
38
                return r;
39

40
        if (!DEVICE_MAJOR_VALID(x) || !DEVICE_MINOR_VALID(y))
15,602✔
41
                return -ERANGE;
42

43
        *ret = makedev(x, y);
31,204✔
44
        return 0;
15,602✔
45
}
46

47
int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret) {
53,424✔
48
        const char *t;
53,424✔
49

50
        /* Generates the /dev/{char|block}/MAJOR:MINOR path for a dev_t */
51

52
        if (S_ISCHR(mode))
53,424✔
53
                t = "char";
54
        else if (S_ISBLK(mode))
40,762✔
55
                t = "block";
56
        else
57
                return -ENODEV;
58

59
        if (asprintf(ret, "/dev/%s/" DEVNUM_FORMAT_STR, t, DEVNUM_FORMAT_VAL(devnum)) < 0)
53,424✔
UNCOV
60
                return -ENOMEM;
×
61

62
        return 0;
63
}
64

65
int device_path_make_inaccessible(mode_t mode, char **ret) {
10✔
66
        const char *s;
10✔
67

68
        assert(ret);
10✔
69

70
        if (S_ISCHR(mode))
10✔
71
                s = "/run/systemd/inaccessible/chr";
72
        else if (S_ISBLK(mode))
5✔
73
                s = "/run/systemd/inaccessible/blk";
74
        else
75
                return -ENODEV;
76

77
        return strdup_to(ret, s);
10✔
78
}
79

80
int device_path_make_canonical(mode_t mode, dev_t devnum, char **ret) {
15✔
81
        _cleanup_free_ char *p = NULL;
15✔
82
        int r;
15✔
83

84
        /* Finds the canonical path for a device, i.e. resolves the /dev/{char|block}/MAJOR:MINOR path to the end. */
85

86
        assert(ret);
15✔
87

88
        if (devnum_is_zero(devnum))
15✔
89
                /* A special hack to make sure our 'inaccessible' device nodes work. They won't have symlinks in
90
                 * /dev/block/ and /dev/char/, hence we handle them specially here. */
91
                return device_path_make_inaccessible(mode, ret);
2✔
92

93
        r = device_path_make_major_minor(mode, devnum, &p);
13✔
94
        if (r < 0)
13✔
95
                return r;
96

97
        return chase(p, NULL, 0, ret, NULL);
13✔
98
}
99

100
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devnum) {
254,328✔
101
        mode_t mode;
254,328✔
102
        dev_t devnum;
254,328✔
103
        int r;
254,328✔
104

105
        /* Tries to extract the major/minor directly from the device path if we can. Handles /dev/block/ and /dev/char/
106
         * paths, as well out synthetic inaccessible device nodes. Never goes to disk. Returns -ENODEV if the device
107
         * path cannot be parsed like this.  */
108

109
        if (path_equal(path, "/run/systemd/inaccessible/chr")) {
254,328✔
110
                mode = S_IFCHR;
844✔
111
                devnum = makedev(0, 0);
844✔
112
        } else if (path_equal(path, "/run/systemd/inaccessible/blk")) {
253,484✔
113
                mode = S_IFBLK;
844✔
114
                devnum = makedev(0, 0);
844✔
115
        } else {
116
                const char *w;
252,640✔
117

118
                w = path_startswith(path, "/dev/block/");
252,640✔
119
                if (w)
252,640✔
120
                        mode = S_IFBLK;
121
                else {
122
                        w = path_startswith(path, "/dev/char/");
252,619✔
123
                        if (!w)
252,619✔
124
                                return -ENODEV;
254,328✔
125

126
                        mode = S_IFCHR;
127
                }
128

129
                r = parse_devnum(w, &devnum);
712✔
130
                if (r < 0)
712✔
131
                        return r;
132
        }
133

134
        if (ret_mode)
2,400✔
135
                *ret_mode = mode;
2,400✔
136
        if (ret_devnum)
2,400✔
137
                *ret_devnum = devnum;
2,400✔
138

139
        return 0;
140
}
141

142
char* format_devnum(dev_t d, char buf[static DEVNUM_STR_MAX]) {
4,861✔
143
        return ASSERT_PTR(snprintf_ok(buf, DEVNUM_STR_MAX, DEVNUM_FORMAT_STR, DEVNUM_FORMAT_VAL(d)));
4,861✔
144
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc