]>
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.
24 #include <linux/magic.h>
27 #include <sys/types.h>
29 #include "file_utils.h"
34 lxc_log_define(file_utils
, lxc
);
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_read_nointr(int fd
, void *buf
, size_t count
)
113 ret
= read(fd
, buf
, count
);
114 if (ret
< 0 && errno
== EINTR
)
120 ssize_t
lxc_read_nointr_expect(int fd
, void *buf
, size_t count
, const void *expected_buf
)
124 ret
= lxc_read_nointr(fd
, buf
, count
);
128 if ((size_t)ret
!= count
)
131 if (expected_buf
&& memcmp(buf
, expected_buf
, count
) != 0) {
139 bool file_exists(const char *f
)
143 return stat(f
, &statbuf
) == 0;
146 int print_to_file(const char *file
, const char *content
)
151 f
= fopen(file
, "w");
155 if (fprintf(f
, "%s", content
) != strlen(content
))
162 int is_dir(const char *path
)
167 ret
= stat(path
, &statbuf
);
168 if (ret
== 0 && S_ISDIR(statbuf
.st_mode
))
175 * Return the number of lines in file @fn, or -1 on error
177 int lxc_count_file_lines(const char *fn
)
184 f
= fopen_cloexec(fn
, "r");
188 while (getline(&line
, &sz
, f
) != -1) {
197 int lxc_make_tmpfile(char *template, bool rm
)
203 fd
= mkstemp(template);
211 ret
= unlink(template);
220 /* In overlayfs, st_dev is unreliable. So on overlayfs we don't do the
223 static bool is_native_overlayfs(const char *path
)
225 if (has_fs_type(path
, OVERLAY_SUPER_MAGIC
) ||
226 has_fs_type(path
, OVERLAYFS_SUPER_MAGIC
))
232 bool is_fs_type(const struct statfs
*fs
, fs_type_magic magic_val
)
234 return (fs
->f_type
== (fs_type_magic
)magic_val
);
237 bool has_fs_type(const char *path
, fs_type_magic magic_val
)
243 ret
= statfs(path
, &sb
);
247 return is_fs_type(&sb
, magic_val
);
250 bool fhas_fs_type(int fd
, fs_type_magic magic_val
)
255 ret
= fstatfs(fd
, &sb
);
259 return is_fs_type(&sb
, magic_val
);
262 FILE *fopen_cloexec(const char *path
, const char *mode
)
270 if (!strncmp(mode
, "r+", 2)) {
273 } else if (!strncmp(mode
, "r", 1)) {
274 open_mode
= O_RDONLY
;
276 } else if (!strncmp(mode
, "w+", 2)) {
277 open_mode
= O_RDWR
| O_TRUNC
| O_CREAT
;
279 } else if (!strncmp(mode
, "w", 1)) {
280 open_mode
= O_WRONLY
| O_TRUNC
| O_CREAT
;
282 } else if (!strncmp(mode
, "a+", 2)) {
283 open_mode
= O_RDWR
| O_CREAT
| O_APPEND
;
285 } else if (!strncmp(mode
, "a", 1)) {
286 open_mode
= O_WRONLY
| O_CREAT
| O_APPEND
;
289 for (; mode
[step
]; step
++)
290 if (mode
[step
] == 'x')
292 open_mode
|= O_CLOEXEC
;
294 fd
= open(path
, open_mode
, 0666);
298 ret
= fdopen(fd
, mode
);