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 <ctype.h>
9 : #include <errno.h>
10 : #include <fcntl.h>
11 : #include <stdio.h>
12 : #include <stdlib.h>
13 : #include <string.h>
14 : #include <sys/types.h>
15 : #include <unistd.h>
16 :
17 : #include "core/logger.h"
18 :
19 : #define OPEN_MODE_644 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
20 :
21 81 : void closep(int *fd)
22 : {
23 81 : if (*fd == -1)
24 : return;
25 :
26 18 : if (close(*fd))
27 0 : bf_warn_r(errno, "failed to close fd %d, assuming file is closed", *fd);
28 :
29 18 : *fd = -1;
30 : }
31 :
32 19 : int bf_strncpy(char *dst, size_t len, const char *src)
33 : {
34 : size_t src_len;
35 : size_t copy_len;
36 :
37 19 : bf_assert(dst && src);
38 19 : bf_assert(len);
39 :
40 19 : src_len = strlen(src);
41 19 : copy_len = bf_min(src_len, len - 1);
42 :
43 19 : memcpy(dst, src, copy_len);
44 19 : dst[copy_len] = '\0';
45 :
46 19 : return copy_len != src_len ? -E2BIG : 0;
47 : }
48 :
49 3 : int bf_realloc(void **ptr, size_t size)
50 : {
51 : _cleanup_free_ void *_ptr;
52 :
53 3 : bf_assert(ptr);
54 :
55 3 : _ptr = realloc(*ptr, size);
56 3 : if (!_ptr)
57 : return -ENOMEM;
58 :
59 3 : *ptr = TAKE_PTR(_ptr);
60 :
61 3 : return 0;
62 : }
63 :
64 7 : int bf_read_file(const char *path, void **buf, size_t *len)
65 : {
66 4 : _cleanup_close_ int fd = -1;
67 : _cleanup_free_ void *_buf = NULL;
68 : size_t _len;
69 : ssize_t r;
70 :
71 7 : bf_assert(path);
72 6 : bf_assert(buf);
73 5 : bf_assert(len);
74 :
75 4 : fd = open(path, O_RDONLY);
76 4 : if (fd < 0)
77 1 : return bf_err_r(errno, "failed to open %s", path);
78 :
79 3 : _len = lseek(fd, 0, SEEK_END);
80 3 : lseek(fd, 0, SEEK_SET);
81 :
82 3 : _buf = malloc(_len);
83 3 : if (!_buf)
84 1 : return bf_err_r(errno, "failed to allocate memory");
85 :
86 2 : r = read(fd, _buf, _len);
87 2 : if (r < 0)
88 1 : return bf_err_r(errno, "failed to read serialized data");
89 1 : if ((size_t)r != _len)
90 0 : return bf_err_r(EIO, "can't read full serialized data");
91 :
92 1 : closep(&fd);
93 :
94 1 : *buf = TAKE_PTR(_buf);
95 1 : *len = _len;
96 :
97 1 : return 0;
98 : }
99 :
100 6 : int bf_write_file(const char *path, const void *buf, size_t len)
101 : {
102 4 : _cleanup_close_ int fd = -1;
103 : ssize_t r;
104 :
105 6 : bf_assert(path);
106 5 : bf_assert(buf);
107 :
108 4 : fd = open(path, O_TRUNC | O_CREAT | O_WRONLY, OPEN_MODE_644);
109 4 : if (fd < 0)
110 1 : return bf_err_r(errno, "failed to open %s", path);
111 :
112 3 : r = write(fd, buf, len);
113 3 : if (r < 0)
114 1 : return bf_err_r(errno, "failed to write to %s", path);
115 2 : if ((size_t)r != len)
116 1 : return bf_err_r(EIO, "can't write full data to %s", path);
117 :
118 1 : closep(&fd);
119 :
120 1 : return 0;
121 : }
122 :
123 97 : char *bf_ltrim(char *str)
124 : {
125 97 : bf_assert(str);
126 :
127 142 : while (isspace(*str))
128 45 : str++;
129 97 : return str;
130 : }
131 :
132 97 : char *bf_rtrim(char *str)
133 : {
134 97 : bf_assert(str);
135 :
136 97 : char *back = str + strlen(str);
137 : do {
138 109 : --back;
139 109 : } while (back > str && isspace(*back));
140 :
141 97 : *(back + 1) = '\0';
142 97 : return str;
143 : }
144 :
145 97 : char *bf_trim(char *str)
146 : {
147 97 : bf_assert(str);
148 :
149 97 : return bf_rtrim(bf_ltrim(str));
150 : }
|