Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */
2 : /*
3 : * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4 : */
5 :
6 : #include "core/helper.h"
7 :
8 : #include <errno.h>
9 : #include <fcntl.h>
10 : #include <stdio.h>
11 : #include <stdlib.h>
12 : #include <string.h>
13 : #include <sys/types.h>
14 : #include <unistd.h>
15 :
16 : #include "core/logger.h"
17 :
18 : #define OPEN_MODE_644 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
19 :
20 82 : void closep(int *fd)
21 : {
22 82 : if (*fd == -1)
23 : return;
24 :
25 18 : if (close(*fd))
26 0 : bf_warn_r(errno, "failed to close fd %d, assuming file is closed", *fd);
27 :
28 18 : *fd = -1;
29 : }
30 :
31 19 : int bf_strncpy(char *dst, size_t len, const char *src)
32 : {
33 : size_t src_len;
34 : size_t copy_len;
35 :
36 19 : bf_assert(dst && src);
37 19 : bf_assert(len);
38 :
39 19 : src_len = strlen(src);
40 19 : copy_len = bf_min(src_len, len - 1);
41 :
42 19 : memcpy(dst, src, copy_len);
43 19 : dst[copy_len] = '\0';
44 :
45 19 : return copy_len != src_len ? -E2BIG : 0;
46 : }
47 :
48 7 : int bf_read_file(const char *path, void **buf, size_t *len)
49 : {
50 4 : _cleanup_close_ int fd = -1;
51 : _cleanup_free_ void *_buf = NULL;
52 : size_t _len;
53 : ssize_t r;
54 :
55 7 : bf_assert(path);
56 6 : bf_assert(buf);
57 5 : bf_assert(len);
58 :
59 4 : fd = open(path, O_RDONLY);
60 4 : if (fd < 0)
61 1 : return bf_err_r(errno, "failed to open %s", path);
62 :
63 3 : _len = lseek(fd, 0, SEEK_END);
64 3 : lseek(fd, 0, SEEK_SET);
65 :
66 3 : _buf = malloc(_len);
67 3 : if (!_buf)
68 1 : return bf_err_r(errno, "failed to allocate memory");
69 :
70 2 : r = read(fd, _buf, _len);
71 2 : if (r < 0)
72 1 : return bf_err_r(errno, "failed to read serialized data");
73 1 : if ((size_t)r != _len)
74 0 : return bf_err_r(EIO, "can't read full serialized data");
75 :
76 1 : closep(&fd);
77 :
78 1 : *buf = TAKE_PTR(_buf);
79 1 : *len = _len;
80 :
81 1 : return 0;
82 : }
83 :
84 6 : int bf_write_file(const char *path, const void *buf, size_t len)
85 : {
86 4 : _cleanup_close_ int fd = -1;
87 : ssize_t r;
88 :
89 6 : bf_assert(path);
90 5 : bf_assert(buf);
91 :
92 4 : fd = open(path, O_TRUNC | O_CREAT | O_WRONLY, OPEN_MODE_644);
93 4 : if (fd < 0)
94 1 : return bf_err_r(errno, "failed to open %s", path);
95 :
96 3 : r = write(fd, buf, len);
97 3 : if (r < 0)
98 1 : return bf_err_r(errno, "failed to write to %s", path);
99 2 : if ((size_t)r != len)
100 1 : return bf_err_r(EIO, "can't write full data to %s", path);
101 :
102 1 : closep(&fd);
103 :
104 1 : return 0;
105 : }
|