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

systemd / systemd / 19996191435

06 Dec 2025 12:24AM UTC coverage: 72.546% (-0.2%) from 72.765%
19996191435

push

github

web-flow
Add 82-net-auto-link-local.{hwdb,rules} to build system and add BMC USB-to-USB links to hwdb (#40006)

Using systems with ADLINK COM-HPC-ALT, ASRock Rack ALTRAD8UD-1L2T and
AMPONED8-2T/BCM boards, there's an issue due to the internal network
connection between the BMC and host, which runs over USB (i.e. Linux
running on the BMC configures a USB gadget ethernet device, with a link
local address).

With the default configuration on Ubuntu (I'm using 25.10),
NetworkManager repeatedly tries to get an address for the interface
using DHCP, resulting in an "Activation of network connection failed"
notification every minute or two.

Add 82-net-auto-link-local.hwdb and 82-net-auto-link-local.rules to the
build system and update 82-net-auto-link-local.hwdb to add the USB
device vendor/product pairs I've seen on the various systems I have with
Ampere Altra and AmpereOne CPUs.

308773 of 425625 relevant lines covered (72.55%)

1159320.34 hits per line

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

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

3
#include <linux/oom.h>
4
#include <pthread.h>
5
#include <spawn.h>
6
#include <stdio.h>
7
#include <sys/mount.h>
8
#include <sys/personality.h>
9
#include <sys/prctl.h>
10
#include <sys/wait.h>
11
#include <syslog.h>
12
#include <threads.h>
13
#include <unistd.h>
14
#if HAVE_VALGRIND_VALGRIND_H
15
#include <valgrind/valgrind.h>
16
#endif
17

18
#include "sd-messages.h"
19

20
#include "alloc-util.h"
21
#include "architecture.h"
22
#include "argv-util.h"
23
#include "cgroup-util.h"
24
#include "dirent-util.h"
25
#include "dlfcn-util.h"
26
#include "env-file.h"
27
#include "errno-util.h"
28
#include "escape.h"
29
#include "fd-util.h"
30
#include "fileio.h"
31
#include "fs-util.h"
32
#include "hostname-util.h"
33
#include "io-util.h"
34
#include "iovec-util.h"
35
#include "locale-util.h"
36
#include "log.h"
37
#include "memory-util.h"
38
#include "mountpoint-util.h"
39
#include "namespace-util.h"
40
#include "nulstr-util.h"
41
#include "parse-util.h"
42
#include "path-util.h"
43
#include "pidfd-util.h"
44
#include "pidref.h"
45
#include "process-util.h"
46
#include "raw-clone.h"
47
#include "rlimit-util.h"
48
#include "signal-util.h"
49
#include "socket-util.h"
50
#include "stat-util.h"
51
#include "stdio-util.h"
52
#include "string-table.h"
53
#include "string-util.h"
54
#include "time-util.h"
55
#include "user-util.h"
56

57
/* The kernel limits userspace processes to TASK_COMM_LEN (16 bytes), but allows higher values for its own
58
 * workers, e.g. "kworker/u9:3-kcryptd/253:0". Let's pick a fixed smallish limit that will work for the kernel.
59
 */
60
#define COMM_MAX_LEN 128
61

62
static int get_process_state(pid_t pid) {
12,975✔
63
        _cleanup_free_ char *line = NULL;
12,975✔
64
        const char *p;
12,975✔
65
        char state;
12,975✔
66
        int r;
12,975✔
67

68
        assert(pid >= 0);
12,975✔
69

70
        /* Shortcut: if we are enquired about our own state, we are obviously running */
71
        if (pid == 0 || pid == getpid_cached())
12,975✔
72
                return (unsigned char) 'R';
×
73

74
        p = procfs_file_alloca(pid, "stat");
12,975✔
75

76
        r = read_one_line_file(p, &line);
12,975✔
77
        if (r == -ENOENT)
12,975✔
78
                return -ESRCH;
79
        if (r < 0)
10,178✔
80
                return r;
81

82
        p = strrchr(line, ')');
10,178✔
83
        if (!p)
10,178✔
84
                return -EIO;
85

86
        p++;
10,178✔
87

88
        if (sscanf(p, " %c", &state) != 1)
10,178✔
89
                return -EIO;
90

91
        return (unsigned char) state;
10,178✔
92
}
93

94
int pid_get_comm(pid_t pid, char **ret) {
43,490✔
95
        _cleanup_free_ char *escaped = NULL, *comm = NULL;
43,490✔
96
        int r;
43,490✔
97

98
        assert(pid >= 0);
43,490✔
99
        assert(ret);
43,490✔
100

101
        if (pid == 0 || pid == getpid_cached()) {
43,490✔
102
                comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */
23,779✔
103
                if (!comm)
23,779✔
104
                        return -ENOMEM;
105

106
                if (prctl(PR_GET_NAME, comm) < 0)
23,779✔
107
                        return -errno;
×
108
        } else {
109
                const char *p;
19,711✔
110

111
                p = procfs_file_alloca(pid, "comm");
19,711✔
112

113
                /* Note that process names of kernel threads can be much longer than TASK_COMM_LEN */
114
                r = read_one_line_file(p, &comm);
19,711✔
115
                if (r == -ENOENT)
19,711✔
116
                        return -ESRCH;
117
                if (r < 0)
16,227✔
118
                        return r;
119
        }
120

121
        escaped = new(char, COMM_MAX_LEN);
40,004✔
122
        if (!escaped)
40,004✔
123
                return -ENOMEM;
124

125
        /* Escape unprintable characters, just in case, but don't grow the string beyond the underlying size */
126
        cellescape(escaped, COMM_MAX_LEN, comm);
40,004✔
127

128
        *ret = TAKE_PTR(escaped);
40,004✔
129
        return 0;
40,004✔
130
}
131

132
int pidref_get_comm(const PidRef *pid, char **ret) {
157✔
133
        _cleanup_free_ char *comm = NULL;
157✔
134
        int r;
157✔
135

136
        if (!pidref_is_set(pid))
157✔
137
                return -ESRCH;
138

139
        if (pidref_is_remote(pid))
314✔
140
                return -EREMOTE;
141

142
        r = pid_get_comm(pid->pid, &comm);
157✔
143
        if (r < 0)
157✔
144
                return r;
145

146
        r = pidref_verify(pid);
157✔
147
        if (r < 0)
157✔
148
                return r;
149

150
        if (ret)
157✔
151
                *ret = TAKE_PTR(comm);
157✔
152
        return 0;
153
}
154

155
static int pid_get_cmdline_nulstr(
18,573✔
156
                pid_t pid,
157
                size_t max_size,
158
                ProcessCmdlineFlags flags,
159
                char **ret,
160
                size_t *ret_size) {
161

162
        _cleanup_free_ char *t = NULL;
18,573✔
163
        const char *p;
18,573✔
164
        size_t k;
18,573✔
165
        int r;
18,573✔
166

167
        /* Retrieves a process' command line as a "sized nulstr", i.e. possibly without the last NUL, but
168
         * with a specified size.
169
         *
170
         * If PROCESS_CMDLINE_COMM_FALLBACK is specified in flags and the process has no command line set
171
         * (the case for kernel threads), or has a command line that resolves to the empty string, will
172
         * return the "comm" name of the process instead. This will use at most _SC_ARG_MAX bytes of input
173
         * data.
174
         *
175
         * Returns an error, 0 if output was read but is truncated, 1 otherwise.
176
         */
177

178
        p = procfs_file_alloca(pid, "cmdline");
18,789✔
179
        r = read_virtual_file(p, max_size, &t, &k); /* Let's assume that each input byte results in >= 1
18,573✔
180
                                                     * columns of output. We ignore zero-width codepoints. */
181
        if (r == -ENOENT)
18,573✔
182
                return -ESRCH;
183
        if (r < 0)
14,989✔
184
                return r;
185

186
        if (k == 0) {
14,986✔
187
                if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
385✔
188
                        return -ENOENT;
362✔
189

190
                /* Kernel threads have no argv[] */
191
                _cleanup_free_ char *comm = NULL;
23✔
192

193
                r = pid_get_comm(pid, &comm);
23✔
194
                if (r < 0)
23✔
195
                        return r;
196

197
                free(t);
23✔
198
                t = strjoin("[", comm, "]");
23✔
199
                if (!t)
23✔
200
                        return -ENOMEM;
201

202
                k = strlen(t);
23✔
203
                r = k <= max_size;
23✔
204
                if (r == 0) /* truncation */
23✔
205
                        t[max_size] = '\0';
12✔
206
        }
207

208
        if (ret)
14,624✔
209
                *ret = TAKE_PTR(t);
14,624✔
210
        if (ret_size)
14,624✔
211
                *ret_size = k;
14,624✔
212

213
        return r;
214
}
215

216
int pid_get_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
13,915✔
217
        _cleanup_free_ char *t = NULL;
13,915✔
218
        size_t k;
13,915✔
219
        char *ans;
13,915✔
220

221
        assert(pid >= 0);
13,915✔
222
        assert(ret);
13,915✔
223

224
        /* Retrieve and format a command line. See above for discussion of retrieval options.
225
         *
226
         * There are two main formatting modes:
227
         *
228
         * - when PROCESS_CMDLINE_QUOTE is specified, output is quoted in C/Python style. If no shell special
229
         *   characters are present, this output can be copy-pasted into the terminal to execute. UTF-8
230
         *   output is assumed.
231
         *
232
         * - otherwise, a compact non-roundtrippable form is returned. Non-UTF8 bytes are replaced by �. The
233
         *   returned string is of the specified console width at most, abbreviated with an ellipsis.
234
         *
235
         * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
236
         * PROCESS_CMDLINE_COMM_FALLBACK is not specified). Returns 0 and sets *line otherwise. */
237

238
        int full = pid_get_cmdline_nulstr(pid, max_columns, flags, &t, &k);
13,915✔
239
        if (full < 0)
13,915✔
240
                return full;
241

242
        if (flags & (PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_QUOTE_POSIX)) {
10,043✔
243
                ShellEscapeFlags shflags = SHELL_ESCAPE_EMPTY |
9,672✔
244
                        FLAGS_SET(flags, PROCESS_CMDLINE_QUOTE_POSIX) * SHELL_ESCAPE_POSIX;
9,672✔
245

246
                assert(!(flags & PROCESS_CMDLINE_USE_LOCALE));
9,672✔
247

248
                _cleanup_strv_free_ char **args = NULL;
9,672✔
249

250
                /* Drop trailing NULs, otherwise strv_parse_nulstr() adds additional empty strings at the end.
251
                 * See also issue #21186. */
252
                args = strv_parse_nulstr_full(t, k, /* drop_trailing_nuls = */ true);
9,672✔
253
                if (!args)
9,672✔
254
                        return -ENOMEM;
255

256
                ans = quote_command_line(args, shflags);
9,672✔
257
                if (!ans)
9,672✔
258
                        return -ENOMEM;
259
        } else {
260
                /* Arguments are separated by NULs. Let's replace those with spaces. */
261
                for (size_t i = 0; i < k - 1; i++)
17,985✔
262
                        if (t[i] == '\0')
17,614✔
263
                                t[i] = ' ';
648✔
264

265
                delete_trailing_chars(t, WHITESPACE);
371✔
266

267
                bool eight_bit = (flags & PROCESS_CMDLINE_USE_LOCALE) && !is_locale_utf8();
371✔
268

269
                ans = escape_non_printable_full(t, max_columns,
1,113✔
270
                                                eight_bit * XESCAPE_8_BIT | !full * XESCAPE_FORCE_ELLIPSIS);
688✔
271
                if (!ans)
371✔
272
                        return -ENOMEM;
273

274
                ans = str_realloc(ans);
371✔
275
        }
276

277
        *ret = ans;
10,043✔
278
        return 0;
10,043✔
279
}
280

281
int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
46✔
282
        _cleanup_free_ char *s = NULL;
46✔
283
        int r;
46✔
284

285
        if (!pidref_is_set(pid))
46✔
286
                return -ESRCH;
287

288
        if (pidref_is_remote(pid))
92✔
289
                return -EREMOTE;
290

291
        r = pid_get_cmdline(pid->pid, max_columns, flags, &s);
46✔
292
        if (r < 0)
46✔
293
                return r;
294

295
        r = pidref_verify(pid);
46✔
296
        if (r < 0)
46✔
297
                return r;
298

299
        if (ret)
46✔
300
                *ret = TAKE_PTR(s);
46✔
301
        return 0;
302
}
303

304
int pid_get_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret) {
4,658✔
305
        _cleanup_free_ char *t = NULL;
4,658✔
306
        char **args;
4,658✔
307
        size_t k;
4,658✔
308
        int r;
4,658✔
309

310
        assert(pid >= 0);
4,658✔
311
        assert((flags & ~PROCESS_CMDLINE_COMM_FALLBACK) == 0);
4,658✔
312
        assert(ret);
4,658✔
313

314
        r = pid_get_cmdline_nulstr(pid, SIZE_MAX, flags, &t, &k);
4,658✔
315
        if (r < 0)
4,658✔
316
                return r;
317

318
        args = strv_parse_nulstr_full(t, k, /* drop_trailing_nuls = */ true);
4,581✔
319
        if (!args)
4,581✔
320
                return -ENOMEM;
321

322
        *ret = args;
4,581✔
323
        return 0;
4,581✔
324
}
325

326
int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char ***ret) {
×
327
        _cleanup_strv_free_ char **args = NULL;
×
328
        int r;
×
329

330
        if (!pidref_is_set(pid))
×
331
                return -ESRCH;
332

333
        if (pidref_is_remote(pid))
×
334
                return -EREMOTE;
335

336
        r = pid_get_cmdline_strv(pid->pid, flags, &args);
×
337
        if (r < 0)
×
338
                return r;
339

340
        r = pidref_verify(pid);
×
341
        if (r < 0)
×
342
                return r;
343

344
        if (ret)
×
345
                *ret = TAKE_PTR(args);
×
346

347
        return 0;
348
}
349

350
int container_get_leader(const char *machine, pid_t *pid) {
35✔
351
        _cleanup_free_ char *s = NULL, *class = NULL;
35✔
352
        const char *p;
35✔
353
        pid_t leader;
35✔
354
        int r;
35✔
355

356
        assert(machine);
35✔
357
        assert(pid);
35✔
358

359
        if (streq(machine, ".host")) {
35✔
360
                *pid = 1;
1✔
361
                return 0;
1✔
362
        }
363

364
        if (!hostname_is_valid(machine, 0))
34✔
365
                return -EINVAL;
366

367
        p = strjoina("/run/systemd/machines/", machine);
170✔
368
        r = parse_env_file(NULL, p,
34✔
369
                           "LEADER", &s,
370
                           "CLASS", &class);
371
        if (r == -ENOENT)
34✔
372
                return -EHOSTDOWN;
373
        if (r < 0)
34✔
374
                return r;
375
        if (!s)
34✔
376
                return -EIO;
377

378
        if (!streq_ptr(class, "container"))
34✔
379
                return -EIO;
380

381
        r = parse_pid(s, &leader);
34✔
382
        if (r < 0)
34✔
383
                return r;
384
        if (leader <= 1)
34✔
385
                return -EIO;
386

387
        *pid = leader;
34✔
388
        return 0;
34✔
389
}
390

391
int pid_is_kernel_thread(pid_t pid) {
3,915✔
392
        _cleanup_free_ char *line = NULL;
3,915✔
393
        unsigned long long flags;
3,915✔
394
        size_t l, i;
3,915✔
395
        const char *p;
3,915✔
396
        char *q;
3,915✔
397
        int r;
3,915✔
398

399
        if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
3,915✔
400
                return 0;
25✔
401
        if (!pid_is_valid(pid))
3,890✔
402
                return -EINVAL;
403

404
        p = procfs_file_alloca(pid, "stat");
3,890✔
405
        r = read_one_line_file(p, &line);
3,890✔
406
        if (r == -ENOENT)
3,890✔
407
                return -ESRCH;
408
        if (r < 0)
3,890✔
409
                return r;
410

411
        /* Skip past the comm field */
412
        q = strrchr(line, ')');
3,890✔
413
        if (!q)
3,890✔
414
                return -EINVAL;
415
        q++;
3,890✔
416

417
        /* Skip 6 fields to reach the flags field */
418
        for (i = 0; i < 6; i++) {
27,230✔
419
                l = strspn(q, WHITESPACE);
23,340✔
420
                if (l < 1)
23,340✔
421
                        return -EINVAL;
422
                q += l;
23,340✔
423

424
                l = strcspn(q, WHITESPACE);
23,340✔
425
                if (l < 1)
23,340✔
426
                        return -EINVAL;
427
                q += l;
23,340✔
428
        }
429

430
        /* Skip preceding whitespace */
431
        l = strspn(q, WHITESPACE);
3,890✔
432
        if (l < 1)
3,890✔
433
                return -EINVAL;
434
        q += l;
3,890✔
435

436
        /* Truncate the rest */
437
        l = strcspn(q, WHITESPACE);
3,890✔
438
        if (l < 1)
3,890✔
439
                return -EINVAL;
440
        q[l] = 0;
3,890✔
441

442
        r = safe_atollu(q, &flags);
3,890✔
443
        if (r < 0)
3,890✔
444
                return r;
445

446
        return !!(flags & PF_KTHREAD);
3,890✔
447
}
448

449
int pidref_is_kernel_thread(const PidRef *pid) {
1,650✔
450
        int result, r;
1,650✔
451

452
        if (!pidref_is_set(pid))
1,650✔
453
                return -ESRCH;
454

455
        if (pidref_is_remote(pid))
1,650✔
456
                return -EREMOTE;
457

458
        result = pid_is_kernel_thread(pid->pid);
1,650✔
459
        if (result < 0)
1,650✔
460
                return result;
461

462
        r = pidref_verify(pid); /* Verify that the PID wasn't reused since */
1,650✔
463
        if (r < 0)
1,650✔
464
                return r;
×
465

466
        return result;
467
}
468

469
static int get_process_link_contents(pid_t pid, const char *proc_file, char **ret) {
13,375✔
470
        const char *p;
13,375✔
471
        int r;
13,375✔
472

473
        assert(proc_file);
13,375✔
474

475
        p = procfs_file_alloca(pid, proc_file);
13,379✔
476

477
        r = readlink_malloc(p, ret);
13,375✔
478
        return (r == -ENOENT && proc_mounted() > 0) ? -ESRCH : r;
13,375✔
479
}
480

481
int get_process_exe(pid_t pid, char **ret) {
13,349✔
482
        char *d;
13,349✔
483
        int r;
13,349✔
484

485
        assert(pid >= 0);
13,349✔
486

487
        r = get_process_link_contents(pid, "exe", ret);
13,349✔
488
        if (r < 0)
13,349✔
489
                return r;
490

491
        if (ret) {
9,650✔
492
                d = endswith(*ret, " (deleted)");
9,650✔
493
                if (d)
9,650✔
494
                        *d = '\0';
×
495
        }
496

497
        return 0;
498
}
499

500
int pid_get_uid(pid_t pid, uid_t *ret) {
3,113✔
501
        int r;
3,113✔
502

503
        assert(pid >= 0);
3,113✔
504
        assert(ret);
3,113✔
505

506
        if (pid == 0 || pid == getpid_cached()) {
3,113✔
507
                *ret = getuid();
2✔
508
                return 0;
3,113✔
509
        }
510

511
        _cleanup_free_ char *v = NULL;
3,111✔
512
        r = procfs_file_get_field(pid, "status", "Uid", &v);
3,111✔
513
        if (r == -ENOENT)
3,111✔
514
                return -ESRCH;
515
        if (r < 0)
190✔
516
                return r;
517

518
        return parse_uid(v, ret);
190✔
519
}
520

521
int pidref_get_uid(const PidRef *pid, uid_t *ret) {
69✔
522
        int r;
69✔
523

524
        if (!pidref_is_set(pid))
69✔
525
                return -ESRCH;
69✔
526

527
        if (pidref_is_remote(pid))
69✔
528
                return -EREMOTE;
529

530
        if (pid->fd >= 0) {
69✔
531
                r = pidfd_get_uid(pid->fd, ret);
69✔
532
                if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
69✔
533
                        return r;
534
        }
535

536
        uid_t uid;
3✔
537
        r = pid_get_uid(pid->pid, &uid);
3✔
538
        if (r < 0)
3✔
539
                return r;
540

541
        r = pidref_verify(pid);
3✔
542
        if (r < 0)
3✔
543
                return r;
544

545
        if (ret)
3✔
546
                *ret = uid;
3✔
547
        return 0;
548
}
549

550
int get_process_gid(pid_t pid, gid_t *ret) {
3,110✔
551
        int r;
3,110✔
552

553
        assert(pid >= 0);
3,110✔
554
        assert(ret);
3,110✔
555

556
        if (pid == 0 || pid == getpid_cached()) {
3,110✔
557
                *ret = getgid();
1✔
558
                return 0;
3,110✔
559
        }
560

561
        _cleanup_free_ char *v = NULL;
3,109✔
562
        r = procfs_file_get_field(pid, "status", "Gid", &v);
3,109✔
563
        if (r == -ENOENT)
3,109✔
564
                return -ESRCH;
565
        if (r < 0)
188✔
566
                return r;
567

568
        return parse_gid(v, ret);
3,109✔
569
}
570

571
int get_process_cwd(pid_t pid, char **ret) {
13✔
572
        assert(pid >= 0);
13✔
573

574
        if (pid == 0 || pid == getpid_cached())
13✔
575
                return safe_getcwd(ret);
×
576

577
        return get_process_link_contents(pid, "cwd", ret);
13✔
578
}
579

580
int get_process_root(pid_t pid, char **ret) {
13✔
581
        assert(pid >= 0);
13✔
582
        return get_process_link_contents(pid, "root", ret);
13✔
583
}
584

585
#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U)
586

587
int get_process_environ(pid_t pid, char **ret) {
15✔
588
        _cleanup_fclose_ FILE *f = NULL;
15✔
589
        _cleanup_free_ char *outcome = NULL;
15✔
590
        size_t sz = 0;
15✔
591
        const char *p;
15✔
592
        int r;
15✔
593

594
        assert(pid >= 0);
15✔
595
        assert(ret);
15✔
596

597
        p = procfs_file_alloca(pid, "environ");
15✔
598

599
        r = fopen_unlocked(p, "re", &f);
15✔
600
        if (r == -ENOENT)
15✔
601
                return -ESRCH;
602
        if (r < 0)
15✔
603
                return r;
604

605
        for (;;) {
6,400✔
606
                char c;
6,415✔
607

608
                if (sz >= ENVIRONMENT_BLOCK_MAX)
6,415✔
609
                        return -ENOBUFS;
×
610

611
                if (!GREEDY_REALLOC(outcome, sz + 5))
6,415✔
612
                        return -ENOMEM;
613

614
                r = safe_fgetc(f, &c);
6,415✔
615
                if (r < 0)
6,415✔
616
                        return r;
617
                if (r == 0)
6,415✔
618
                        break;
619

620
                if (c == '\0')
6,400✔
621
                        outcome[sz++] = '\n';
227✔
622
                else
623
                        sz += cescape_char(c, outcome + sz);
6,173✔
624
        }
625

626
        outcome[sz] = '\0';
15✔
627
        *ret = TAKE_PTR(outcome);
15✔
628

629
        return 0;
15✔
630
}
631

632
int pid_get_ppid(pid_t pid, pid_t *ret) {
1,528✔
633
        _cleanup_free_ char *line = NULL;
1,528✔
634
        unsigned long ppid;
1,528✔
635
        const char *p;
1,528✔
636
        int r;
1,528✔
637

638
        assert(pid >= 0);
1,528✔
639

640
        if (pid == 0)
1,528✔
641
                pid = getpid_cached();
1✔
642
        if (pid == 1) /* PID 1 has no parent, shortcut this case */
1,528✔
643
                return -EADDRNOTAVAIL;
644

645
        if (pid == getpid_cached()) {
1,524✔
646
                if (ret)
6✔
647
                        *ret = getppid();
6✔
648
                return 0;
6✔
649
        }
650

651
        p = procfs_file_alloca(pid, "stat");
1,518✔
652
        r = read_one_line_file(p, &line);
1,518✔
653
        if (r == -ENOENT)
1,518✔
654
                return -ESRCH;
655
        if (r < 0)
1,517✔
656
                return r;
657

658
        /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its
659
         * value, so let's skip over it manually */
660

661
        p = strrchr(line, ')');
1,517✔
662
        if (!p)
1,517✔
663
                return -EIO;
664
        p++;
1,517✔
665

666
        if (sscanf(p, " "
1,517✔
667
                   "%*c "  /* state */
668
                   "%lu ", /* ppid */
669
                   &ppid) != 1)
670
                return -EIO;
671

672
        /* If ppid is zero the process has no parent. Which might be the case for PID 1 (caught above)
673
         * but also for processes originating in other namespaces that are inserted into a pidns.
674
         * Return a recognizable error in this case. */
675
        if (ppid == 0)
1,517✔
676
                return -EADDRNOTAVAIL;
677

678
        if ((pid_t) ppid < 0 || (unsigned long) (pid_t) ppid != ppid)
1,517✔
679
                return -ERANGE;
680

681
        if (ret)
1,517✔
682
                *ret = (pid_t) ppid;
1,517✔
683

684
        return 0;
685
}
686

687
int pidref_get_ppid(const PidRef *pidref, pid_t *ret) {
2,473✔
688
        int r;
2,473✔
689

690
        if (!pidref_is_set(pidref))
2,473✔
691
                return -ESRCH;
2,473✔
692

693
        if (pidref_is_remote(pidref))
2,473✔
694
                return -EREMOTE;
695

696
        if (pidref->fd >= 0) {
2,473✔
697
                r = pidfd_get_ppid(pidref->fd, ret);
2,473✔
698
                if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
2,473✔
699
                        return r;
700
        }
701

702
        pid_t ppid;
1,522✔
703
        r = pid_get_ppid(pidref->pid, ret ? &ppid : NULL);
1,522✔
704
        if (r < 0)
1,522✔
705
                return r;
706

707
        r = pidref_verify(pidref);
1,521✔
708
        if (r < 0)
1,521✔
709
                return r;
710

711
        if (ret)
1,521✔
712
                *ret = ppid;
1,521✔
713
        return 0;
714
}
715

716
int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret) {
11✔
717
        pid_t ppid;
11✔
718
        int r;
11✔
719

720
        assert(ret);
11✔
721

722
        r = pidref_get_ppid(pidref, &ppid);
11✔
723
        if (r < 0)
11✔
724
                return r;
11✔
725

726
        for (unsigned attempt = 0; attempt < 16; attempt++) {
10✔
727
                _cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
10✔
728

729
                r = pidref_set_pid(&parent, ppid);
10✔
730
                if (r < 0)
10✔
731
                        return r;
732

733
                /* If we have a pidfd of the original PID, let's verify that the process we acquired really
734
                 * is the parent still */
735
                if (pidref->fd >= 0) {
10✔
736
                        r = pidref_get_ppid(pidref, &ppid);
10✔
737
                        if (r < 0)
10✔
738
                                return r;
739

740
                        /* Did the PPID change since we queried it? if so we might have pinned the wrong
741
                         * process, if its PID got reused by now. Let's try again */
742
                        if (parent.pid != ppid)
10✔
743
                                continue;
×
744
                }
745

746
                *ret = TAKE_PIDREF(parent);
10✔
747
                return 0;
10✔
748
        }
749

750
        /* Give up after 16 tries */
751
        return -ENOTRECOVERABLE;
752
}
753

754
int pid_get_start_time(pid_t pid, usec_t *ret) {
581✔
755
        _cleanup_free_ char *line = NULL;
581✔
756
        const char *p;
581✔
757
        int r;
581✔
758

759
        assert(pid >= 0);
581✔
760

761
        p = procfs_file_alloca(pid, "stat");
581✔
762
        r = read_one_line_file(p, &line);
581✔
763
        if (r == -ENOENT)
581✔
764
                return -ESRCH;
765
        if (r < 0)
581✔
766
                return r;
767

768
        /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its
769
         * value, so let's skip over it manually */
770

771
        p = strrchr(line, ')');
581✔
772
        if (!p)
581✔
773
                return -EIO;
774
        p++;
581✔
775

776
        unsigned long llu;
581✔
777

778
        if (sscanf(p, " "
581✔
779
                   "%*c " /* state */
780
                   "%*u " /* ppid */
781
                   "%*u " /* pgrp */
782
                   "%*u " /* session */
783
                   "%*u " /* tty_nr */
784
                   "%*u " /* tpgid */
785
                   "%*u " /* flags */
786
                   "%*u " /* minflt */
787
                   "%*u " /* cminflt */
788
                   "%*u " /* majflt */
789
                   "%*u " /* cmajflt */
790
                   "%*u " /* utime */
791
                   "%*u " /* stime */
792
                   "%*u " /* cutime */
793
                   "%*u " /* cstime */
794
                   "%*i " /* priority */
795
                   "%*i " /* nice */
796
                   "%*u " /* num_threads */
797
                   "%*u " /* itrealvalue */
798
                   "%lu ", /* starttime */
799
                   &llu) != 1)
800
                return -EIO;
801

802
        if (ret)
581✔
803
                *ret = jiffies_to_usec(llu); /* CLOCK_BOOTTIME */
581✔
804

805
        return 0;
806
}
807

808
int pidref_get_start_time(const PidRef *pid, usec_t *ret) {
581✔
809
        usec_t t;
581✔
810
        int r;
581✔
811

812
        if (!pidref_is_set(pid))
581✔
813
                return -ESRCH;
581✔
814

815
        if (pidref_is_remote(pid))
581✔
816
                return -EREMOTE;
817

818
        r = pid_get_start_time(pid->pid, ret ? &t : NULL);
581✔
819
        if (r < 0)
581✔
820
                return r;
821

822
        r = pidref_verify(pid);
581✔
823
        if (r < 0)
581✔
824
                return r;
825

826
        if (ret)
581✔
827
                *ret = t;
581✔
828

829
        return 0;
830
}
831

832
int get_process_umask(pid_t pid, mode_t *ret) {
22,005✔
833
        _cleanup_free_ char *m = NULL;
22,005✔
834
        int r;
22,005✔
835

836
        assert(pid >= 0);
22,005✔
837
        assert(ret);
22,005✔
838

839
        r = procfs_file_get_field(pid, "status", "Umask", &m);
22,005✔
840
        if (r == -ENOENT)
22,005✔
841
                return -ESRCH;
842
        if (r < 0)
22,005✔
843
                return r;
844

845
        return parse_mode(m, ret);
22,005✔
846
}
847

848
int wait_for_terminate(pid_t pid, siginfo_t *ret) {
582✔
849
        return pidref_wait_for_terminate(&PIDREF_MAKE_FROM_PID(pid), ret);
582✔
850
}
851

852
/*
853
 * Return values:
854
 * < 0 : wait_for_terminate() failed to get the state of the
855
 *       process, the process was terminated by a signal, or
856
 *       failed for an unknown reason.
857
 * >=0 : The process terminated normally, and its exit code is
858
 *       returned.
859
 *
860
 * That is, success is indicated by a return value of zero, and an
861
 * error is indicated by a non-zero value.
862
 *
863
 * A warning is emitted if the process terminates abnormally,
864
 * and also if it returns non-zero unless check_exit_code is true.
865
 */
866
int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags) {
6,932✔
867
        int r;
6,932✔
868

869
        if (!pidref_is_set(pidref))
6,932✔
870
                return -ESRCH;
6,932✔
871
        if (pidref_is_remote(pidref))
13,864✔
872
                return -EREMOTE;
873
        if (pidref->pid == 1 || pidref_is_self(pidref))
6,932✔
874
                return -ECHILD;
×
875

876
        _cleanup_free_ char *buffer = NULL;
6,932✔
877
        if (!name) {
6,932✔
878
                r = pidref_get_comm(pidref, &buffer);
2✔
879
                if (r < 0)
2✔
880
                        log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pidref->pid);
×
881
                else
882
                        name = buffer;
2✔
883
        }
884

885
        int prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG;
6,932✔
886

887
        siginfo_t status;
6,932✔
888
        r = pidref_wait_for_terminate(pidref, &status);
6,932✔
889
        if (r < 0)
6,932✔
890
                return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name));
×
891

892
        if (status.si_code == CLD_EXITED) {
6,932✔
893
                if (status.si_status != EXIT_SUCCESS)
6,932✔
894
                        log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG,
63✔
895
                                 "%s failed with exit status %i.", strna(name), status.si_status);
896
                else
897
                        log_debug("%s succeeded.", name);
6,869✔
898

899
                return status.si_status;
6,932✔
900

901
        } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) {
×
902

903
                log_full(prio, "%s terminated by signal %s.", strna(name), signal_to_string(status.si_status));
×
904
                return -EPROTO;
×
905
        }
906

907
        log_full(prio, "%s failed due to unknown reason.", strna(name));
×
908
        return -EPROTO;
909
}
910

911
int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) {
5,626✔
912
        return pidref_wait_for_terminate_and_check(name, &PIDREF_MAKE_FROM_PID(pid), flags);
5,626✔
913
}
914

915
/*
916
 * Return values:
917
 *
918
 * < 0 : wait_for_terminate_with_timeout() failed to get the state of the process, the process timed out, the process
919
 *       was terminated by a signal, or failed for an unknown reason.
920
 *
921
 * >=0 : The process terminated normally with no failures.
922
 *
923
 * Success is indicated by a return value of zero, a timeout is indicated by ETIMEDOUT, and all other child failure
924
 * states are indicated by error is indicated by a non-zero value.
925
 *
926
 * This call assumes SIGCHLD has been blocked already, in particular before the child to wait for has been forked off
927
 * to remain entirely race-free.
928
 */
929
int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
×
930
        sigset_t mask;
×
931
        int r;
×
932
        usec_t until;
×
933

934
        assert_se(sigemptyset(&mask) == 0);
×
935
        assert_se(sigaddset(&mask, SIGCHLD) == 0);
×
936

937
        /* Drop into a sigtimewait-based timeout. Waiting for the
938
         * pid to exit. */
939
        until = usec_add(now(CLOCK_MONOTONIC), timeout);
×
940
        for (;;) {
×
941
                usec_t n;
×
942
                siginfo_t status = {};
×
943

944
                n = now(CLOCK_MONOTONIC);
×
945
                if (n >= until)
×
946
                        break;
947

948
                r = RET_NERRNO(sigtimedwait(&mask, NULL, TIMESPEC_STORE(until - n)));
×
949
                /* Assuming we woke due to the child exiting. */
950
                if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) {
×
951
                        if (status.si_pid == pid) {
×
952
                                /* This is the correct child. */
953
                                if (status.si_code == CLD_EXITED)
×
954
                                        return status.si_status == 0 ? 0 : -EPROTO;
×
955
                                else
956
                                        return -EPROTO;
957
                        }
958
                }
959
                /* Not the child, check for errors and proceed appropriately */
960
                if (r < 0) {
×
961
                        switch (r) {
×
962
                        case -EAGAIN:
963
                                /* Timed out, child is likely hung. */
964
                                return -ETIMEDOUT;
965
                        case -EINTR:
×
966
                                /* Received a different signal and should retry */
967
                                continue;
×
968
                        default:
×
969
                                /* Return any unexpected errors */
970
                                return r;
×
971
                        }
972
                }
973
        }
974

975
        return -EPROTO;
×
976
}
977

978
void sigkill_wait(pid_t pid) {
141✔
979
        assert(pid > 1);
141✔
980

981
        (void) kill(pid, SIGKILL);
141✔
982
        (void) wait_for_terminate(pid, NULL);
141✔
983
}
141✔
984

985
void sigkill_waitp(pid_t *pid) {
12,107✔
986
        PROTECT_ERRNO;
12,107✔
987

988
        if (!pid)
12,107✔
989
                return;
990
        if (*pid <= 1)
12,107✔
991
                return;
992

993
        sigkill_wait(*pid);
141✔
994
}
995

996
void sigterm_wait(pid_t pid) {
96✔
997
        assert(pid > 1);
96✔
998

999
        (void) kill_and_sigcont(pid, SIGTERM);
96✔
1000
        (void) wait_for_terminate(pid, NULL);
96✔
1001
}
96✔
1002

1003
void sigkill_nowait(pid_t pid) {
×
1004
        assert(pid > 1);
×
1005

1006
        (void) kill(pid, SIGKILL);
×
1007
}
×
1008

1009
void sigkill_nowaitp(pid_t *pid) {
×
1010
        PROTECT_ERRNO;
×
1011

1012
        if (!pid)
×
1013
                return;
1014
        if (*pid <= 1)
×
1015
                return;
1016

1017
        sigkill_nowait(*pid);
×
1018
}
1019

1020
int kill_and_sigcont(pid_t pid, int sig) {
96✔
1021
        int r;
96✔
1022

1023
        r = RET_NERRNO(kill(pid, sig));
96✔
1024

1025
        /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
1026
         * affected by a process being suspended anyway. */
1027
        if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
96✔
1028
                (void) kill(pid, SIGCONT);
96✔
1029

1030
        return r;
96✔
1031
}
1032

1033
int getenv_for_pid(pid_t pid, const char *field, char **ret) {
4,746✔
1034
        _cleanup_fclose_ FILE *f = NULL;
4,746✔
1035
        const char *path;
4,746✔
1036
        size_t sum = 0;
4,746✔
1037
        int r;
4,746✔
1038

1039
        assert(pid >= 0);
4,746✔
1040
        assert(field);
4,746✔
1041
        assert(ret);
4,746✔
1042

1043
        if (pid == 0 || pid == getpid_cached())
4,746✔
1044
                return strdup_to_full(ret, getenv(field));
14✔
1045

1046
        if (!pid_is_valid(pid))
4,732✔
1047
                return -EINVAL;
1048

1049
        path = procfs_file_alloca(pid, "environ");
4,732✔
1050

1051
        r = fopen_unlocked(path, "re", &f);
4,732✔
1052
        if (r == -ENOENT)
4,732✔
1053
                return -ESRCH;
1054
        if (r < 0)
4,329✔
1055
                return r;
1056

1057
        for (;;) {
51,016✔
1058
                _cleanup_free_ char *line = NULL;
24,012✔
1059
                const char *match;
27,021✔
1060

1061
                if (sum > ENVIRONMENT_BLOCK_MAX) /* Give up searching eventually */
27,021✔
1062
                        return -ENOBUFS;
1063

1064
                r = read_nul_string(f, LONG_LINE_MAX, &line);
27,021✔
1065
                if (r < 0)
27,021✔
1066
                        return r;
1067
                if (r == 0)  /* EOF */
27,021✔
1068
                        break;
1069

1070
                sum += r;
24,012✔
1071

1072
                match = startswith(line, field);
24,012✔
1073
                if (match && *match == '=')
24,012✔
1074
                        return strdup_to_full(ret, match + 1);
17✔
1075
        }
1076

1077
        *ret = NULL;
3,009✔
1078
        return 0;
3,009✔
1079
}
1080

1081
int pidref_is_my_child(PidRef *pid) {
2,451✔
1082
        int r;
2,451✔
1083

1084
        if (!pidref_is_set(pid))
2,451✔
1085
                return -ESRCH;
2,451✔
1086

1087
        if (pidref_is_remote(pid))
2,451✔
1088
                return -EREMOTE;
1089

1090
        if (pid->pid == 1 || pidref_is_self(pid))
2,451✔
1091
                return false;
×
1092

1093
        pid_t ppid;
2,451✔
1094
        r = pidref_get_ppid(pid, &ppid);
2,451✔
1095
        if (r == -EADDRNOTAVAIL) /* if this process is outside of our pidns, it is definitely not our child */
2,451✔
1096
                return false;
1097
        if (r < 0)
2,451✔
1098
                return r;
1099

1100
        return ppid == getpid_cached();
2,451✔
1101
}
1102

1103
int pid_is_my_child(pid_t pid) {
×
1104

1105
        if (pid == 0)
×
1106
                return false;
×
1107

1108
        return pidref_is_my_child(&PIDREF_MAKE_FROM_PID(pid));
×
1109
}
1110

1111
int pidref_is_unwaited(PidRef *pid) {
9,475✔
1112
        int r;
9,475✔
1113

1114
        /* Checks whether a PID is still valid at all, including a zombie */
1115

1116
        if (!pidref_is_set(pid))
9,475✔
1117
                return -ESRCH;
1118

1119
        if (pidref_is_remote(pid))
9,474✔
1120
                return -EREMOTE;
1121

1122
        if (pid->pid == 1 || pidref_is_self(pid))
9,474✔
1123
                return true;
8✔
1124

1125
        r = pidref_kill(pid, 0);
9,466✔
1126
        if (r == -ESRCH)
9,466✔
1127
                return false;
1128
        if (r < 0)
2,096✔
1129
                return r;
172✔
1130

1131
        return true;
1132
}
1133

1134
int pid_is_unwaited(pid_t pid) {
8,895✔
1135

1136
        if (pid == 0)
8,895✔
1137
                return true;
8,895✔
1138

1139
        return pidref_is_unwaited(&PIDREF_MAKE_FROM_PID(pid));
8,895✔
1140
}
1141

1142
int pid_is_alive(pid_t pid) {
12,977✔
1143
        int r;
12,977✔
1144

1145
        /* Checks whether a PID is still valid and not a zombie */
1146

1147
        if (pid < 0)
12,977✔
1148
                return -ESRCH;
1149

1150
        if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
12,976✔
1151
                return true;
1152

1153
        if (pid == getpid_cached())
12,976✔
1154
                return true;
1155

1156
        r = get_process_state(pid);
12,975✔
1157
        if (r == -ESRCH)
12,975✔
1158
                return false;
1159
        if (r < 0)
10,178✔
1160
                return r;
1161

1162
        return r != 'Z';
10,178✔
1163
}
1164

1165
int pidref_is_alive(const PidRef *pidref) {
12,972✔
1166
        int r, result;
12,972✔
1167

1168
        if (!pidref_is_set(pidref))
12,972✔
1169
                return -ESRCH;
1170

1171
        if (pidref_is_remote(pidref))
12,972✔
1172
                return -EREMOTE;
1173

1174
        result = pid_is_alive(pidref->pid);
12,972✔
1175
        if (result < 0) {
12,972✔
1176
                assert(result != -ESRCH);
×
1177
                return result;
1178
        }
1179

1180
        r = pidref_verify(pidref);
12,972✔
1181
        if (r == -ESRCH)
12,972✔
1182
                return false;
1183
        if (r < 0)
10,169✔
1184
                return r;
×
1185

1186
        return result;
1187
}
1188

1189
int pidref_from_same_root_fs(PidRef *a, PidRef *b) {
20✔
1190
        _cleanup_(pidref_done) PidRef self = PIDREF_NULL;
×
1191
        int r;
20✔
1192

1193
        /* Checks if the two specified processes have the same root fs. Either can be specified as NULL in
1194
         * which case we'll check against ourselves. */
1195

1196
        if (!a || !b) {
20✔
1197
                r = pidref_set_self(&self);
×
1198
                if (r < 0)
×
1199
                        return r;
1200
                if (!a)
×
1201
                        a = &self;
×
1202
                if (!b)
×
1203
                        b = &self;
×
1204
        }
1205

1206
        if (!pidref_is_set(a) || !pidref_is_set(b))
20✔
1207
                return -ESRCH;
×
1208

1209
        /* If one of the two processes have the same root they cannot have the same root fs, but if both of
1210
         * them do we don't know */
1211
        if (pidref_is_remote(a) && pidref_is_remote(b))
20✔
1212
                return -EREMOTE;
1213
        if (pidref_is_remote(a) || pidref_is_remote(b))
60✔
1214
                return false;
1215

1216
        if (pidref_equal(a, b))
20✔
1217
                return true;
1218

1219
        const char *roota = procfs_file_alloca(a->pid, "root");
18✔
1220
        const char *rootb = procfs_file_alloca(b->pid, "root");
18✔
1221

1222
        int result = inode_same(roota, rootb, 0);
18✔
1223
        if (result == -ENOENT)
18✔
1224
                return proc_mounted() == 0 ? -ENOSYS : -ESRCH;
×
1225
        if (result < 0)
18✔
1226
                return result;
1227

1228
        r = pidref_verify(a);
18✔
1229
        if (r < 0)
18✔
1230
                return r;
1231
        r = pidref_verify(b);
18✔
1232
        if (r < 0)
18✔
1233
                return r;
×
1234

1235
        return result;
1236
}
1237

1238
bool is_main_thread(void) {
7,263,008✔
1239
        static thread_local int cached = -1;
7,263,008✔
1240

1241
        if (cached < 0)
7,263,008✔
1242
                cached = getpid_cached() == gettid();
55,639✔
1243

1244
        return cached;
7,263,008✔
1245
}
1246

1247
bool oom_score_adjust_is_valid(int oa) {
6,766✔
1248
        return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
6,766✔
1249
}
1250

1251
unsigned long personality_from_string(const char *p) {
9✔
1252
        Architecture architecture;
9✔
1253

1254
        if (!p)
9✔
1255
                return PERSONALITY_INVALID;
1256

1257
        /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just
1258
         * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for
1259
         * the same register size. */
1260

1261
        architecture = architecture_from_string(p);
8✔
1262
        if (architecture < 0)
8✔
1263
                return PERSONALITY_INVALID;
1264

1265
        if (architecture == native_architecture())
6✔
1266
                return PER_LINUX;
1267
#ifdef ARCHITECTURE_SECONDARY
1268
        if (architecture == ARCHITECTURE_SECONDARY)
3✔
1269
                return PER_LINUX32;
2✔
1270
#endif
1271

1272
        return PERSONALITY_INVALID;
1273
}
1274

1275
const char* personality_to_string(unsigned long p) {
2,779✔
1276
        Architecture architecture = _ARCHITECTURE_INVALID;
2,779✔
1277

1278
        if (p == PER_LINUX)
2,779✔
1279
                architecture = native_architecture();
1280
#ifdef ARCHITECTURE_SECONDARY
1281
        else if (p == PER_LINUX32)
2,774✔
1282
                architecture = ARCHITECTURE_SECONDARY;
1283
#endif
1284

1285
        if (architecture < 0)
1286
                return NULL;
1287

1288
        return architecture_to_string(architecture);
7✔
1289
}
1290

1291
int safe_personality(unsigned long p) {
1,468✔
1292
        int ret;
1,468✔
1293

1294
        /* So here's the deal, personality() is weirdly defined by glibc. In some cases it returns a failure via errno,
1295
         * and in others as negative return value containing an errno-like value. Let's work around this: this is a
1296
         * wrapper that uses errno if it is set, and uses the return value otherwise. And then it sets both errno and
1297
         * the return value indicating the same issue, so that we are definitely on the safe side.
1298
         *
1299
         * See https://github.com/systemd/systemd/issues/6737 */
1300

1301
        errno = 0;
1,468✔
1302
        ret = personality(p);
1,468✔
1303
        if (ret < 0) {
1,468✔
1304
                if (errno != 0)
12✔
1305
                        return -errno;
12✔
1306

1307
                errno = -ret;
×
1308
        }
1309

1310
        return ret;
1311
}
1312

1313
int opinionated_personality(unsigned long *ret) {
1,453✔
1314
        int current;
1,453✔
1315

1316
        /* Returns the current personality, or PERSONALITY_INVALID if we can't determine it. This function is a bit
1317
         * opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the
1318
         * two most relevant personalities: PER_LINUX and PER_LINUX32. */
1319

1320
        current = safe_personality(PERSONALITY_INVALID);
1,453✔
1321
        if (current < 0)
1,453✔
1322
                return current;
1323

1324
        if (((unsigned long) current & OPINIONATED_PERSONALITY_MASK) == PER_LINUX32)
1,453✔
1325
                *ret = PER_LINUX32;
×
1326
        else
1327
                *ret = PER_LINUX;
1,453✔
1328

1329
        return 0;
1330
}
1331

1332
void valgrind_summary_hack(void) {
39✔
1333
#if HAVE_VALGRIND_VALGRIND_H
1334
        if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
1335
                pid_t pid;
1336
                pid = raw_clone(SIGCHLD);
1337
                if (pid < 0)
1338
                        log_struct_errno(
1339
                                LOG_EMERG, errno,
1340
                                LOG_MESSAGE_ID(SD_MESSAGE_VALGRIND_HELPER_FORK_STR),
1341
                                LOG_MESSAGE("Failed to fork off valgrind helper: %m"));
1342
                else if (pid == 0)
1343
                        exit(EXIT_SUCCESS);
1344
                else {
1345
                        log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
1346
                        (void) wait_for_terminate(pid, NULL);
1347
                }
1348
        }
1349
#endif
1350
}
39✔
1351

1352
int pid_compare_func(const pid_t *a, const pid_t *b) {
1,154✔
1353
        /* Suitable for usage in qsort() */
1354
        return CMP(*a, *b);
1,154✔
1355
}
1356

1357
bool nice_is_valid(int n) {
872✔
1358
        return n >= PRIO_MIN && n < PRIO_MAX;
872✔
1359
}
1360

1361
bool sched_policy_is_valid(int i) {
×
1362
        return IN_SET(i, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_FIFO, SCHED_RR);
×
1363
}
1364

1365
bool sched_priority_is_valid(int i) {
×
1366
        return i >= 0 && i <= sched_get_priority_max(SCHED_RR);
×
1367
}
1368

1369
/* The cached PID, possible values:
1370
 *
1371
 *     == UNSET [0]  → cache not initialized yet
1372
 *     == BUSY [-1]  → some thread is initializing it at the moment
1373
 *     any other     → the cached PID
1374
 */
1375

1376
#define CACHED_PID_UNSET ((pid_t) 0)
1377
#define CACHED_PID_BUSY ((pid_t) -1)
1378

1379
static pid_t cached_pid = CACHED_PID_UNSET;
1380

1381
void reset_cached_pid(void) {
1,580✔
1382
        /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
1383
        cached_pid = CACHED_PID_UNSET;
1,580✔
1384
}
1,580✔
1385

1386
pid_t getpid_cached(void) {
151,020,797✔
1387
        static bool installed = false;
151,020,797✔
1388
        pid_t current_value = CACHED_PID_UNSET;
151,020,797✔
1389

1390
        /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a
1391
         * system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally
1392
         * cached. Starting with 2.24 getpid() started to become prohibitively expensive when used for detecting when
1393
         * objects were used across fork()s. With this caching the old behaviour is somewhat restored.
1394
         *
1395
         * https://bugzilla.redhat.com/show_bug.cgi?id=1443976
1396
         * https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c579f48edba88380635ab98cb612030e3ed8691e
1397
         */
1398

1399
        (void) __atomic_compare_exchange_n(
151,020,797✔
1400
                        &cached_pid,
1401
                        &current_value,
1402
                        CACHED_PID_BUSY,
1403
                        false,
1404
                        __ATOMIC_SEQ_CST,
1405
                        __ATOMIC_SEQ_CST);
1406

1407
        switch (current_value) {
151,020,797✔
1408

1409
        case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */
102,130✔
1410
                pid_t new_pid;
102,130✔
1411

1412
                new_pid = getpid();
102,130✔
1413

1414
                if (!installed) {
102,130✔
1415
                        /* __register_atfork() either returns 0 or -ENOMEM, in its glibc implementation. Since it's
1416
                         * only half-documented (glibc doesn't document it but LSB does — though only superficially)
1417
                         * we'll check for errors only in the most generic fashion possible. */
1418

1419
                        if (pthread_atfork(NULL, NULL, reset_cached_pid) != 0) {
71,657✔
1420
                                /* OOM? Let's try again later */
1421
                                cached_pid = CACHED_PID_UNSET;
×
1422
                                return new_pid;
×
1423
                        }
1424

1425
                        installed = true;
71,657✔
1426
                }
1427

1428
                cached_pid = new_pid;
102,130✔
1429
                return new_pid;
102,130✔
1430
        }
1431

1432
        case CACHED_PID_BUSY: /* Somebody else is currently initializing */
×
1433
                return getpid();
×
1434

1435
        default: /* Properly initialized */
1436
                return current_value;
1437
        }
1438
}
1439

1440
int must_be_root(void) {
54✔
1441

1442
        if (geteuid() == 0)
54✔
1443
                return 0;
1444

1445
        return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
×
1446
}
1447

1448
pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) {
3,522✔
1449
        size_t ps;
3,522✔
1450
        pid_t pid;
3,522✔
1451
        void *mystack;
3,522✔
1452

1453
        /* A wrapper around glibc's clone() call that automatically sets up a "nested" stack. Only supports
1454
         * invocations without CLONE_VM, so that we can continue to use the parent's stack mapping.
1455
         *
1456
         * Note: glibc's clone() wrapper does not synchronize malloc() locks. This means that if the parent
1457
         * is threaded these locks will be in an undefined state in the child, and hence memory allocations
1458
         * are likely going to run into deadlocks. Hence: if you use this function make sure your parent is
1459
         * strictly single-threaded or your child never calls malloc(). */
1460

1461
        assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
3,522✔
1462
                         CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0);
1463

1464
        /* We allocate some space on the stack to use as the stack for the child (hence "nested"). Note that
1465
         * the net effect is that the child will have the start of its stack inside the stack of the parent,
1466
         * but since they are a CoW copy of each other that's fine. We allocate one page-aligned page. But
1467
         * since we don't want to deal with differences between systems where the stack grows backwards or
1468
         * forwards we'll allocate one more and place the stack address in the middle. Except that we also
1469
         * want it page aligned, hence we'll allocate one page more. Makes 3. */
1470

1471
        ps = page_size();
3,522✔
1472
        mystack = alloca(ps*3);
3,522✔
1473
        mystack = (uint8_t*) mystack + ps; /* move pointer one page ahead since stacks usually grow backwards */
3,522✔
1474
        mystack = (void*) ALIGN_TO((uintptr_t) mystack, ps); /* align to page size (moving things further ahead) */
3,522✔
1475

1476
#if HAVE_CLONE
1477
        pid = clone(fn, mystack, flags, userdata);
3,522✔
1478
#else
1479
        pid = __clone2(fn, mystack, ps, flags, userdata);
1480
#endif
1481
        if (pid < 0)
3,522✔
1482
                return -errno;
×
1483

1484
        return pid;
1485
}
1486

1487
static void restore_sigsetp(sigset_t **ssp) {
57,890✔
1488
        if (*ssp)
57,890✔
1489
                (void) sigprocmask(SIG_SETMASK, *ssp, NULL);
23,839✔
1490
}
57,890✔
1491

1492
static int fork_flags_to_signal(ForkFlags flags) {
28,654✔
1493
        return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM :
28,654✔
1494
                (flags & FORK_DEATHSIG_SIGINT) ? SIGINT :
560✔
1495
                                                 SIGKILL;
1496
}
1497

1498
int pidref_safe_fork_full(
28,122✔
1499
                const char *name,
1500
                const int stdio_fds[3],
1501
                int except_fds[],
1502
                size_t n_except_fds,
1503
                ForkFlags flags,
1504
                PidRef *ret_pid) {
1505

1506
        pid_t original_pid, pid;
28,122✔
1507
        sigset_t saved_ss, ss;
28,122✔
1508
        _unused_ _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL;
×
1509
        bool block_signals = false, block_all = false, intermediary = false;
28,122✔
1510
        _cleanup_close_pair_ int pidref_transport_fds[2] = EBADF_PAIR;
57,890✔
1511
        int prio, r;
28,122✔
1512

1513
        assert(!FLAGS_SET(flags, FORK_WAIT|FORK_FREEZE));
28,122✔
1514
        assert(!FLAGS_SET(flags, FORK_DETACH) ||
28,122✔
1515
               (flags & (FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) == 0);
1516

1517
        /* A wrapper around fork(), that does a couple of important initializations in addition to mere
1518
         * forking. If provided, ret_pid is initialized in both the parent and the child process, both times
1519
         * referencing the child process. Returns == 0 in the child and > 0 in the parent. */
1520

1521
        prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG;
28,122✔
1522

1523
        original_pid = getpid_cached();
28,122✔
1524

1525
        if (flags & FORK_FLUSH_STDIO) {
28,122✔
1526
                fflush(stdout);
5✔
1527
                fflush(stderr); /* This one shouldn't be necessary, stderr should be unbuffered anyway, but let's better be safe than sorry */
5✔
1528
        }
1529

1530
        if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT)) {
28,122✔
1531
                /* We temporarily block all signals, so that the new child has them blocked initially. This
1532
                 * way, we can be sure that SIGTERMs are not lost we might send to the child. (Note that for
1533
                 * FORK_DEATHSIG_SIGKILL we don't bother, since it cannot be blocked anyway.) */
1534

1535
                assert_se(sigfillset(&ss) >= 0);
24,003✔
1536
                block_signals = block_all = true;
1537

1538
        } else if (flags & FORK_WAIT) {
4,119✔
1539
                /* Let's block SIGCHLD at least, so that we can safely watch for the child process */
1540

1541
                assert_se(sigemptyset(&ss) >= 0);
148✔
1542
                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
148✔
1543
                block_signals = true;
1544
        }
1545

1546
        if (block_signals) {
1547
                if (sigprocmask(SIG_BLOCK, &ss, &saved_ss) < 0)
24,151✔
1548
                        return log_full_errno(prio, errno, "Failed to block signal mask: %m");
×
1549
                saved_ssp = &saved_ss;
24,151✔
1550
        }
1551

1552
        if (FLAGS_SET(flags, FORK_DETACH)) {
28,122✔
1553
                /* Fork off intermediary child if needed */
1554

1555
                r = is_reaper_process();
105✔
1556
                if (r < 0)
105✔
1557
                        return log_full_errno(prio, r, "Failed to determine if we are a reaper process: %m");
×
1558

1559
                if (!r) {
105✔
1560
                        /* Not a reaper process, hence do a double fork() so we are reparented to one */
1561

1562
                        if (ret_pid && socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, pidref_transport_fds) < 0)
11✔
1563
                                return log_full_errno(prio, errno, "Failed to allocate pidref socket: %m");
×
1564

1565
                        pid = fork();
11✔
1566
                        if (pid < 0)
28✔
1567
                                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
×
1568
                        if (pid > 0) {
28✔
1569
                                log_debug("Successfully forked off intermediary '%s' as PID " PID_FMT ".", strna(name), pid);
11✔
1570

1571
                                pidref_transport_fds[1] = safe_close(pidref_transport_fds[1]);
11✔
1572

1573
                                if (pidref_transport_fds[0] >= 0) {
11✔
1574
                                        /* Wait for the intermediary child to exit so the caller can be certain the actual child
1575
                                         * process has been reparented by the time this function returns. */
1576
                                        r = wait_for_terminate_and_check(name, pid, FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
20✔
1577
                                        if (r < 0)
10✔
1578
                                                return log_full_errno(prio, r, "Failed to wait for intermediary process: %m");
×
1579
                                        if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
10✔
1580
                                                return -EPROTO;
1581

1582
                                        int pidfd;
10✔
1583
                                        ssize_t n = receive_one_fd_iov(
20✔
1584
                                                        pidref_transport_fds[0],
1585
                                                        &IOVEC_MAKE(&pid, sizeof(pid)),
10✔
1586
                                                        /* iovlen= */ 1,
1587
                                                        /* flags= */ 0,
1588
                                                        &pidfd);
1589
                                        if (n < 0)
10✔
1590
                                                return log_full_errno(prio, n, "Failed to receive child pidref: %m");
×
1591

1592
                                        *ret_pid = (PidRef) { .pid = pid, .fd = pidfd };
10✔
1593
                                }
1594

1595
                                return 1; /* return in the parent */
11✔
1596
                        }
1597

1598
                        pidref_transport_fds[0] = safe_close(pidref_transport_fds[0]);
17✔
1599
                        intermediary = true;
17✔
1600
                }
1601
        }
1602

1603
        if ((flags & (FORK_NEW_MOUNTNS|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS)) != 0)
28,128✔
1604
                pid = raw_clone(SIGCHLD|
5,468✔
1605
                                (FLAGS_SET(flags, FORK_NEW_MOUNTNS) ? CLONE_NEWNS : 0) |
5,468✔
1606
                                (FLAGS_SET(flags, FORK_NEW_USERNS) ? CLONE_NEWUSER : 0) |
5,468✔
1607
                                (FLAGS_SET(flags, FORK_NEW_NETNS) ? CLONE_NEWNET : 0) |
5,468✔
1608
                                (FLAGS_SET(flags, FORK_NEW_PIDNS) ? CLONE_NEWPID : 0));
5,468✔
1609
        else
1610
                pid = fork();
22,660✔
1611
        if (pid < 0)
57,890✔
1612
                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
×
1613
        if (pid > 0) {
57,890✔
1614

1615
                /* If we are in the intermediary process, exit now */
1616
                if (intermediary) {
27,810✔
1617
                        if (pidref_transport_fds[1] >= 0) {
11✔
1618
                                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
10✔
1619

1620
                                r = pidref_set_pid(&pidref, pid);
10✔
1621
                                if (r < 0) {
10✔
1622
                                        log_full_errno(prio, r, "Failed to open reference to PID "PID_FMT": %m", pid);
×
1623
                                        _exit(EXIT_FAILURE);
×
1624
                                }
1625

1626
                                r = send_one_fd_iov(
10✔
1627
                                                pidref_transport_fds[1],
1628
                                                pidref.fd,
1629
                                                &IOVEC_MAKE(&pidref.pid, sizeof(pidref.pid)),
1630
                                                /* iovlen= */ 1,
1631
                                                /* flags= */ 0);
1632
                                if (r < 0) {
10✔
1633
                                        log_full_errno(prio, r, "Failed to send child pidref: %m");
×
1634
                                        _exit(EXIT_FAILURE);
×
1635
                                }
1636
                        }
1637

1638
                        _exit(EXIT_SUCCESS);
11✔
1639
                }
1640

1641
                /* We are in the parent process */
1642
                log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
27,799✔
1643

1644
                if (flags & FORK_WAIT) {
27,799✔
1645
                        if (block_all) {
739✔
1646
                                /* undo everything except SIGCHLD */
1647
                                ss = saved_ss;
591✔
1648
                                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
591✔
1649
                                (void) sigprocmask(SIG_SETMASK, &ss, NULL);
591✔
1650
                        }
1651

1652
                        r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
869✔
1653
                        if (r < 0)
739✔
1654
                                return r;
1655
                        if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
739✔
1656
                                return -EPROTO;
1657

1658
                        /* If we are in the parent and successfully waited, then the process doesn't exist anymore. */
1659
                        if (ret_pid)
739✔
1660
                                *ret_pid = PIDREF_NULL;
14✔
1661

1662
                        return 1;
739✔
1663
                }
1664

1665
                if (ret_pid) {
27,060✔
1666
                        if (FLAGS_SET(flags, _FORK_PID_ONLY))
26,460✔
1667
                                *ret_pid = PIDREF_MAKE_FROM_PID(pid);
7,367✔
1668
                        else {
1669
                                r = pidref_set_pid(ret_pid, pid);
19,093✔
1670
                                if (r < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */
19,093✔
1671
                                        *ret_pid = PIDREF_MAKE_FROM_PID(pid);
×
1672
                        }
1673
                }
1674

1675
                return 1;
27,060✔
1676
        }
1677

1678
        /* We are in the child process */
1679

1680
        pidref_transport_fds[1] = safe_close(pidref_transport_fds[1]);
30,080✔
1681

1682
        /* Restore signal mask manually */
1683
        saved_ssp = NULL;
30,080✔
1684

1685
        if (flags & FORK_REOPEN_LOG) {
30,080✔
1686
                /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
1687
                log_close();
6,640✔
1688
                log_set_open_when_needed(true);
6,640✔
1689
                log_settle_target();
6,640✔
1690
        }
1691

1692
        if (name) {
30,080✔
1693
                r = rename_process(name);
30,080✔
1694
                if (r < 0)
30,080✔
1695
                        log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG,
×
1696
                                       r, "Failed to rename process, ignoring: %m");
1697
        }
1698

1699
        /* let's disable dlopen() in the child, as a paranoia safety precaution: children should not live for
1700
         * long and only do minimal work before exiting or exec()ing. Doing dlopen() is not either. If people
1701
         * want dlopen() they should do it before forking. This is a safety precaution in particular for
1702
         * cases where the child does namespace shenanigans: we should never end up loading a module from a
1703
         * foreign environment. Note that this has no effect on NSS! (i.e. it only has effect on uses of our
1704
         * dlopen_safe(), which we use comprehensively in our codebase, but glibc NSS doesn't bother, of
1705
         * course.) */
1706
        block_dlopen();
30,080✔
1707

1708
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL))
30,080✔
1709
                if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) {
28,654✔
1710
                        log_full_errno(prio, errno, "Failed to set death signal: %m");
×
1711
                        _exit(EXIT_FAILURE);
×
1712
                }
1713

1714
        if (flags & FORK_RESET_SIGNALS) {
30,080✔
1715
                r = reset_all_signal_handlers();
24,896✔
1716
                if (r < 0) {
24,896✔
1717
                        log_full_errno(prio, r, "Failed to reset signal handlers: %m");
×
1718
                        _exit(EXIT_FAILURE);
×
1719
                }
1720

1721
                /* This implicitly undoes the signal mask stuff we did before the fork()ing above */
1722
                r = reset_signal_mask();
24,896✔
1723
                if (r < 0) {
24,896✔
1724
                        log_full_errno(prio, r, "Failed to reset signal mask: %m");
×
1725
                        _exit(EXIT_FAILURE);
×
1726
                }
1727
        } else if (block_signals) { /* undo what we did above */
5,184✔
1728
                if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) {
4,662✔
1729
                        log_full_errno(prio, errno, "Failed to restore signal mask: %m");
×
1730
                        _exit(EXIT_FAILURE);
×
1731
                }
1732
        }
1733

1734
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGINT)) {
30,080✔
1735
                pid_t ppid;
28,654✔
1736
                /* Let's see if the parent PID is still the one we started from? If not, then the parent
1737
                 * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */
1738

1739
                ppid = getppid();
28,654✔
1740
                if (ppid == 0)
28,654✔
1741
                        /* Parent is in a different PID namespace. */;
1742
                else if (ppid != original_pid) {
28,616✔
1743
                        int sig = fork_flags_to_signal(flags);
×
1744
                        log_debug("Parent died early, raising %s.", signal_to_string(sig));
×
1745
                        (void) raise(sig);
×
1746
                        _exit(EXIT_FAILURE);
×
1747
                }
1748
        }
1749

1750
        if (FLAGS_SET(flags, FORK_NEW_MOUNTNS | FORK_MOUNTNS_SLAVE)) {
30,080✔
1751
                /* Optionally, make sure we never propagate mounts to the host. */
1752
                if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
142✔
1753
                        log_full_errno(prio, errno, "Failed to remount root directory as MS_SLAVE: %m");
×
1754
                        _exit(EXIT_FAILURE);
×
1755
                }
1756
        }
1757

1758
        if (FLAGS_SET(flags, FORK_PRIVATE_TMP)) {
30,080✔
1759
                assert(FLAGS_SET(flags, FORK_NEW_MOUNTNS));
×
1760

1761
                /* Optionally, overmount new tmpfs instance on /tmp/. */
1762
                r = mount_nofollow("tmpfs", "/tmp", "tmpfs",
×
1763
                                   MS_NOSUID|MS_NODEV,
1764
                                   "mode=01777" TMPFS_LIMITS_RUN);
1765
                if (r < 0) {
×
1766
                        log_full_errno(prio, r, "Failed to overmount /tmp/: %m");
×
1767
                        _exit(EXIT_FAILURE);
×
1768
                }
1769
        }
1770

1771
        if (flags & FORK_REARRANGE_STDIO) {
30,080✔
1772
                if (stdio_fds) {
15,877✔
1773
                        r = rearrange_stdio(stdio_fds[0], stdio_fds[1], stdio_fds[2]);
15,861✔
1774
                        if (r < 0) {
15,861✔
1775
                                log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
×
1776
                                _exit(EXIT_FAILURE);
×
1777
                        }
1778

1779
                        /* Turn off O_NONBLOCK on the fdio fds, in case it was left on */
1780
                        stdio_disable_nonblock();
15,861✔
1781
                } else {
1782
                        r = make_null_stdio();
16✔
1783
                        if (r < 0) {
16✔
1784
                                log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
×
1785
                                _exit(EXIT_FAILURE);
×
1786
                        }
1787
                }
1788
        } else if (flags & FORK_STDOUT_TO_STDERR) {
14,203✔
1789
                if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
2✔
1790
                        log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
×
1791
                        _exit(EXIT_FAILURE);
×
1792
                }
1793
        }
1794

1795
        if (flags & FORK_CLOSE_ALL_FDS) {
30,080✔
1796
                /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
1797
                log_close();
24,086✔
1798

1799
                r = close_all_fds(except_fds, n_except_fds);
24,086✔
1800
                if (r < 0) {
24,086✔
1801
                        log_full_errno(prio, r, "Failed to close all file descriptors: %m");
×
1802
                        _exit(EXIT_FAILURE);
×
1803
                }
1804
        }
1805

1806
        if (flags & FORK_PACK_FDS) {
30,080✔
1807
                /* FORK_CLOSE_ALL_FDS ensures that except_fds are the only FDs >= 3 that are
1808
                 * open, this is including the log. This is required by pack_fds, which will
1809
                 * get stuck in an infinite loop of any FDs other than except_fds are open. */
1810
                assert(FLAGS_SET(flags, FORK_CLOSE_ALL_FDS));
88✔
1811

1812
                r = pack_fds(except_fds, n_except_fds);
88✔
1813
                if (r < 0) {
88✔
1814
                        log_full_errno(prio, r, "Failed to pack file descriptors: %m");
×
1815
                        _exit(EXIT_FAILURE);
×
1816
                }
1817
        }
1818

1819
        if (flags & FORK_CLOEXEC_OFF) {
30,080✔
1820
                r = fd_cloexec_many(except_fds, n_except_fds, false);
103✔
1821
                if (r < 0) {
103✔
1822
                        log_full_errno(prio, r, "Failed to turn off O_CLOEXEC on file descriptors: %m");
×
1823
                        _exit(EXIT_FAILURE);
×
1824
                }
1825
        }
1826

1827
        /* When we were asked to reopen the logs, do so again now */
1828
        if (flags & FORK_REOPEN_LOG) {
30,080✔
1829
                log_open();
6,640✔
1830
                log_set_open_when_needed(false);
6,640✔
1831
        }
1832

1833
        if (flags & FORK_RLIMIT_NOFILE_SAFE) {
30,080✔
1834
                r = rlimit_nofile_safe();
17,001✔
1835
                if (r < 0) {
17,001✔
1836
                        log_full_errno(prio, r, "Failed to lower RLIMIT_NOFILE's soft limit to 1K: %m");
×
1837
                        _exit(EXIT_FAILURE);
×
1838
                }
1839
        }
1840

1841
        if (!FLAGS_SET(flags, FORK_KEEP_NOTIFY_SOCKET)) {
30,080✔
1842
                r = RET_NERRNO(unsetenv("NOTIFY_SOCKET"));
30,080✔
1843
                if (r < 0) {
×
1844
                        log_full_errno(prio, r, "Failed to unset $NOTIFY_SOCKET: %m");
×
1845
                        _exit(EXIT_FAILURE);
×
1846
                }
1847
        }
1848

1849
        if (FLAGS_SET(flags, FORK_FREEZE))
30,080✔
1850
                freeze();
×
1851

1852
        if (ret_pid) {
30,080✔
1853
                if (FLAGS_SET(flags, _FORK_PID_ONLY))
28,563✔
1854
                        *ret_pid = PIDREF_MAKE_FROM_PID(getpid_cached());
7,272✔
1855
                else {
1856
                        r = pidref_set_self(ret_pid);
21,291✔
1857
                        if (r < 0) {
21,291✔
1858
                                log_full_errno(prio, r, "Failed to acquire PID reference on ourselves: %m");
×
1859
                                _exit(EXIT_FAILURE);
×
1860
                        }
1861
                }
1862
        }
1863

1864
        return 0;
1865
}
1866

1867
int safe_fork_full(
9,012✔
1868
                const char *name,
1869
                const int stdio_fds[3],
1870
                int except_fds[],
1871
                size_t n_except_fds,
1872
                ForkFlags flags,
1873
                pid_t *ret_pid) {
1874

1875
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
17,427✔
1876
        int r;
9,012✔
1877

1878
        /* Getting the detached child process pid without pidfd is racy, so don't allow it if not returning
1879
         * a pidref to the caller. */
1880
        assert(!FLAGS_SET(flags, FORK_DETACH) || !ret_pid);
9,012✔
1881

1882
        r = pidref_safe_fork_full(name, stdio_fds, except_fds, n_except_fds, flags|_FORK_PID_ONLY, ret_pid ? &pidref : NULL);
10,394✔
1883
        if (r < 0 || !ret_pid)
17,427✔
1884
                return r;
1885

1886
        *ret_pid = pidref.pid;
14,651✔
1887

1888
        return r;
14,651✔
1889
}
1890

1891
int namespace_fork(
224✔
1892
                const char *outer_name,
1893
                const char *inner_name,
1894
                int except_fds[],
1895
                size_t n_except_fds,
1896
                ForkFlags flags,
1897
                int pidns_fd,
1898
                int mntns_fd,
1899
                int netns_fd,
1900
                int userns_fd,
1901
                int root_fd,
1902
                pid_t *ret_pid) {
1903

1904
        int r;
224✔
1905

1906
        /* This is much like safe_fork(), but forks twice, and joins the specified namespaces in the middle
1907
         * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
1908
         * /proc/self/fd works correctly. */
1909

1910
        r = safe_fork_full(outer_name,
629✔
1911
                           NULL,
1912
                           except_fds, n_except_fds,
1913
                           (flags|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
224✔
1914
        if (r < 0)
405✔
1915
                return r;
1916
        if (r == 0) {
405✔
1917
                pid_t pid;
181✔
1918

1919
                /* Child */
1920

1921
                r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd);
181✔
1922
                if (r < 0) {
181✔
1923
                        log_full_errno(FLAGS_SET(flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG, r, "Failed to join namespace: %m");
×
1924
                        _exit(EXIT_FAILURE);
×
1925
                }
1926

1927
                /* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */
1928
                r = safe_fork_full(inner_name,
544✔
1929
                                   NULL,
1930
                                   except_fds, n_except_fds,
1931
                                   flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO), &pid);
181✔
1932
                if (r < 0)
363✔
1933
                        _exit(EXIT_FAILURE);
×
1934
                if (r == 0) {
363✔
1935
                        /* Child */
1936
                        if (ret_pid)
182✔
1937
                                *ret_pid = pid;
182✔
1938
                        return 0;
182✔
1939
                }
1940

1941
                r = wait_for_terminate_and_check(inner_name, pid, FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
362✔
1942
                if (r < 0)
181✔
1943
                        _exit(EXIT_FAILURE);
×
1944

1945
                _exit(r);
181✔
1946
        }
1947

1948
        return 1;
1949
}
1950

1951
int set_oom_score_adjust(int value) {
3,724✔
1952
        char t[DECIMAL_STR_MAX(int)];
3,724✔
1953

1954
        if (!oom_score_adjust_is_valid(value))
3,724✔
1955
                return -EINVAL;
3,724✔
1956

1957
        xsprintf(t, "%i", value);
3,724✔
1958

1959
        return write_string_file("/proc/self/oom_score_adj", t,
3,724✔
1960
                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
1961
}
1962

1963
int get_oom_score_adjust(int *ret) {
2,349✔
1964
        _cleanup_free_ char *t = NULL;
2,349✔
1965
        int r, a;
2,349✔
1966

1967
        r = read_virtual_file("/proc/self/oom_score_adj", SIZE_MAX, &t, NULL);
2,349✔
1968
        if (r < 0)
2,349✔
1969
                return r;
1970

1971
        delete_trailing_chars(t, WHITESPACE);
2,349✔
1972

1973
        r = safe_atoi(t, &a);
2,349✔
1974
        if (r < 0)
2,349✔
1975
                return r;
1976

1977
        if (!oom_score_adjust_is_valid(a))
2,349✔
1978
                return -ENODATA;
1979

1980
        if (ret)
2,349✔
1981
                *ret = a;
2,349✔
1982

1983
        return 0;
1984
}
1985

1986
static int rlimit_to_nice(rlim_t limit) {
2✔
1987
        if (limit <= 1)
2✔
1988
                return PRIO_MAX-1; /* i.e. 19 */
1989

1990
        if (limit >= -PRIO_MIN + PRIO_MAX)
2✔
1991
                return PRIO_MIN; /* i.e. -20 */
1992

1993
        return PRIO_MAX - (int) limit;
2✔
1994
}
1995

1996
int setpriority_closest(int priority) {
27✔
1997
        struct rlimit highest;
27✔
1998
        int r, current, limit;
27✔
1999

2000
        /* Try to set requested nice level */
2001
        r = RET_NERRNO(setpriority(PRIO_PROCESS, 0, priority));
27✔
2002
        if (r >= 0)
2✔
2003
                return 1;
25✔
2004
        if (!ERRNO_IS_NEG_PRIVILEGE(r))
2✔
2005
                return r;
2006

2007
        errno = 0;
2✔
2008
        current = getpriority(PRIO_PROCESS, 0);
2✔
2009
        if (errno != 0)
2✔
2010
                return -errno;
×
2011

2012
        if (priority == current)
2✔
2013
                return 1;
2014

2015
       /* Hmm, we'd expect that raising the nice level from our status quo would always work. If it doesn't,
2016
        * then the whole setpriority() system call is blocked to us, hence let's propagate the error
2017
        * right-away */
2018
        if (priority > current)
2✔
2019
                return r;
2020

2021
        if (getrlimit(RLIMIT_NICE, &highest) < 0)
2✔
2022
                return -errno;
×
2023

2024
        limit = rlimit_to_nice(highest.rlim_cur);
2✔
2025

2026
        /* Push to the allowed limit if we're higher than that. Note that we could also be less nice than
2027
         * limit allows us, but still higher than what's requested. In that case our current value is
2028
         * the best choice. */
2029
        if (current > limit)
2✔
2030
                if (setpriority(PRIO_PROCESS, 0, limit) < 0)
2✔
2031
                        return -errno;
×
2032

2033
        log_debug("Cannot set requested nice level (%i), using next best (%i).", priority, MIN(current, limit));
2✔
2034
        return 0;
2035
}
2036

2037
_noreturn_ void freeze(void) {
×
2038
        log_close();
×
2039

2040
        /* Make sure nobody waits for us (i.e. on one of our sockets) anymore. Note that we use
2041
         * close_all_fds_without_malloc() instead of plain close_all_fds() here, since we want this function
2042
         * to be compatible with being called from signal handlers. */
2043
        (void) close_all_fds_without_malloc(NULL, 0);
×
2044

2045
        /* Let's not freeze right away, but keep reaping zombies. */
2046
        for (;;) {
×
2047
                siginfo_t si = {};
×
2048

2049
                if (waitid(P_ALL, 0, &si, WEXITED) < 0 && errno != EINTR)
×
2050
                        break;
2051
        }
2052

2053
        /* waitid() failed with an ECHLD error (because there are no left-over child processes) or any other
2054
         * (unexpected) error. Freeze for good now! */
2055
        for (;;)
×
2056
                pause();
×
2057
}
2058

2059
int get_process_threads(pid_t pid) {
7✔
2060
        _cleanup_free_ char *t = NULL;
7✔
2061
        int n, r;
7✔
2062

2063
        if (pid < 0)
7✔
2064
                return -EINVAL;
2065

2066
        r = procfs_file_get_field(pid, "status", "Threads", &t);
7✔
2067
        if (r == -ENOENT)
7✔
2068
                return -ESRCH;
2069
        if (r < 0)
7✔
2070
                return r;
2071

2072
        r = safe_atoi(t, &n);
7✔
2073
        if (r < 0)
7✔
2074
                return r;
2075
        if (n < 0)
7✔
2076
                return -EINVAL;
×
2077

2078
        return n;
2079
}
2080

2081
int is_reaper_process(void) {
3,631✔
2082
        int b = 0;
3,631✔
2083

2084
        /* Checks if we are running in a reaper process, i.e. if we are expected to deal with processes
2085
         * reparented to us. This simply checks if we are PID 1 or if PR_SET_CHILD_SUBREAPER was called. */
2086

2087
        if (getpid_cached() == 1)
3,631✔
2088
                return true;
3,631✔
2089

2090
        if (prctl(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0UL, 0UL, 0UL) < 0)
349✔
2091
                return -errno;
×
2092

2093
        return b != 0;
349✔
2094
}
2095

2096
int make_reaper_process(bool b) {
677✔
2097

2098
        if (getpid_cached() == 1) {
677✔
2099

2100
                if (!b)
52✔
2101
                        return -EINVAL;
2102

2103
                return 0;
52✔
2104
        }
2105

2106
        /* Some prctl()s insist that all 5 arguments are specified, others do not. Let's always specify all,
2107
         * to avoid any ambiguities */
2108
        if (prctl(PR_SET_CHILD_SUBREAPER, (unsigned long) b, 0UL, 0UL, 0UL) < 0)
625✔
2109
                return -errno;
×
2110

2111
        return 0;
2112
}
2113

2114
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(posix_spawnattr_t*, posix_spawnattr_destroy, NULL);
×
2115

2116
int posix_spawn_wrapper(
2,435✔
2117
                const char *path,
2118
                char * const *argv,
2119
                char * const *envp,
2120
                const char *cgroup,
2121
                PidRef *ret_pidref) {
2122

2123
        short flags = POSIX_SPAWN_SETSIGMASK;
2,435✔
2124
        posix_spawnattr_t attr;
2,435✔
2125
        sigset_t mask;
2,435✔
2126
        int r;
2,435✔
2127

2128
        /* Forks and invokes 'path' with 'argv' and 'envp' using CLONE_VM and CLONE_VFORK, which means the
2129
         * caller will be blocked until the child either exits or exec's. The memory of the child will be
2130
         * fully shared with the memory of the parent, so that there are no copy-on-write or memory.max
2131
         * issues.
2132
         *
2133
         * Also, move the newly-created process into 'cgroup' through POSIX_SPAWN_SETCGROUP (clone3())
2134
         * if available.
2135
         * returns 1: We're already in the right cgroup
2136
         *         0: 'cgroup' not specified or POSIX_SPAWN_SETCGROUP is not supported. The caller
2137
         *            needs to call 'cg_attach' on their own */
2138

2139
        assert(path);
2,435✔
2140
        assert(argv);
2,435✔
2141
        assert(ret_pidref);
2,435✔
2142

2143
        assert_se(sigfillset(&mask) >= 0);
2,435✔
2144

2145
        r = posix_spawnattr_init(&attr);
2,435✔
2146
        if (r != 0)
2,435✔
2147
                return -r; /* These functions return a positive errno on failure */
2,435✔
2148

2149
        /* Initialization needs to succeed before we can set up a destructor. */
2150
        _unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr;
4,870✔
2151

2152
#if HAVE_PIDFD_SPAWN
2153
        static bool have_clone_into_cgroup = true; /* kernel 5.7+ */
2,435✔
2154
        _cleanup_close_ int cgroup_fd = -EBADF;
2,435✔
2155

2156
        if (cgroup && have_clone_into_cgroup) {
2,435✔
2157
                _cleanup_free_ char *resolved_cgroup = NULL;
2,435✔
2158

2159
                r = cg_get_path(cgroup, /* suffix= */ NULL, &resolved_cgroup);
2,435✔
2160
                if (r < 0)
2,435✔
2161
                        return r;
2162

2163
                cgroup_fd = open(resolved_cgroup, O_PATH|O_DIRECTORY|O_CLOEXEC);
2,435✔
2164
                if (cgroup_fd < 0)
2,435✔
2165
                        return -errno;
×
2166

2167
                r = posix_spawnattr_setcgroup_np(&attr, cgroup_fd);
2,435✔
2168
                if (r != 0)
2,435✔
2169
                        return -r;
×
2170

2171
                flags |= POSIX_SPAWN_SETCGROUP;
2,435✔
2172
        }
2173
#endif
2174

2175
        r = posix_spawnattr_setflags(&attr, flags);
2,435✔
2176
        if (r != 0)
2,435✔
2177
                return -r;
×
2178
        r = posix_spawnattr_setsigmask(&attr, &mask);
2,435✔
2179
        if (r != 0)
2,435✔
2180
                return -r;
×
2181

2182
#if HAVE_PIDFD_SPAWN
2183
        _cleanup_close_ int pidfd = -EBADF;
2,435✔
2184

2185
        r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
2,435✔
2186
        if (ERRNO_IS_NOT_SUPPORTED(r) && FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP) && cg_is_threaded(cgroup) > 0)
2,435✔
2187
                return -EUCLEAN; /* clone3() could also return EOPNOTSUPP if the target cgroup is in threaded mode,
2188
                                    turn that into something recognizable */
2189
        if ((ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || r == E2BIG) &&
2,435✔
2190
            FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP)) {
2191
                /* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but
2192
                 * need to disable POSIX_SPAWN_SETCGROUP, which is what redirects to clone3().
2193
                 * Note that we might get E2BIG here since some kernels (e.g. 5.4) support clone3()
2194
                 * but not CLONE_INTO_CGROUP. */
2195

2196
                /* CLONE_INTO_CGROUP definitely won't work, hence remember the fact so that we don't
2197
                 * retry every time. */
2198
                have_clone_into_cgroup = false;
×
2199

2200
                flags &= ~POSIX_SPAWN_SETCGROUP;
×
2201
                r = posix_spawnattr_setflags(&attr, flags);
×
2202
                if (r != 0)
×
2203
                        return -r;
×
2204

2205
                r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
×
2206
        }
2207
        if (r != 0)
2,435✔
2208
                return -r;
×
2209

2210
        r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
2,435✔
2211
        if (r < 0)
2,435✔
2212
                return r;
2213

2214
        return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
2,435✔
2215
#else
2216
        pid_t pid;
2217

2218
        r = posix_spawn(&pid, path, NULL, &attr, argv, envp);
2219
        if (r != 0)
2220
                return -r;
2221

2222
        r = pidref_set_pid(ret_pidref, pid);
2223
        if (r < 0)
2224
                return r;
2225

2226
        return 0; /* We did not use CLONE_INTO_CGROUP so return 0, the caller will have to move the child */
2227
#endif
2228
}
2229

2230
int proc_dir_open(DIR **ret) {
13✔
2231
        DIR *d;
13✔
2232

2233
        assert(ret);
13✔
2234

2235
        d = opendir("/proc");
13✔
2236
        if (!d)
13✔
2237
                return -errno;
×
2238

2239
        *ret = d;
13✔
2240
        return 0;
13✔
2241
}
2242

2243
int proc_dir_read(DIR *d, pid_t *ret) {
1,171✔
2244
        assert(d);
1,171✔
2245

2246
        for (;;) {
1,955✔
2247
                struct dirent *de;
1,955✔
2248

2249
                errno = 0;
1,955✔
2250
                de = readdir_no_dot(d);
1,955✔
2251
                if (!de) {
1,955✔
2252
                        if (errno != 0)
13✔
2253
                                return -errno;
×
2254

2255
                        break;
13✔
2256
                }
2257

2258
                if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
1,942✔
2259
                        continue;
641✔
2260

2261
                if (parse_pid(de->d_name, ret) >= 0)
1,301✔
2262
                        return 1;
2263
        }
2264

2265
        if (ret)
13✔
2266
                *ret = 0;
13✔
2267
        return 0;
2268
}
2269

2270
int proc_dir_read_pidref(DIR *d, PidRef *ret) {
1,129✔
2271
        int r;
1,129✔
2272

2273
        assert(d);
1,129✔
2274

2275
        for (;;) {
1,129✔
2276
                pid_t pid;
1,129✔
2277

2278
                r = proc_dir_read(d, &pid);
1,129✔
2279
                if (r < 0)
1,129✔
2280
                        return r;
1,117✔
2281
                if (r == 0)
1,129✔
2282
                        break;
2283

2284
                r = pidref_set_pid(ret, pid);
1,117✔
2285
                if (r == -ESRCH) /* gone by now? skip it */
1,117✔
2286
                        continue;
×
2287
                if (r < 0)
1,117✔
2288
                        return r;
×
2289

2290
                return 1;
2291
        }
2292

2293
        if (ret)
12✔
2294
                *ret = PIDREF_NULL;
12✔
2295
        return 0;
2296
}
2297

2298
static const char *const sigchld_code_table[] = {
2299
        [CLD_EXITED] = "exited",
2300
        [CLD_KILLED] = "killed",
2301
        [CLD_DUMPED] = "dumped",
2302
        [CLD_TRAPPED] = "trapped",
2303
        [CLD_STOPPED] = "stopped",
2304
        [CLD_CONTINUED] = "continued",
2305
};
2306

2307
DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
8,846✔
2308

2309
static const char* const sched_policy_table[] = {
2310
        [SCHED_OTHER] = "other",
2311
        [SCHED_BATCH] = "batch",
2312
        [SCHED_IDLE] = "idle",
2313
        [SCHED_FIFO] = "fifo",
2314
        [SCHED_RR] = "rr",
2315
};
2316

2317
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
52✔
2318

2319
_noreturn_ void report_errno_and_exit(int errno_fd, int error) {
64✔
2320
        int r;
64✔
2321

2322
        if (error >= 0)
64✔
2323
                _exit(EXIT_SUCCESS);
63✔
2324

2325
        assert(errno_fd >= 0);
1✔
2326

2327
        r = loop_write(errno_fd, &error, sizeof(error));
1✔
2328
        if (r < 0)
1✔
2329
                log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd);
×
2330

2331
        _exit(EXIT_FAILURE);
1✔
2332
}
2333

2334
int read_errno(int errno_fd) {
3✔
2335
        int r;
3✔
2336

2337
        assert(errno_fd >= 0);
3✔
2338

2339
        /* The issue here is that it's impossible to distinguish between an error code returned by child and
2340
         * IO error arose when reading it. So, the function logs errors and return EIO for the later case. */
2341

2342
        ssize_t n = loop_read(errno_fd, &r, sizeof(r), /* do_poll = */ false);
3✔
2343
        if (n < 0) {
3✔
2344
                log_debug_errno(n, "Failed to read errno: %m");
×
2345
                return -EIO;
×
2346
        }
2347
        if (n == sizeof(r)) {
3✔
2348
                if (r == 0)
×
2349
                        return 0;
2350
                if (r < 0) /* child process reported an error, return it */
×
2351
                        return log_debug_errno(r, "Child process failed with errno: %m");
×
2352
                return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received an errno, but it's a positive value.");
×
2353
        }
2354
        if (n != 0)
3✔
2355
                return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received unexpected amount of bytes while reading errno.");
×
2356

2357
        /* the process exited without reporting an error, assuming success */
2358
        return 0;
2359
}
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