]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/file_utils.c
3 * Copyright © 2018 Christian Brauner <christian.brauner@ubuntu.com>.
4 * Copyright © 2018 Canonical Ltd.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <linux/magic.h>
28 #include <sys/sendfile.h>
29 #include <sys/types.h>
32 #include "file_utils.h"
34 #include "string_utils.h"
36 int lxc_write_to_file(const char *filename
, const void *buf
, size_t count
,
37 bool add_newline
, mode_t mode
)
42 fd
= open(filename
, O_WRONLY
| O_TRUNC
| O_CREAT
| O_CLOEXEC
, mode
);
46 ret
= lxc_write_nointr(fd
, buf
, count
);
50 if ((size_t)ret
!= count
)
54 ret
= lxc_write_nointr(fd
, "\n", 1);
69 int lxc_read_from_file(const char *filename
, void *buf
, size_t count
)
71 int fd
= -1, saved_errno
;
74 fd
= open(filename
, O_RDONLY
| O_CLOEXEC
);
82 while ((ret
= lxc_read_nointr(fd
, buf2
, 100)) > 0)
88 memset(buf
, 0, count
);
89 ret
= lxc_read_nointr(fd
, buf
, count
);
98 ssize_t
lxc_write_nointr(int fd
, const void *buf
, size_t count
)
102 ret
= write(fd
, buf
, count
);
103 if (ret
< 0 && errno
== EINTR
)
109 ssize_t
lxc_send_nointr(int sockfd
, void *buf
, size_t len
, int flags
)
113 ret
= send(sockfd
, buf
, len
, flags
);
114 if (ret
< 0 && errno
== EINTR
)
120 ssize_t
lxc_read_nointr(int fd
, void *buf
, size_t count
)
124 ret
= read(fd
, buf
, count
);
125 if (ret
< 0 && errno
== EINTR
)
131 ssize_t
lxc_recv_nointr(int sockfd
, void *buf
, size_t len
, int flags
)
135 ret
= recv(sockfd
, buf
, len
, flags
);
136 if (ret
< 0 && errno
== EINTR
)
142 ssize_t
lxc_read_nointr_expect(int fd
, void *buf
, size_t count
, const void *expected_buf
)
146 ret
= lxc_read_nointr(fd
, buf
, count
);
150 if ((size_t)ret
!= count
)
153 if (expected_buf
&& memcmp(buf
, expected_buf
, count
) != 0) {
161 bool file_exists(const char *f
)
165 return stat(f
, &statbuf
) == 0;
168 int print_to_file(const char *file
, const char *content
)
173 f
= fopen(file
, "w");
177 if (fprintf(f
, "%s", content
) != strlen(content
))
184 int is_dir(const char *path
)
189 ret
= stat(path
, &statbuf
);
190 if (ret
== 0 && S_ISDIR(statbuf
.st_mode
))
197 * Return the number of lines in file @fn, or -1 on error
199 int lxc_count_file_lines(const char *fn
)
206 f
= fopen_cloexec(fn
, "r");
210 while (getline(&line
, &sz
, f
) != -1) {
219 int lxc_make_tmpfile(char *template, bool rm
)
225 fd
= mkstemp(template);
233 ret
= unlink(template);
242 bool is_fs_type(const struct statfs
*fs
, fs_type_magic magic_val
)
244 return (fs
->f_type
== (fs_type_magic
)magic_val
);
247 bool has_fs_type(const char *path
, fs_type_magic magic_val
)
252 ret
= statfs(path
, &sb
);
256 return is_fs_type(&sb
, magic_val
);
259 bool fhas_fs_type(int fd
, fs_type_magic magic_val
)
264 ret
= fstatfs(fd
, &sb
);
268 return is_fs_type(&sb
, magic_val
);
271 FILE *fopen_cloexec(const char *path
, const char *mode
)
279 if (!strncmp(mode
, "r+", 2)) {
282 } else if (!strncmp(mode
, "r", 1)) {
283 open_mode
= O_RDONLY
;
285 } else if (!strncmp(mode
, "w+", 2)) {
286 open_mode
= O_RDWR
| O_TRUNC
| O_CREAT
;
288 } else if (!strncmp(mode
, "w", 1)) {
289 open_mode
= O_WRONLY
| O_TRUNC
| O_CREAT
;
291 } else if (!strncmp(mode
, "a+", 2)) {
292 open_mode
= O_RDWR
| O_CREAT
| O_APPEND
;
294 } else if (!strncmp(mode
, "a", 1)) {
295 open_mode
= O_WRONLY
| O_CREAT
| O_APPEND
;
298 for (; mode
[step
]; step
++)
299 if (mode
[step
] == 'x')
301 open_mode
|= O_CLOEXEC
;
303 fd
= open(path
, open_mode
, 0660);
307 ret
= fdopen(fd
, mode
);
315 ssize_t
lxc_sendfile_nointr(int out_fd
, int in_fd
, off_t
*offset
, size_t count
)
320 ret
= sendfile(out_fd
, in_fd
, offset
, count
);
331 char *file_to_buf(char *path
, size_t *length
)
340 fd
= open(path
, O_RDONLY
| O_CLOEXEC
);
349 n
= lxc_read_nointr(fd
, buf
, sizeof(buf
));
355 copy
= must_realloc(old
, (*length
+ n
) * sizeof(*old
));
356 memcpy(copy
+ *length
, buf
, n
);