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

systemd / systemd / 13846995901

13 Mar 2025 08:25PM UTC coverage: 71.9% (+0.04%) from 71.864%
13846995901

push

github

yuwata
mkosi: update debian commit reference

* d8c7f8f7f4 Update changelog for 257.4-2 release
* f74cf88300 Split bootctl to new systemd-boot-tools package
* 10a8764966 Update changelog for 257.4-1 release

295942 of 411600 relevant lines covered (71.9%)

714834.66 hits per line

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

92.64
/src/basic/fileio.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <ctype.h>
4
#include <errno.h>
5
#include <fcntl.h>
6
#include <limits.h>
7
#include <stdarg.h>
8
#include <stdint.h>
9
#include <stdio_ext.h>
10
#include <stdlib.h>
11
#include <sys/stat.h>
12
#include <sys/types.h>
13
#include <unistd.h>
14

15
#include "alloc-util.h"
16
#include "chase.h"
17
#include "extract-word.h"
18
#include "fd-util.h"
19
#include "fileio.h"
20
#include "fs-util.h"
21
#include "hexdecoct.h"
22
#include "label.h"
23
#include "log.h"
24
#include "macro.h"
25
#include "mkdir.h"
26
#include "nulstr-util.h"
27
#include "parse-util.h"
28
#include "path-util.h"
29
#include "socket-util.h"
30
#include "stdio-util.h"
31
#include "string-util.h"
32
#include "sync-util.h"
33
#include "terminal-util.h"
34
#include "tmpfile-util.h"
35

36
/* The maximum size of the file we'll read in one go in read_full_file() (64M). */
37
#define READ_FULL_BYTES_MAX (64U * U64_MB - UINT64_C(1))
38
/* Used when a size is specified for read_full_file() with READ_FULL_FILE_UNBASE64 or _UNHEX */
39
#define READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY 3
40

41
/* The maximum size of virtual files (i.e. procfs, sysfs, and other virtual "API" files) we'll read in one go
42
 * in read_virtual_file(). Note that this limit is different (and much lower) than the READ_FULL_BYTES_MAX
43
 * limit. This reflects the fact that we use different strategies for reading virtual and regular files:
44
 * virtual files we generally have to read in a single read() syscall since the kernel doesn't support
45
 * continuation read()s for them. Thankfully they are somewhat size constrained. Thus we can allocate the
46
 * full potential buffer in advance. Regular files OTOH can be much larger, and there we grow the allocations
47
 * exponentially in a loop. We use a size limit of 4M-2 because 4M-1 is the maximum buffer that /proc/sys/
48
 * allows us to read() (larger reads will fail with ENOMEM), and we want to read one extra byte so that we
49
 * can detect EOFs. */
50
#define READ_VIRTUAL_BYTES_MAX (4U * U64_MB - UINT64_C(2))
51

52
int fdopen_unlocked(int fd, const char *options, FILE **ret) {
422,006✔
53
        assert(ret);
422,006✔
54

55
        FILE *f = fdopen(fd, options);
422,006✔
56
        if (!f)
422,006✔
57
                return -errno;
×
58

59
        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
422,006✔
60

61
        *ret = f;
422,006✔
62
        return 0;
422,006✔
63
}
64

65
int take_fdopen_unlocked(int *fd, const char *options, FILE **ret) {
422,006✔
66
        int r;
422,006✔
67

68
        assert(fd);
422,006✔
69

70
        r = fdopen_unlocked(*fd, options, ret);
422,006✔
71
        if (r < 0)
422,006✔
72
                return r;
73

74
        *fd = -EBADF;
422,006✔
75

76
        return 0;
422,006✔
77
}
78

79
FILE* take_fdopen(int *fd, const char *options) {
40,604✔
80
        assert(fd);
40,604✔
81

82
        FILE *f = fdopen(*fd, options);
40,604✔
83
        if (!f)
40,604✔
84
                return NULL;
85

86
        *fd = -EBADF;
40,604✔
87

88
        return f;
40,604✔
89
}
90

91
DIR* take_fdopendir(int *dfd) {
230,734✔
92
        assert(dfd);
230,734✔
93

94
        DIR *d = fdopendir(*dfd);
230,734✔
95
        if (!d)
230,734✔
96
                return NULL;
97

98
        *dfd = -EBADF;
230,734✔
99

100
        return d;
230,734✔
101
}
102

103
FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc) {
517,988✔
104
        FILE *f = open_memstream(ptr, sizeloc);
517,988✔
105
        if (!f)
517,988✔
106
                return NULL;
107

108
        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
517,988✔
109

110
        return f;
517,988✔
111
}
112

113
FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode) {
103✔
114
        FILE *f = fmemopen(buf, size, mode);
103✔
115
        if (!f)
103✔
116
                return NULL;
117

118
        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
103✔
119

120
        return f;
103✔
121
}
122

123
int write_string_stream_full(
212,764✔
124
                FILE *f,
125
                const char *line,
126
                WriteStringFileFlags flags,
127
                const struct timespec *ts) {
128

129
        bool needs_nl;
212,764✔
130
        int r, fd = -EBADF;
212,764✔
131

132
        assert(f);
212,764✔
133
        assert(line);
212,764✔
134

135
        if (ferror(f))
212,764✔
136
                return -EIO;
137

138
        if (ts) {
212,764✔
139
                /* If we shall set the timestamp we need the fd. But fmemopen() streams generally don't have
140
                 * an fd. Let's fail early in that case. */
141
                fd = fileno(f);
202✔
142
                if (fd < 0)
202✔
143
                        return -EBADF;
144
        }
145

146
        if (flags & WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) {
212,764✔
147
                _cleanup_free_ char *t = NULL;
9,426✔
148

149
                /* If value to be written is same as that of the existing value, then suppress the write. */
150

151
                if (fd < 0) {
9,426✔
152
                        fd = fileno(f);
9,426✔
153
                        if (fd < 0)
9,426✔
154
                                return -EBADF;
155
                }
156

157
                /* Read an additional byte to detect cases where the prefix matches but the rest
158
                 * doesn't. Also, 0 returned by read_virtual_file_fd() means the read was truncated and
159
                 * it won't be equal to the new value. */
160
                if (read_virtual_file_fd(fd, strlen(line)+1, &t, NULL) > 0 &&
18,806✔
161
                    streq_skip_trailing_chars(line, t, NEWLINE)) {
9,380✔
162
                        log_debug("No change in value '%s', suppressing write", line);
6,882✔
163
                        return 0;
6,882✔
164
                }
165

166
                if (lseek(fd, 0, SEEK_SET) < 0)
2,544✔
167
                        return -errno;
×
168
        }
169

170
        needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");
205,882✔
171

172
        if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
46,880✔
173
                /* If STDIO buffering was disabled, then let's append the newline character to the string
174
                 * itself, so that the write goes out in one go, instead of two */
175

176
                line = strjoina(line, "\n");
228,605✔
177
                needs_nl = false;
45,721✔
178
        }
179

180
        if (fputs(line, f) == EOF)
205,882✔
181
                return -errno;
74✔
182

183
        if (needs_nl)
205,808✔
184
                if (fputc('\n', f) == EOF)
1,158✔
185
                        return -errno;
×
186

187
        if (flags & WRITE_STRING_FILE_SYNC)
205,808✔
188
                r = fflush_sync_and_check(f);
1,703✔
189
        else
190
                r = fflush_and_check(f);
204,105✔
191
        if (r < 0)
205,808✔
192
                return r;
193

194
        if (ts) {
205,796✔
195
                const struct timespec twice[2] = {*ts, *ts};
202✔
196

197
                assert(fd >= 0);
202✔
198
                if (futimens(fd, twice) < 0)
202✔
199
                        return -errno;
×
200
        }
201

202
        return 0;
203
}
204

205
static mode_t write_string_file_flags_to_mode(WriteStringFileFlags flags) {
90,762✔
206

207
        /* We support three different modes, that are the ones that really make sense for text files like this:
208
         *
209
         *     → 0600 (i.e. root-only)
210
         *     → 0444 (i.e. read-only)
211
         *     → 0644 (i.e. writable for root, readable for everyone else)
212
         */
213

214
        return FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 :
90,762✔
215
                FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0444) ? 0444 : 0644;
90,657✔
216
}
217

218
static int write_string_file_atomic_at(
2,319✔
219
                int dir_fd,
220
                const char *fn,
221
                const char *line,
222
                WriteStringFileFlags flags,
223
                const struct timespec *ts) {
224

225
        _cleanup_fclose_ FILE *f = NULL;
2,319✔
226
        _cleanup_free_ char *p = NULL;
2,319✔
227
        int r;
2,319✔
228

229
        assert(fn);
2,319✔
230
        assert(line);
2,319✔
231

232
        /* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement
233
         * semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */
234

235
        mode_t mode = write_string_file_flags_to_mode(flags);
2,319✔
236

237
        bool call_label_ops_post = false;
2,319✔
238
        if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) {
2,319✔
239
                r = label_ops_pre(dir_fd, fn, mode);
358✔
240
                if (r < 0)
358✔
241
                        return r;
242

243
                call_label_ops_post = true;
244
        }
245

246
        r = fopen_temporary_at(dir_fd, fn, &f, &p);
2,319✔
247
        if (call_label_ops_post)
2,319✔
248
                /* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures
249
                 * in label_ops_post(). */
250
                RET_GATHER(r, label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f));
716✔
251
        if (r < 0)
2,319✔
252
                goto fail;
1✔
253

254
        r = write_string_stream_full(f, line, flags, ts);
2,318✔
255
        if (r < 0)
2,318✔
256
                goto fail;
×
257

258
        r = fchmod_umask(fileno(f), mode);
2,318✔
259
        if (r < 0)
2,318✔
260
                goto fail;
×
261

262
        r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
2,318✔
263
        if (r < 0)
×
264
                goto fail;
×
265

266
        if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
2,318✔
267
                /* Sync the rename, too */
268
                r = fsync_directory_of_file(fileno(f));
1,703✔
269
                if (r < 0)
1,703✔
270
                        return r;
×
271
        }
272

273
        return 0;
274

275
fail:
1✔
276
        if (f)
1✔
277
                (void) unlinkat(dir_fd, p, 0);
×
278
        return r;
279
}
280

281
int write_string_file_full(
187,531✔
282
                int dir_fd,
283
                const char *fn,
284
                const char *line,
285
                WriteStringFileFlags flags,
286
                const struct timespec *ts,
287
                const char *label_fn) {
288

289
        bool made_file = false;
187,531✔
290
        _cleanup_fclose_ FILE *f = NULL;
187,531✔
291
        _cleanup_close_ int fd = -EBADF;
187,531✔
292
        int r;
187,531✔
293

294
        assert(dir_fd == AT_FDCWD || dir_fd >= 0);
187,531✔
295
        assert(line);
187,531✔
296

297
        /* We don't know how to verify whether the file contents was already on-disk. */
298
        assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC)));
187,531✔
299

300
        if (flags & WRITE_STRING_FILE_MKDIR_0755) {
187,531✔
301
                assert(fn);
252✔
302

303
                r = mkdirat_parents(dir_fd, fn, 0755);
252✔
304
                if (r < 0)
252✔
305
                        return r;
306
        }
307

308
        if (flags & WRITE_STRING_FILE_ATOMIC) {
187,531✔
309
                assert(fn);
2,319✔
310
                assert(flags & WRITE_STRING_FILE_CREATE);
2,319✔
311

312
                r = write_string_file_atomic_at(dir_fd, fn, line, flags, ts);
2,319✔
313
                if (r < 0)
2,319✔
314
                        goto fail;
1✔
315

316
                return r;
317
        }
318

319
        /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
320
        if (isempty(fn))
185,212✔
321
                r = fd = fd_reopen(
96,769✔
322
                                ASSERT_FD(dir_fd), O_CLOEXEC | O_NOCTTY |
96,769✔
323
                                (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
96,769✔
324
                                (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY));
96,769✔
325
        else {
326
                mode_t mode = write_string_file_flags_to_mode(flags);
88,443✔
327
                bool call_label_ops_post = false;
88,443✔
328

329
                if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
88,443✔
330
                        r = label_ops_pre(dir_fd, label_fn ?: fn, mode);
359✔
331
                        if (r < 0)
359✔
332
                                goto fail;
×
333

334
                        call_label_ops_post = true;
335
                }
336

337
                r = fd = openat_report_new(
88,443✔
338
                                dir_fd, fn, O_CLOEXEC | O_NOCTTY |
88,443✔
339
                                (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
88,443✔
340
                                (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
88,443✔
341
                                (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
88,443✔
342
                                (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
88,443✔
343
                                mode,
344
                                &made_file);
345
                if (call_label_ops_post)
88,443✔
346
                        /* If openat_report_new() failed in the above, propagate the error code, and ignore
347
                         * failures in label_ops_post(). */
348
                        RET_GATHER(r, label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file));
1,077✔
349
        }
350
        if (r < 0)
185,212✔
351
                goto fail;
1,592✔
352

353
        r = take_fdopen_unlocked(&fd, "w", &f);
183,620✔
354
        if (r < 0)
183,620✔
355
                goto fail;
×
356

357
        if (flags & WRITE_STRING_FILE_DISABLE_BUFFER)
183,620✔
358
                setvbuf(f, NULL, _IONBF, 0);
182,491✔
359

360
        r = write_string_stream_full(f, line, flags, ts);
183,620✔
361
        if (r < 0)
183,620✔
362
                goto fail;
79✔
363

364
        return 0;
365

366
fail:
1,672✔
367
        if (made_file)
1,672✔
368
                (void) unlinkat(dir_fd, fn, 0);
×
369

370
        if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
1,672✔
371
                return r;
372

373
        f = safe_fclose(f);
1,642✔
374
        fd = safe_close(fd);
1,642✔
375

376
        /* OK, the operation failed, but let's see if the right contents in place already. If so, eat up the
377
         * error. */
378
        if (verify_file_at(dir_fd, fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)) > 0)
1,642✔
379
                return 0;
454✔
380

381
        return r;
382
}
383

384
int write_string_filef(
280✔
385
                const char *fn,
386
                WriteStringFileFlags flags,
387
                const char *format, ...) {
388

389
        _cleanup_free_ char *p = NULL;
280✔
390
        va_list ap;
280✔
391
        int r;
280✔
392

393
        va_start(ap, format);
280✔
394
        r = vasprintf(&p, format, ap);
280✔
395
        va_end(ap);
280✔
396

397
        if (r < 0)
280✔
398
                return -ENOMEM;
399

400
        return write_string_file(fn, p, flags);
280✔
401
}
402

403
int write_base64_file_at(
7✔
404
                int dir_fd,
405
                const char *fn,
406
                const struct iovec *data,
407
                WriteStringFileFlags flags) {
408

409
        _cleanup_free_ char *encoded = NULL;
7✔
410
        ssize_t n;
7✔
411

412
        n = base64mem_full(data ? data->iov_base : NULL, data ? data->iov_len : 0, 79, &encoded);
7✔
413
        if (n < 0)
7✔
414
                return n;
×
415

416
        return write_string_file_at(dir_fd, fn, encoded, flags);
7✔
417
}
418

419
int read_one_line_file_at(int dir_fd, const char *filename, char **ret) {
175,742✔
420
        _cleanup_fclose_ FILE *f = NULL;
175,742✔
421
        int r;
175,742✔
422

423
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
175,742✔
424
        assert(filename);
175,742✔
425
        assert(ret);
175,742✔
426

427
        r = fopen_unlocked_at(dir_fd, filename, "re", 0, &f);
175,742✔
428
        if (r < 0)
175,742✔
429
                return r;
430

431
        return read_line(f, LONG_LINE_MAX, ret);
175,742✔
432
}
433

434
int verify_file_at(int dir_fd, const char *fn, const char *blob, bool accept_extra_nl) {
1,642✔
435
        _cleanup_fclose_ FILE *f = NULL;
1,642✔
436
        _cleanup_free_ char *buf = NULL;
1,642✔
437
        size_t l, k;
1,642✔
438
        int r;
1,642✔
439

440
        assert(blob);
1,642✔
441

442
        l = strlen(blob);
1,642✔
443

444
        if (accept_extra_nl && endswith(blob, "\n"))
1,642✔
445
                accept_extra_nl = false;
1✔
446

447
        buf = malloc(l + accept_extra_nl + 1);
1,642✔
448
        if (!buf)
1,642✔
449
                return -ENOMEM;
450

451
        r = fopen_unlocked_at(dir_fd, strempty(fn), "re", 0, &f);
1,642✔
452
        if (r < 0)
1,642✔
453
                return r;
454

455
        /* We try to read one byte more than we need, so that we know whether we hit eof */
456
        errno = 0;
918✔
457
        k = fread(buf, 1, l + accept_extra_nl + 1, f);
918✔
458
        if (ferror(f))
918✔
459
                return errno_or_else(EIO);
×
460

461
        if (k != l && k != l + accept_extra_nl)
918✔
462
                return 0;
463
        if (memcmp(buf, blob, l) != 0)
730✔
464
                return 0;
465
        if (k > l && buf[l] != '\n')
454✔
466
                return 0;
×
467

468
        return 1;
469
}
470

471
int read_virtual_file_at(
982,657✔
472
                int dir_fd,
473
                const char *filename,
474
                size_t max_size,
475
                char **ret_contents,
476
                size_t *ret_size) {
477

478
        _cleanup_free_ char *buf = NULL;
982,657✔
479
        size_t n, size;
982,657✔
480
        int n_retries;
982,657✔
481
        bool truncated = false;
982,657✔
482

483
        /* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work with two sorts of
484
         * virtual files. One sort uses "seq_file", and the results of the first read are buffered for the
485
         * second read. The other sort uses "raw" reads which always go direct to the device. In the latter
486
         * case, the content of the virtual file must be retrieved with a single read otherwise a second read
487
         * might get the new value instead of finding EOF immediately. That's the reason why the usage of
488
         * fread(3) is prohibited in this case as it always performs a second call to read(2) looking for
489
         * EOF. See issue #13585.
490
         *
491
         * max_size specifies a limit on the bytes read. If max_size is SIZE_MAX, the full file is read. If
492
         * the full file is too large to read, an error is returned. For other values of max_size, *partial
493
         * contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on
494
         * partial success, 1 if untruncated contents were read.
495
         *
496
         * Rule: for kernfs files using "seq_file" → use regular read_full_file_at()
497
         *       for kernfs files using "raw" → use read_virtual_file_at()
498
         */
499

500
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
982,657✔
501
        assert(max_size <= READ_VIRTUAL_BYTES_MAX || max_size == SIZE_MAX);
982,657✔
502

503
        _cleanup_close_ int fd = -EBADF;
982,657✔
504
        if (isempty(filename))
982,657✔
505
                fd = fd_reopen(ASSERT_FD(dir_fd), O_RDONLY | O_NOCTTY | O_CLOEXEC);
767,449✔
506
        else
507
                fd = RET_NERRNO(openat(dir_fd, filename, O_RDONLY | O_NOCTTY | O_CLOEXEC));
215,208✔
508
        if (fd < 0)
982,657✔
509
                return fd;
510

511
        /* Limit the number of attempts to read the number of bytes returned by fstat(). */
512
        n_retries = 3;
513

514
        for (;;) {
876,843✔
515
                struct stat st;
876,842✔
516

517
                if (fstat(fd, &st) < 0)
876,842✔
518
                        return -errno;
1,116✔
519

520
                if (!S_ISREG(st.st_mode))
876,842✔
521
                        return -EBADF;
522

523
                /* Be prepared for files from /proc which generally report a file size of 0. */
524
                assert_cc(READ_VIRTUAL_BYTES_MAX < SSIZE_MAX);
876,842✔
525
                if (st.st_size > 0 && n_retries > 1) {
876,842✔
526
                        /* Let's use the file size if we have more than 1 attempt left. On the last attempt
527
                         * we'll ignore the file size */
528

529
                        if (st.st_size > SSIZE_MAX) { /* Avoid overflow with 32-bit size_t and 64-bit off_t. */
664,592✔
530

531
                                if (max_size == SIZE_MAX)
532
                                        return -EFBIG;
533

534
                                size = max_size;
535
                        } else {
536
                                size = MIN((size_t) st.st_size, max_size);
664,592✔
537

538
                                if (size > READ_VIRTUAL_BYTES_MAX)
664,592✔
539
                                        return -EFBIG;
540
                        }
541

542
                        n_retries--;
664,592✔
543
                } else if (n_retries > 1) {
212,250✔
544
                        /* Files in /proc are generally smaller than the page size so let's start with
545
                         * a page size buffer from malloc and only use the max buffer on the final try. */
546
                        size = MIN3(page_size() - 1, READ_VIRTUAL_BYTES_MAX, max_size);
212,249✔
547
                        n_retries = 1;
212,249✔
548
                } else {
549
                        size = MIN(READ_VIRTUAL_BYTES_MAX, max_size);
1✔
550
                        n_retries = 0;
1✔
551
                }
552

553
                buf = malloc(size + 1);
876,842✔
554
                if (!buf)
876,842✔
555
                        return -ENOMEM;
556

557
                /* Use a bigger allocation if we got it anyway, but not more than the limit. */
558
                size = MIN3(MALLOC_SIZEOF_SAFE(buf) - 1, max_size, READ_VIRTUAL_BYTES_MAX);
876,842✔
559

560
                for (;;) {
876,842✔
561
                        ssize_t k;
876,842✔
562

563
                        /* Read one more byte so we can detect whether the content of the
564
                         * file has already changed or the guessed size for files from /proc
565
                         * wasn't large enough . */
566
                        k = read(fd, buf, size + 1);
876,842✔
567
                        if (k >= 0) {
876,842✔
568
                                n = k;
875,726✔
569
                                break;
875,726✔
570
                        }
571

572
                        if (errno != EINTR)
1,116✔
573
                                return -errno;
1,116✔
574
                }
575

576
                /* Consider a short read as EOF */
577
                if (n <= size)
875,726✔
578
                        break;
579

580
                /* If a maximum size is specified and we already read more we know the file is larger, and
581
                 * can handle this as truncation case. Note that if the size of what we read equals the
582
                 * maximum size then this doesn't mean truncation, the file might or might not end on that
583
                 * byte. We need to rerun the loop in that case, with a larger buffer size, so that we read
584
                 * at least one more byte to be able to distinguish EOF from truncation. */
585
                if (max_size != SIZE_MAX && n > max_size) {
41,052✔
586
                        n = size; /* Make sure we never use more than what we sized the buffer for (so that
587
                                   * we have one free byte in it for the trailing NUL we add below). */
588
                        truncated = true;
589
                        break;
590
                }
591

592
                /* We have no further attempts left? Then the file is apparently larger than our limits. Give up. */
593
                if (n_retries <= 0)
1✔
594
                        return -EFBIG;
595

596
                /* Hmm... either we read too few bytes from /proc or less likely the content of the file
597
                 * might have been changed (and is now bigger) while we were processing, let's try again
598
                 * either with the new file size. */
599

600
                if (lseek(fd, 0, SEEK_SET) < 0)
1✔
601
                        return -errno;
×
602

603
                buf = mfree(buf);
1✔
604
        }
605

606
        if (ret_contents) {
875,725✔
607

608
                /* Safety check: if the caller doesn't want to know the size of what we just read it will
609
                 * rely on the trailing NUL byte. But if there's an embedded NUL byte, then we should refuse
610
                 * operation as otherwise there'd be ambiguity about what we just read. */
611
                if (!ret_size && memchr(buf, 0, n))
834,784✔
612
                        return -EBADMSG;
613

614
                if (n < size) {
834,784✔
615
                        char *p;
826,096✔
616

617
                        /* Return rest of the buffer to libc */
618
                        p = realloc(buf, n + 1);
826,096✔
619
                        if (!p)
826,096✔
620
                                return -ENOMEM;
621
                        buf = p;
826,096✔
622
                }
623

624
                buf[n] = 0;
834,784✔
625
                *ret_contents = TAKE_PTR(buf);
834,784✔
626
        }
627

628
        if (ret_size)
875,725✔
629
                *ret_size = n;
677,687✔
630

631
        return !truncated;
875,725✔
632
}
633

634
int read_full_stream_full(
457,346✔
635
                FILE *f,
636
                const char *filename,
637
                uint64_t offset,
638
                size_t size,
639
                ReadFullFileFlags flags,
640
                char **ret_contents,
641
                size_t *ret_size) {
642

643
        _cleanup_free_ char *buf = NULL;
457,346✔
644
        size_t n, n_next = 0, l, expected_decoded_size = size;
457,346✔
645
        int fd, r;
457,346✔
646

647
        assert(f);
457,346✔
648
        assert(ret_contents);
457,346✔
649
        assert(!FLAGS_SET(flags, READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX));
457,346✔
650
        assert(size != SIZE_MAX || !FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER));
457,346✔
651

652
        if (offset != UINT64_MAX && offset > LONG_MAX) /* fseek() can only deal with "long" offsets */
457,346✔
653
                return -ERANGE;
654

655
        if ((flags & (READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX)) != 0) {
457,346✔
656
                if (size <= SIZE_MAX / READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY)
34✔
657
                        size *= READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY;
32✔
658
                else
659
                        size = SIZE_MAX;
660
        }
661

662
        fd = fileno(f);
457,346✔
663
        if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see
457,346✔
664
                        * fmemopen()), let's optimize our buffering */
665
                struct stat st;
457,256✔
666

667
                if (fstat(fd, &st) < 0)
457,256✔
668
                        return -errno;
×
669

670
                if (S_ISREG(st.st_mode)) {
457,256✔
671

672
                        /* Try to start with the right file size if we shall read the file in full. Note
673
                         * that we increase the size to read here by one, so that the first read attempt
674
                         * already makes us notice the EOF. If the reported size of the file is zero, we
675
                         * avoid this logic however, since quite likely it might be a virtual file in procfs
676
                         * that all report a zero file size. */
677

678
                        if (st.st_size > 0 &&
456,846✔
679
                            (size == SIZE_MAX || FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER))) {
1,199✔
680

681
                                uint64_t rsize =
1,279,512✔
682
                                        LESS_BY((uint64_t) st.st_size, offset == UINT64_MAX ? 0 : offset);
853,002✔
683

684
                                if (rsize < SIZE_MAX) /* overflow check */
426,504✔
685
                                        n_next = rsize + 1;
426,504✔
686
                        }
687

688
                        if (flags & READ_FULL_FILE_WARN_WORLD_READABLE)
456,846✔
689
                                (void) warn_file_is_world_accessible(filename, &st, NULL, 0);
128✔
690
                }
691
        }
692

693
        /* If we don't know how much to read, figure it out now. If we shall read a part of the file, then
694
         * allocate the requested size. If we shall load the full file start with LINE_MAX. Note that if
695
         * READ_FULL_FILE_FAIL_WHEN_LARGER we consider the specified size a safety limit, and thus also start
696
         * with LINE_MAX, under assumption the file is most likely much shorter. */
697
        if (n_next == 0)
457,256✔
698
                n_next = size != SIZE_MAX && !FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER) ? size : LINE_MAX;
30,842✔
699

700
        /* Never read more than we need to determine that our own limit is hit */
701
        if (n_next > READ_FULL_BYTES_MAX)
426,850✔
702
                n_next = READ_FULL_BYTES_MAX + 1;
×
703

704
        if (offset != UINT64_MAX && fseek(f, offset, SEEK_SET) < 0)
457,346✔
705
                return -errno;
×
706

707
        n = l = 0;
708
        for (;;) {
457,636✔
709
                char *t;
457,491✔
710
                size_t k;
457,491✔
711

712
                /* If we shall fail when reading overly large data, then read exactly one byte more than the
713
                 * specified size at max, since that'll tell us if there's anymore data beyond the limit. */
714
                if (FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER) && n_next > size)
457,491✔
715
                        n_next = size + 1;
8✔
716

717
                if (flags & READ_FULL_FILE_SECURE) {
457,491✔
718
                        t = malloc(n_next + 1);
1,397✔
719
                        if (!t) {
1,397✔
720
                                r = -ENOMEM;
×
721
                                goto finalize;
×
722
                        }
723
                        memcpy_safe(t, buf, n);
1,397✔
724
                        explicit_bzero_safe(buf, n);
1,397✔
725
                        free(buf);
1,397✔
726
                } else {
727
                        t = realloc(buf, n_next + 1);
456,094✔
728
                        if (!t)
456,094✔
729
                                return -ENOMEM;
730
                }
731

732
                buf = t;
457,491✔
733
                /* Unless a size has been explicitly specified, try to read as much as fits into the memory
734
                 * we allocated (minus 1, to leave one byte for the safety NUL byte) */
735
                n = size == SIZE_MAX ? MALLOC_SIZEOF_SAFE(buf) - 1 : n_next;
457,491✔
736

737
                errno = 0;
457,491✔
738
                k = fread(buf + l, 1, n - l, f);
457,491✔
739

740
                assert(k <= n - l);
457,491✔
741
                l += k;
457,491✔
742

743
                if (ferror(f)) {
457,491✔
744
                        r = errno_or_else(EIO);
2✔
745
                        goto finalize;
2✔
746
                }
747
                if (feof(f))
457,489✔
748
                        break;
749

750
                if (size != SIZE_MAX && !FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER)) { /* If we got asked to read some specific size, we already sized the buffer right, hence leave */
295✔
751
                        assert(l == size);
144✔
752
                        break;
753
                }
754

755
                assert(k > 0); /* we can't have read zero bytes because that would have been EOF */
151✔
756

757
                if (FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER) && l > size) {
151✔
758
                        r = -E2BIG;
6✔
759
                        goto finalize;
6✔
760
                }
761

762
                if (n >= READ_FULL_BYTES_MAX) {
145✔
763
                        r = -E2BIG;
×
764
                        goto finalize;
×
765
                }
766

767
                n_next = MIN(n * 2, READ_FULL_BYTES_MAX);
145✔
768
        }
769

770
        if (flags & (READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX)) {
457,338✔
771
                _cleanup_free_ void *decoded = NULL;
32✔
772
                size_t decoded_size;
32✔
773

774
                buf[l++] = 0;
32✔
775
                if (flags & READ_FULL_FILE_UNBASE64)
32✔
776
                        r = unbase64mem_full(buf, l, flags & READ_FULL_FILE_SECURE, &decoded, &decoded_size);
30✔
777
                else
778
                        r = unhexmem_full(buf, l, flags & READ_FULL_FILE_SECURE, &decoded, &decoded_size);
2✔
779
                if (r < 0)
32✔
780
                        goto finalize;
×
781

782
                if (flags & READ_FULL_FILE_SECURE)
32✔
783
                        explicit_bzero_safe(buf, n);
14✔
784
                free_and_replace(buf, decoded);
32✔
785
                n = l = decoded_size;
32✔
786

787
                if (FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER) && l > expected_decoded_size) {
32✔
788
                        r = -E2BIG;
×
789
                        goto finalize;
×
790
                }
791
        }
792

793
        if (!ret_size) {
457,338✔
794
                /* Safety check: if the caller doesn't want to know the size of what we just read it will rely on the
795
                 * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise
796
                 * there'd be ambiguity about what we just read. */
797

798
                if (memchr(buf, 0, l)) {
328,983✔
799
                        r = -EBADMSG;
2✔
800
                        goto finalize;
2✔
801
                }
802
        }
803

804
        buf[l] = 0;
457,336✔
805
        *ret_contents = TAKE_PTR(buf);
457,336✔
806

807
        if (ret_size)
457,336✔
808
                *ret_size = l;
128,355✔
809

810
        return 0;
811

812
finalize:
10✔
813
        if (flags & READ_FULL_FILE_SECURE)
10✔
814
                explicit_bzero_safe(buf, n);
3✔
815

816
        return r;
817
}
818

819
int read_full_file_full(
738,049✔
820
                int dir_fd,
821
                const char *filename,
822
                uint64_t offset,
823
                size_t size,
824
                ReadFullFileFlags flags,
825
                const char *bind_name,
826
                char **ret_contents,
827
                size_t *ret_size) {
828

829
        _cleanup_fclose_ FILE *f = NULL;
738,049✔
830
        XfopenFlags xflags = XFOPEN_UNLOCKED;
738,049✔
831
        int r;
738,049✔
832

833
        assert(filename);
738,049✔
834
        assert(ret_contents);
738,049✔
835

836
        if (FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET) && /* If this is enabled, let's try to connect to it */
738,049✔
837
            offset == UINT64_MAX)                              /* Seeking is not supported on AF_UNIX sockets */
838
                xflags |= XFOPEN_SOCKET;
181✔
839

840
        r = xfopenat_full(dir_fd, filename, "re", 0, xflags, bind_name, &f);
738,049✔
841
        if (r < 0)
738,049✔
842
                return r;
843

844
        return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size);
444,057✔
845
}
846

847
int script_get_shebang_interpreter(const char *path, char **ret) {
8✔
848
        _cleanup_fclose_ FILE *f = NULL;
8✔
849
        int r;
8✔
850

851
        assert(path);
8✔
852

853
        f = fopen(path, "re");
8✔
854
        if (!f)
8✔
855
                return -errno;
1✔
856

857
        char c;
7✔
858
        r = safe_fgetc(f, &c);
7✔
859
        if (r < 0)
7✔
860
                return r;
861
        if (r == 0)
7✔
862
                return -EBADMSG;
863
        if (c != '#')
7✔
864
                return -EMEDIUMTYPE;
865
        r = safe_fgetc(f, &c);
2✔
866
        if (r < 0)
2✔
867
                return r;
868
        if (r == 0)
2✔
869
                return -EBADMSG;
870
        if (c != '!')
2✔
871
                return -EMEDIUMTYPE;
872

873
        _cleanup_free_ char *line = NULL;
2✔
874
        r = read_line(f, LONG_LINE_MAX, &line);
2✔
875
        if (r < 0)
2✔
876
                return r;
877

878
        _cleanup_free_ char *p = NULL;
2✔
879
        const char *s = line;
2✔
880

881
        r = extract_first_word(&s, &p, /* separators = */ NULL, /* flags = */ 0);
2✔
882
        if (r < 0)
2✔
883
                return r;
884
        if (r == 0)
2✔
885
                return -ENOEXEC;
886

887
        if (ret)
2✔
888
                *ret = TAKE_PTR(p);
2✔
889
        return 0;
890
}
891

892
/**
893
 * Retrieve one field from a file like /proc/self/status.  pattern
894
 * should not include whitespace or the delimiter (':'). pattern matches only
895
 * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
896
 * zeros after the ':' will be skipped. field must be freed afterwards.
897
 * terminator specifies the terminating characters of the field value (not
898
 * included in the value).
899
 */
900
int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
22,979✔
901
        _cleanup_free_ char *status = NULL;
22,979✔
902
        char *t, *f;
22,979✔
903
        int r;
22,979✔
904

905
        assert(terminator);
22,979✔
906
        assert(filename);
22,979✔
907
        assert(pattern);
22,979✔
908
        assert(field);
22,979✔
909

910
        r = read_full_virtual_file(filename, &status, NULL);
22,979✔
911
        if (r < 0)
22,979✔
912
                return r;
913

914
        t = status;
22,918✔
915

916
        do {
22,918✔
917
                bool pattern_ok;
22,918✔
918

919
                do {
22,918✔
920
                        t = strstr(t, pattern);
22,918✔
921
                        if (!t)
22,918✔
922
                                return -ENOENT;
923

924
                        /* Check that pattern occurs in beginning of line. */
925
                        pattern_ok = (t == status || t[-1] == '\n');
22,917✔
926

927
                        t += strlen(pattern);
22,917✔
928

929
                } while (!pattern_ok);
22,917✔
930

931
                t += strspn(t, " \t");
22,917✔
932
                if (!*t)
22,917✔
933
                        return -ENOENT;
934

935
        } while (*t != ':');
22,917✔
936

937
        t++;
22,917✔
938

939
        if (*t) {
22,917✔
940
                t += strspn(t, " \t");
22,917✔
941

942
                /* Also skip zeros, because when this is used for
943
                 * capabilities, we don't want the zeros. This way the
944
                 * same capability set always maps to the same string,
945
                 * irrespective of the total capability set size. For
946
                 * other numbers it shouldn't matter. */
947
                t += strspn(t, "0");
22,917✔
948
                /* Back off one char if there's nothing but whitespace
949
                   and zeros */
950
                if (!*t || isspace(*t))
22,917✔
951
                        t--;
9,255✔
952
        }
953

954
        f = strdupcspn(t, terminator);
22,917✔
955
        if (!f)
22,917✔
956
                return -ENOMEM;
957

958
        *field = f;
22,917✔
959
        return 0;
22,917✔
960
}
961

962
DIR* xopendirat(int dir_fd, const char *name, int flags) {
194,740✔
963
        _cleanup_close_ int fd = -EBADF;
194,740✔
964

965
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
194,740✔
966
        assert(name);
194,740✔
967
        assert(!(flags & (O_CREAT|O_TMPFILE)));
194,740✔
968

969
        if (dir_fd == AT_FDCWD && flags == 0)
194,740✔
970
                return opendir(name);
×
971

972
        fd = openat(dir_fd, name, O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
194,740✔
973
        if (fd < 0)
194,740✔
974
                return NULL;
975

976
        return take_fdopendir(&fd);
194,026✔
977
}
978

979
int fopen_mode_to_flags(const char *mode) {
78,927✔
980
        const char *p;
78,927✔
981
        int flags;
78,927✔
982

983
        assert(mode);
78,927✔
984

985
        if ((p = startswith(mode, "r+")))
78,927✔
986
                flags = O_RDWR;
987
        else if ((p = startswith(mode, "r")))
78,926✔
988
                flags = O_RDONLY;
989
        else if ((p = startswith(mode, "w+")))
×
990
                flags = O_RDWR|O_CREAT|O_TRUNC;
991
        else if ((p = startswith(mode, "w")))
×
992
                flags = O_WRONLY|O_CREAT|O_TRUNC;
993
        else if ((p = startswith(mode, "a+")))
×
994
                flags = O_RDWR|O_CREAT|O_APPEND;
995
        else if ((p = startswith(mode, "a")))
×
996
                flags = O_WRONLY|O_CREAT|O_APPEND;
997
        else
998
                return -EINVAL;
999

1000
        for (; *p != 0; p++) {
154,268✔
1001

1002
                switch (*p) {
75,341✔
1003

1004
                case 'e':
75,341✔
1005
                        flags |= O_CLOEXEC;
75,341✔
1006
                        break;
75,341✔
1007

1008
                case 'x':
×
1009
                        flags |= O_EXCL;
×
1010
                        break;
×
1011

1012
                case 'm':
1013
                        /* ignore this here, fdopen() might care later though */
1014
                        break;
1015

1016
                case 'c': /* not sure what to do about this one */
1017
                default:
1018
                        return -EINVAL;
1019
                }
1020
        }
1021

1022
        return flags;
1023
}
1024

1025
static int xfopenat_regular(int dir_fd, const char *path, const char *mode, int open_flags, FILE **ret) {
977,012✔
1026
        FILE *f;
977,012✔
1027

1028
        /* A combination of fopen() with openat() */
1029

1030
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
977,012✔
1031
        assert(path);
977,012✔
1032
        assert(mode);
977,012✔
1033
        assert(ret);
977,012✔
1034

1035
        if (dir_fd == AT_FDCWD && open_flags == 0)
977,012✔
1036
                f = fopen(path, mode);
976,407✔
1037
        else {
1038
                _cleanup_close_ int fd = -EBADF;
605✔
1039
                int mode_flags;
605✔
1040

1041
                mode_flags = fopen_mode_to_flags(mode);
605✔
1042
                if (mode_flags < 0)
605✔
1043
                        return mode_flags;
1044

1045
                fd = openat(dir_fd, path, mode_flags | open_flags);
605✔
1046
                if (fd < 0)
605✔
1047
                        return -errno;
278✔
1048

1049
                f = take_fdopen(&fd, mode);
327✔
1050
        }
1051
        if (!f)
976,734✔
1052
                return -errno;
324,921✔
1053

1054
        *ret = f;
651,813✔
1055
        return 0;
651,813✔
1056
}
1057

1058
static int xfopenat_unix_socket(int dir_fd, const char *path, const char *bind_name, FILE **ret) {
1✔
1059
        _cleanup_close_ int sk = -EBADF;
1✔
1060
        FILE *f;
1✔
1061
        int r;
1✔
1062

1063
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
1✔
1064
        assert(path);
1✔
1065
        assert(ret);
1✔
1066

1067
        sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
1✔
1068
        if (sk < 0)
1✔
1069
                return -errno;
×
1070

1071
        if (bind_name) {
1✔
1072
                /* If the caller specified a socket name to bind to, do so before connecting. This is
1073
                 * useful to communicate some minor, short meta-information token from the client to
1074
                 * the server. */
1075
                union sockaddr_union bsa;
1✔
1076

1077
                r = sockaddr_un_set_path(&bsa.un, bind_name);
1✔
1078
                if (r < 0)
1✔
1079
                        return r;
×
1080

1081
                if (bind(sk, &bsa.sa, r) < 0)
1✔
1082
                        return -errno;
×
1083
        }
1084

1085
        r = connect_unix_path(sk, dir_fd, path);
1✔
1086
        if (r < 0)
1✔
1087
                return r;
1088

1089
        if (shutdown(sk, SHUT_WR) < 0)
1✔
1090
                return -errno;
×
1091

1092
        f = take_fdopen(&sk, "r");
1✔
1093
        if (!f)
1✔
1094
                return -errno;
×
1095

1096
        *ret = f;
1✔
1097
        return 0;
1✔
1098
}
1099

1100
int xfopenat_full(
977,012✔
1101
                int dir_fd,
1102
                const char *path,
1103
                const char *mode,
1104
                int open_flags,
1105
                XfopenFlags flags,
1106
                const char *bind_name,
1107
                FILE **ret) {
1108

1109
        FILE *f = NULL;  /* avoid false maybe-uninitialized warning */
977,012✔
1110
        int r;
977,012✔
1111

1112
        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
977,012✔
1113
        assert(path);
977,012✔
1114
        assert(mode);
977,012✔
1115
        assert(ret);
977,012✔
1116

1117
        r = xfopenat_regular(dir_fd, path, mode, open_flags, &f);
977,012✔
1118
        if (r == -ENXIO && FLAGS_SET(flags, XFOPEN_SOCKET)) {
977,012✔
1119
                /* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */
1120
                r = xfopenat_unix_socket(dir_fd, path, bind_name, &f);
1✔
1121
                if (IN_SET(r, -ENOTSOCK, -EINVAL))
1✔
1122
                        return -ENXIO; /* propagate original error if this is not a socket after all */
977,012✔
1123
        }
1124
        if (r < 0)
977,012✔
1125
                return r;
1126

1127
        if (FLAGS_SET(flags, XFOPEN_UNLOCKED))
651,814✔
1128
                (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
651,579✔
1129

1130
        *ret = f;
651,814✔
1131
        return 0;
651,814✔
1132
}
1133

1134
int fdopen_independent(int fd, const char *mode, FILE **ret) {
11,177✔
1135
        _cleanup_close_ int copy_fd = -EBADF;
11,177✔
1136
        _cleanup_fclose_ FILE *f = NULL;
11,177✔
1137
        int mode_flags;
11,177✔
1138

1139
        assert(fd >= 0);
11,177✔
1140
        assert(mode);
11,177✔
1141
        assert(ret);
11,177✔
1142

1143
        /* A combination of fdopen() + fd_reopen(). i.e. reopens the inode the specified fd points to and
1144
         * returns a FILE* for it */
1145

1146
        mode_flags = fopen_mode_to_flags(mode);
11,177✔
1147
        if (mode_flags < 0)
11,177✔
1148
                return mode_flags;
1149

1150
        /* Flags returned by fopen_mode_to_flags might contain O_CREAT, but it doesn't make sense for fd_reopen
1151
         * since we're working on an existing fd anyway. Let's drop it here to avoid triggering assertion. */
1152
        copy_fd = fd_reopen(fd, mode_flags & ~O_CREAT);
11,177✔
1153
        if (copy_fd < 0)
11,177✔
1154
                return copy_fd;
1155

1156
        f = take_fdopen(&copy_fd, mode);
11,177✔
1157
        if (!f)
11,177✔
1158
                return -errno;
×
1159

1160
        *ret = TAKE_PTR(f);
11,177✔
1161
        return 0;
11,177✔
1162
}
1163

1164
static int search_and_open_internal(
21,513✔
1165
                const char *path,
1166
                int mode,            /* if ret_fd is NULL this is an [FRWX]_OK mode for access(), otherwise an open mode for open() */
1167
                const char *root,
1168
                char **search,
1169
                int *ret_fd,
1170
                char **ret_path) {
1171

1172
        int r;
21,513✔
1173

1174
        assert(!ret_fd || !FLAGS_SET(mode, O_CREAT)); /* We don't support O_CREAT for this */
21,513✔
1175
        assert(path);
21,513✔
1176

1177
        if (path_is_absolute(path)) {
21,513✔
1178
                _cleanup_close_ int fd = -EBADF;
×
1179

1180
                if (ret_fd)
5,596✔
1181
                        /* We only specify 0777 here to appease static analyzers, it's never used since we
1182
                         * don't support O_CREAT here */
1183
                        r = fd = RET_NERRNO(open(path, mode, 0777));
5,594✔
1184
                else
1185
                        r = RET_NERRNO(access(path, mode));
2✔
1186
                if (r < 0)
178✔
1187
                        return r;
1188

1189
                if (ret_path) {
5,418✔
1190
                        r = path_simplify_alloc(path, ret_path);
5,418✔
1191
                        if (r < 0)
5,418✔
1192
                                return r;
1193
                }
1194

1195
                if (ret_fd)
5,418✔
1196
                        *ret_fd = TAKE_FD(fd);
5,417✔
1197

1198
                return 0;
5,418✔
1199
        }
1200

1201
        if (!path_strv_resolve_uniq(search, root))
15,917✔
1202
                return -ENOMEM;
1203

1204
        STRV_FOREACH(i, search) {
94,618✔
1205
                _cleanup_close_ int fd = -EBADF;
100,214✔
1206
                _cleanup_free_ char *p = NULL;
78,809✔
1207

1208
                p = path_join(root, *i, path);
78,809✔
1209
                if (!p)
78,809✔
1210
                        return -ENOMEM;
1211

1212
                if (ret_fd)
78,809✔
1213
                        /* as above, 0777 is static analyzer appeasement */
1214
                        r = fd = RET_NERRNO(open(p, mode, 0777));
78,505✔
1215
                else
1216
                        r = RET_NERRNO(access(p, F_OK));
304✔
1217
                if (r >= 0) {
78,701✔
1218
                        if (ret_path)
108✔
1219
                                *ret_path = path_simplify(TAKE_PTR(p));
108✔
1220

1221
                        if (ret_fd)
108✔
1222
                                *ret_fd = TAKE_FD(fd);
101✔
1223

1224
                        return 0;
108✔
1225
                }
1226
                if (r != -ENOENT)
78,701✔
1227
                        return r;
1228
        }
1229

1230
        return -ENOENT;
1231
}
1232

1233
int search_and_open(
21,513✔
1234
                const char *path,
1235
                int mode,
1236
                const char *root,
1237
                char **search,
1238
                int *ret_fd,
1239
                char **ret_path) {
1240

1241
        _cleanup_strv_free_ char **copy = NULL;
21,513✔
1242

1243
        assert(path);
21,513✔
1244

1245
        copy = strv_copy((char**) search);
21,513✔
1246
        if (!copy)
21,513✔
1247
                return -ENOMEM;
1248

1249
        return search_and_open_internal(path, mode, root, copy, ret_fd, ret_path);
21,513✔
1250
}
1251

1252
static int search_and_fopen_internal(
21,508✔
1253
                const char *path,
1254
                const char *mode,
1255
                const char *root,
1256
                char **search,
1257
                FILE **ret_file,
1258
                char **ret_path) {
1259

1260
        _cleanup_free_ char *found_path = NULL;
21,508✔
1261
        _cleanup_close_ int fd = -EBADF;
21,508✔
1262
        int r;
21,508✔
1263

1264
        assert(path);
21,508✔
1265
        assert(mode || !ret_file);
21,508✔
1266

1267
        r = search_and_open(
43,120✔
1268
                        path,
1269
                        mode ? fopen_mode_to_flags(mode) : 0,
21,364✔
1270
                        root,
1271
                        search,
1272
                        ret_file ? &fd : NULL,
1273
                        ret_path ? &found_path : NULL);
1274
        if (r < 0)
21,508✔
1275
                return r;
1276

1277
        if (ret_file) {
5,521✔
1278
                FILE *f = take_fdopen(&fd, mode);
5,518✔
1279
                if (!f)
5,518✔
1280
                        return -errno;
×
1281

1282
                *ret_file = f;
5,518✔
1283
        }
1284

1285
        if (ret_path)
5,521✔
1286
                *ret_path = TAKE_PTR(found_path);
5,521✔
1287

1288
        return 0;
1289
}
1290

1291
int search_and_fopen(
5,600✔
1292
                const char *path,
1293
                const char *mode,
1294
                const char *root,
1295
                const char **search,
1296
                FILE **ret_file,
1297
                char **ret_path) {
1298

1299
        _cleanup_strv_free_ char **copy = NULL;
5,600✔
1300

1301
        assert(path);
5,600✔
1302
        assert(mode || !ret_file);
5,600✔
1303

1304
        copy = strv_copy((char**) search);
5,600✔
1305
        if (!copy)
5,600✔
1306
                return -ENOMEM;
1307

1308
        return search_and_fopen_internal(path, mode, root, copy, ret_file, ret_path);
5,600✔
1309
}
1310

1311
int search_and_fopen_nulstr(
15,908✔
1312
                const char *path,
1313
                const char *mode,
1314
                const char *root,
1315
                const char *search,
1316
                FILE **ret_file,
1317
                char **ret_path) {
1318

1319
        _cleanup_strv_free_ char **l = NULL;
15,908✔
1320

1321
        assert(path);
15,908✔
1322
        assert(mode || !ret_file);
15,908✔
1323

1324
        l = strv_split_nulstr(search);
15,908✔
1325
        if (!l)
15,908✔
1326
                return -ENOMEM;
1327

1328
        return search_and_fopen_internal(path, mode, root, l, ret_file, ret_path);
15,908✔
1329
}
1330

1331
int fflush_and_check(FILE *f) {
913,577✔
1332
        assert(f);
913,577✔
1333

1334
        errno = 0;
913,577✔
1335
        fflush(f);
913,577✔
1336

1337
        if (ferror(f))
913,577✔
1338
                return errno_or_else(EIO);
24✔
1339

1340
        return 0;
1341
}
1342

1343
int fflush_sync_and_check(FILE *f) {
2,339✔
1344
        int r, fd;
2,339✔
1345

1346
        assert(f);
2,339✔
1347

1348
        r = fflush_and_check(f);
2,339✔
1349
        if (r < 0)
2,339✔
1350
                return r;
1351

1352
        /* Not all file streams have an fd associated (think: fmemopen()), let's handle this gracefully and
1353
         * assume that in that case we need no explicit syncing */
1354
        fd = fileno(f);
2,339✔
1355
        if (fd < 0)
2,339✔
1356
                return 0;
1357

1358
        r = fsync_full(fd);
2,339✔
1359
        if (r < 0)
2,339✔
1360
                return r;
×
1361

1362
        return 0;
1363
}
1364

1365
int write_timestamp_file_atomic(const char *fn, usec_t n) {
120✔
1366
        char ln[DECIMAL_STR_MAX(n)+2];
120✔
1367

1368
        /* Creates a "timestamp" file, that contains nothing but a
1369
         * usec_t timestamp, formatted in ASCII. */
1370

1371
        if (!timestamp_is_set(n))
120✔
1372
                return -ERANGE;
120✔
1373

1374
        xsprintf(ln, USEC_FMT "\n", n);
120✔
1375

1376
        return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
120✔
1377
}
1378

1379
int read_timestamp_file(const char *fn, usec_t *ret) {
76✔
1380
        _cleanup_free_ char *ln = NULL;
76✔
1381
        uint64_t t;
76✔
1382
        int r;
76✔
1383

1384
        r = read_one_line_file(fn, &ln);
76✔
1385
        if (r < 0)
76✔
1386
                return r;
1387

1388
        r = safe_atou64(ln, &t);
×
1389
        if (r < 0)
×
1390
                return r;
1391

1392
        if (!timestamp_is_set(t))
×
1393
                return -ERANGE;
1394

1395
        *ret = (usec_t) t;
×
1396
        return 0;
×
1397
}
1398

1399
int fputs_with_separator(FILE *f, const char *s, const char *separator, bool *space) {
3,291✔
1400
        assert(s);
3,291✔
1401
        assert(space);
3,291✔
1402

1403
        /* Outputs the specified string with fputs(), but optionally prefixes it with a separator.
1404
         * The *space parameter when specified shall initially point to a boolean variable initialized
1405
         * to false. It is set to true after the first invocation. This call is supposed to be use in loops,
1406
         * where a separator shall be inserted between each element, but not before the first one. */
1407

1408
        if (!f)
3,291✔
1409
                f = stdout;
×
1410

1411
        if (!separator)
3,291✔
1412
                separator = " ";
1,614✔
1413

1414
        if (*space)
3,291✔
1415
                if (fputs(separator, f) < 0)
1,432✔
1416
                        return -EIO;
1417

1418
        *space = true;
3,291✔
1419

1420
        if (fputs(s, f) < 0)
3,291✔
1421
                return -EIO;
×
1422

1423
        return 0;
1424
}
1425

1426
int fputs_with_newline(FILE *f, const char *s) {
595✔
1427

1428
        /* This is like fputs() but outputs a trailing newline char, but only if the string isn't empty
1429
         * and doesn't end in a newline already. Returns 0 in case we didn't append a newline, > 0 otherwise. */
1430

1431
        if (isempty(s))
595✔
1432
                return 0;
1433

1434
        if (!f)
595✔
1435
                f = stdout;
×
1436

1437
        if (fputs(s, f) < 0)
595✔
1438
                return -EIO;
1439

1440
        if (endswith(s, "\n"))
595✔
1441
                return 0;
1442

1443
        if (fputc('\n', f) < 0)
467✔
1444
                return -EIO;
×
1445

1446
        return 1;
1447
}
1448

1449
/* A bitmask of the EOL markers we know */
1450
typedef enum EndOfLineMarker {
1451
        EOL_NONE     = 0,
1452
        EOL_ZERO     = 1 << 0,  /* \0 (aka NUL) */
1453
        EOL_TEN      = 1 << 1,  /* \n (aka NL, aka LF)  */
1454
        EOL_THIRTEEN = 1 << 2,  /* \r (aka CR)  */
1455
} EndOfLineMarker;
1456

1457
static EndOfLineMarker categorize_eol(char c, ReadLineFlags flags) {
255,235,356✔
1458

1459
        if (!FLAGS_SET(flags, READ_LINE_ONLY_NUL)) {
255,235,356✔
1460
                if (c == '\n')
254,199,850✔
1461
                        return EOL_TEN;
1462
                if (c == '\r')
246,178,192✔
1463
                        return EOL_THIRTEEN;
1464
        }
1465

1466
        if (c == '\0')
247,213,682✔
1467
                return EOL_ZERO;
31,978✔
1468

1469
        return EOL_NONE;
1470
}
1471

1472
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(FILE*, funlockfile, NULL);
7,425,881✔
1473

1474
int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
7,425,881✔
1475
        _cleanup_free_ char *buffer = NULL;
7,425,881✔
1476
        size_t n = 0, count = 0;
7,425,881✔
1477
        int r;
7,425,881✔
1478

1479
        assert(f);
7,425,881✔
1480

1481
        /* Something like a bounded version of getline().
1482
         *
1483
         * Considers EOF, \n, \r and \0 end of line delimiters (or combinations of these), and does not include these
1484
         * delimiters in the string returned. Specifically, recognizes the following combinations of markers as line
1485
         * endings:
1486
         *
1487
         *     • \n        (UNIX)
1488
         *     • \r        (old MacOS)
1489
         *     • \0        (C strings)
1490
         *     • \n\0
1491
         *     • \r\0
1492
         *     • \r\n      (Windows)
1493
         *     • \n\r
1494
         *     • \r\n\0
1495
         *     • \n\r\0
1496
         *
1497
         * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
1498
         * the number of characters in the returned string). When EOF is hit, 0 is returned.
1499
         *
1500
         * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
1501
         * delimiters. If the limit is hit we fail and return -ENOBUFS.
1502
         *
1503
         * If a line shall be skipped ret may be initialized as NULL. */
1504

1505
        if (ret) {
7,425,881✔
1506
                if (!GREEDY_REALLOC(buffer, 1))
7,425,850✔
1507
                        return -ENOMEM;
1508
        }
1509

1510
        {
1511
                _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
7,425,881✔
1512
                EndOfLineMarker previous_eol = EOL_NONE;
7,425,881✔
1513
                flockfile(f);
7,425,881✔
1514

1515
                for (;;) {
255,774,442✔
1516
                        EndOfLineMarker eol;
255,774,442✔
1517
                        char c;
255,774,442✔
1518

1519
                        if (n >= limit)
255,774,442✔
1520
                                return -ENOBUFS;
20✔
1521

1522
                        if (count >= INT_MAX) /* We couldn't return the counter anymore as "int", hence refuse this */
255,774,436✔
1523
                                return -ENOBUFS;
1524

1525
                        r = safe_fgetc(f, &c);
255,774,436✔
1526
                        if (r < 0)
255,774,436✔
1527
                                return r;
1528
                        if (r == 0) /* EOF is definitely EOL */
255,774,422✔
1529
                                break;
1530

1531
                        eol = categorize_eol(c, flags);
255,235,356✔
1532

1533
                        if (FLAGS_SET(previous_eol, EOL_ZERO) ||
255,235,356✔
1534
                            (eol == EOL_NONE && previous_eol != EOL_NONE) ||
255,206,805✔
1535
                            (eol != EOL_NONE && (previous_eol & eol) != 0)) {
8,053,646✔
1536
                                /* Previous char was a NUL? This is not an EOL, but the previous char was? This type of
1537
                                 * EOL marker has been seen right before?  In either of these three cases we are
1538
                                 * done. But first, let's put this character back in the queue. (Note that we have to
1539
                                 * cast this to (unsigned char) here as ungetc() expects a positive 'int', and if we
1540
                                 * are on an architecture where 'char' equals 'signed char' we need to ensure we don't
1541
                                 * pass a negative value here. That said, to complicate things further ungetc() is
1542
                                 * actually happy with most negative characters and implicitly casts them back to
1543
                                 * positive ones as needed, except for \xff (aka -1, aka EOF), which it refuses. What a
1544
                                 * godawful API!) */
1545
                                assert_se(ungetc((unsigned char) c, f) != EOF);
6,886,795✔
1546
                                break;
1547
                        }
1548

1549
                        count++;
248,348,561✔
1550

1551
                        if (eol != EOL_NONE) {
241,084,939✔
1552
                                /* If we are on a tty, we can't shouldn't wait for more input, because that
1553
                                 * generally means waiting for the user, interactively. In the case of a TTY
1554
                                 * we expect only \n as the single EOL marker, so we are in the lucky
1555
                                 * position that there is no need to wait. We check this condition last, to
1556
                                 * avoid isatty() check if not necessary. */
1557

1558
                                if ((flags & (READ_LINE_IS_A_TTY|READ_LINE_NOT_A_TTY)) == 0) {
7,263,622✔
1559
                                        int fd;
6,553,024✔
1560

1561
                                        fd = fileno(f);
6,553,024✔
1562
                                        if (fd < 0) /* Maybe an fmemopen() stream? Handle this gracefully,
6,553,024✔
1563
                                                     * and don't call isatty() on an invalid fd */
1564
                                                flags |= READ_LINE_NOT_A_TTY;
28✔
1565
                                        else
1566
                                                flags |= isatty_safe(fd) ? READ_LINE_IS_A_TTY : READ_LINE_NOT_A_TTY;
13,105,992✔
1567
                                }
1568
                                if (FLAGS_SET(flags, READ_LINE_IS_A_TTY))
7,263,622✔
1569
                                        break;
1570
                        }
1571

1572
                        if (eol != EOL_NONE) {
248,348,561✔
1573
                                previous_eol |= eol;
7,263,622✔
1574
                                continue;
7,263,622✔
1575
                        }
1576

1577
                        if (ret) {
241,084,939✔
1578
                                if (!GREEDY_REALLOC(buffer, n + 2))
241,084,839✔
1579
                                        return -ENOMEM;
1580

1581
                                buffer[n] = c;
241,084,839✔
1582
                        }
1583

1584
                        n++;
241,084,939✔
1585
                }
1586
        }
1587

1588
        if (ret) {
7,425,861✔
1589
                buffer[n] = 0;
7,425,830✔
1590

1591
                *ret = TAKE_PTR(buffer);
7,425,830✔
1592
        }
1593

1594
        return (int) count;
7,425,861✔
1595
}
1596

1597
int read_stripped_line(FILE *f, size_t limit, char **ret) {
3,035,261✔
1598
        _cleanup_free_ char *s = NULL;
3,035,261✔
1599
        int r, k;
3,035,261✔
1600

1601
        assert(f);
3,035,261✔
1602

1603
        r = read_line(f, limit, ret ? &s : NULL);
3,035,261✔
1604
        if (r < 0)
3,035,261✔
1605
                return r;
1606

1607
        if (ret) {
3,035,261✔
1608
                const char *p = strstrip(s);
3,035,261✔
1609
                if (p == s)
3,035,261✔
1610
                        *ret = TAKE_PTR(s);
3,035,258✔
1611
                else {
1612
                        k = strdup_to(ret, p);
3✔
1613
                        if (k < 0)
3✔
1614
                                return k;
1615
                }
1616
        }
1617

1618
        return r > 0;          /* Return 1 if something was read. */
3,035,261✔
1619
}
1620

1621
int safe_fgetc(FILE *f, char *ret) {
255,781,531✔
1622
        int k;
255,781,531✔
1623

1624
        assert(f);
255,781,531✔
1625

1626
        /* A safer version of plain fgetc(): let's propagate the error that happened while reading as such, and
1627
         * separate the EOF condition from the byte read, to avoid those confusion signed/unsigned issues fgetc()
1628
         * has. */
1629

1630
        errno = 0;
255,781,531✔
1631
        k = fgetc(f);
255,781,531✔
1632
        if (k == EOF) {
255,781,531✔
1633
                if (ferror(f))
539,173✔
1634
                        return errno_or_else(EIO);
28✔
1635

1636
                if (ret)
539,159✔
1637
                        *ret = 0;
539,083✔
1638

1639
                return 0;
539,159✔
1640
        }
1641

1642
        if (ret)
255,242,358✔
1643
                *ret = k;
255,242,358✔
1644

1645
        return 1;
1646
}
1647

1648
int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line) {
150✔
1649
        struct stat _st;
150✔
1650

1651
        if (!filename)
150✔
1652
                return 0;
150✔
1653

1654
        if (!st) {
150✔
1655
                if (stat(filename, &_st) < 0)
22✔
1656
                        return -errno;
×
1657
                st = &_st;
1658
        }
1659

1660
        if ((st->st_mode & S_IRWXO) == 0)
150✔
1661
                return 0;
1662

1663
        if (unit)
35✔
1664
                log_syntax(unit, LOG_WARNING, filename, line, 0,
×
1665
                           "%s has %04o mode that is too permissive, please adjust the ownership and access mode.",
1666
                           filename, st->st_mode & 07777);
1667
        else
1668
                log_warning("%s has %04o mode that is too permissive, please adjust the ownership and access mode.",
35✔
1669
                            filename, st->st_mode & 07777);
1670
        return 0;
1671
}
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