]>
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"
37 lxc_log_define(file_utils
, lxc
);
39 int lxc_write_to_file(const char *filename
, const void *buf
, size_t count
,
40 bool add_newline
, mode_t mode
)
45 fd
= open(filename
, O_WRONLY
| O_TRUNC
| O_CREAT
| O_CLOEXEC
, mode
);
49 ret
= lxc_write_nointr(fd
, buf
, count
);
53 if ((size_t)ret
!= count
)
57 ret
= lxc_write_nointr(fd
, "\n", 1);
72 int lxc_read_from_file(const char *filename
, void *buf
, size_t count
)
74 int fd
= -1, saved_errno
;
77 fd
= open(filename
, O_RDONLY
| O_CLOEXEC
);
85 while ((ret
= lxc_read_nointr(fd
, buf2
, 100)) > 0)
91 memset(buf
, 0, count
);
92 ret
= lxc_read_nointr(fd
, buf
, count
);
101 ssize_t
lxc_write_nointr(int fd
, const void *buf
, size_t count
)
105 ret
= write(fd
, buf
, count
);
106 if (ret
< 0 && errno
== EINTR
)
112 ssize_t
lxc_send_nointr(int sockfd
, void *buf
, size_t len
, int flags
)
116 ret
= send(sockfd
, buf
, len
, flags
);
117 if (ret
< 0 && errno
== EINTR
)
123 ssize_t
lxc_read_nointr(int fd
, void *buf
, size_t count
)
127 ret
= read(fd
, buf
, count
);
128 if (ret
< 0 && errno
== EINTR
)
134 ssize_t
lxc_recv_nointr(int sockfd
, void *buf
, size_t len
, int flags
)
138 ret
= recv(sockfd
, buf
, len
, flags
);
139 if (ret
< 0 && errno
== EINTR
)
145 ssize_t
lxc_read_nointr_expect(int fd
, void *buf
, size_t count
, const void *expected_buf
)
149 ret
= lxc_read_nointr(fd
, buf
, count
);
153 if ((size_t)ret
!= count
)
156 if (expected_buf
&& memcmp(buf
, expected_buf
, count
) != 0) {
164 bool file_exists(const char *f
)
168 return stat(f
, &statbuf
) == 0;
171 int print_to_file(const char *file
, const char *content
)
176 f
= fopen(file
, "w");
180 if (fprintf(f
, "%s", content
) != strlen(content
))
187 int is_dir(const char *path
)
192 ret
= stat(path
, &statbuf
);
193 if (ret
== 0 && S_ISDIR(statbuf
.st_mode
))
200 * Return the number of lines in file @fn, or -1 on error
202 int lxc_count_file_lines(const char *fn
)
209 f
= fopen_cloexec(fn
, "r");
213 while (getline(&line
, &sz
, f
) != -1) {
222 int lxc_make_tmpfile(char *template, bool rm
)
228 fd
= mkstemp(template);
236 ret
= unlink(template);
245 bool is_fs_type(const struct statfs
*fs
, fs_type_magic magic_val
)
247 return (fs
->f_type
== (fs_type_magic
)magic_val
);
250 bool has_fs_type(const char *path
, fs_type_magic magic_val
)
255 ret
= statfs(path
, &sb
);
259 return is_fs_type(&sb
, magic_val
);
262 bool fhas_fs_type(int fd
, fs_type_magic magic_val
)
267 ret
= fstatfs(fd
, &sb
);
271 return is_fs_type(&sb
, magic_val
);
274 FILE *fopen_cloexec(const char *path
, const char *mode
)
282 if (!strncmp(mode
, "r+", 2)) {
285 } else if (!strncmp(mode
, "r", 1)) {
286 open_mode
= O_RDONLY
;
288 } else if (!strncmp(mode
, "w+", 2)) {
289 open_mode
= O_RDWR
| O_TRUNC
| O_CREAT
;
291 } else if (!strncmp(mode
, "w", 1)) {
292 open_mode
= O_WRONLY
| O_TRUNC
| O_CREAT
;
294 } else if (!strncmp(mode
, "a+", 2)) {
295 open_mode
= O_RDWR
| O_CREAT
| O_APPEND
;
297 } else if (!strncmp(mode
, "a", 1)) {
298 open_mode
= O_WRONLY
| O_CREAT
| O_APPEND
;
301 for (; mode
[step
]; step
++)
302 if (mode
[step
] == 'x')
304 open_mode
|= O_CLOEXEC
;
306 fd
= open(path
, open_mode
, 0660);
310 ret
= fdopen(fd
, mode
);
318 ssize_t
lxc_sendfile_nointr(int out_fd
, int in_fd
, off_t
*offset
, size_t count
)
323 ret
= sendfile(out_fd
, in_fd
, offset
, count
);