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

systemd / systemd / 14939761809

09 May 2025 06:22PM UTC coverage: 72.251% (-0.001%) from 72.252%
14939761809

push

github

web-flow
mount-tool: honor arg_canonicalize for ACTION_UMOUNT path_is_absolute() check too (#37398)

Split out from #36337

4 of 4 new or added lines in 2 files covered. (100.0%)

3591 existing lines in 114 files now uncovered.

297546 of 411820 relevant lines covered (72.25%)

704170.35 hits per line

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

98.36
/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 "string-util.h"
13

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

20
        n = strspn(s, DIGITS);
11,779✔
21
        if (n == 0)
11,779✔
22
                return -EINVAL;
11,779✔
23
        if (n > DECIMAL_STR_MAX(dev_t))
11,775✔
24
                return -EINVAL;
25
        if (s[n] != ':')
11,775✔
26
                return -EINVAL;
27

28
        major = strndupa_safe(s, n);
11,773✔
29
        r = safe_atou(major, &x);
11,773✔
30
        if (r < 0)
11,773✔
31
                return r;
32

33
        r = safe_atou(s + n + 1, &y);
11,773✔
34
        if (r < 0)
11,773✔
35
                return r;
36

37
        if (!DEVICE_MAJOR_VALID(x) || !DEVICE_MINOR_VALID(y))
11,772✔
38
                return -ERANGE;
39

40
        *ret = makedev(x, y);
11,772✔
41
        return 0;
11,772✔
42
}
43

44
int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret) {
53,887✔
45
        const char *t;
53,887✔
46

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

49
        if (S_ISCHR(mode))
53,887✔
50
                t = "char";
51
        else if (S_ISBLK(mode))
40,683✔
52
                t = "block";
53
        else
54
                return -ENODEV;
55

56
        if (asprintf(ret, "/dev/%s/" DEVNUM_FORMAT_STR, t, DEVNUM_FORMAT_VAL(devnum)) < 0)
53,887✔
UNCOV
57
                return -ENOMEM;
×
58

59
        return 0;
60
}
61

62
int device_path_make_inaccessible(mode_t mode, char **ret) {
6✔
63
        const char *s;
6✔
64

65
        assert(ret);
6✔
66

67
        if (S_ISCHR(mode))
6✔
68
                s = "/run/systemd/inaccessible/chr";
69
        else if (S_ISBLK(mode))
3✔
70
                s = "/run/systemd/inaccessible/blk";
71
        else
72
                return -ENODEV;
73

74
        return strdup_to(ret, s);
6✔
75
}
76

77
int device_path_make_canonical(mode_t mode, dev_t devnum, char **ret) {
15✔
78
        _cleanup_free_ char *p = NULL;
15✔
79
        int r;
15✔
80

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

83
        assert(ret);
15✔
84

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

90
        r = device_path_make_major_minor(mode, devnum, &p);
13✔
91
        if (r < 0)
13✔
92
                return r;
93

94
        return chase(p, NULL, 0, ret, NULL);
13✔
95
}
96

97
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devnum) {
312,068✔
98
        mode_t mode;
312,068✔
99
        dev_t devnum;
312,068✔
100
        int r;
312,068✔
101

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

106
        if (path_equal(path, "/run/systemd/inaccessible/chr")) {
312,068✔
107
                mode = S_IFCHR;
155✔
108
                devnum = makedev(0, 0);
155✔
109
        } else if (path_equal(path, "/run/systemd/inaccessible/blk")) {
311,913✔
110
                mode = S_IFBLK;
155✔
111
                devnum = makedev(0, 0);
155✔
112
        } else {
113
                const char *w;
311,758✔
114

115
                w = path_startswith(path, "/dev/block/");
311,758✔
116
                if (w)
311,758✔
117
                        mode = S_IFBLK;
118
                else {
119
                        w = path_startswith(path, "/dev/char/");
311,743✔
120
                        if (!w)
311,743✔
121
                                return -ENODEV;
312,068✔
122

123
                        mode = S_IFCHR;
124
                }
125

126
                r = parse_devnum(w, &devnum);
368✔
127
                if (r < 0)
368✔
128
                        return r;
129
        }
130

131
        if (ret_mode)
678✔
132
                *ret_mode = mode;
678✔
133
        if (ret_devnum)
678✔
134
                *ret_devnum = devnum;
678✔
135

136
        return 0;
137
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc