29 #ifdef HAVE_SYS_TYPES_H
30 #include <sys/types.h>
32 #ifdef HAVE_SYS_STAT_H
38 #ifdef HAVE_SYS_TIME_H
59 fd = open(p, flags|O_CLOEXEC, mode);
69 log_debug(
LD_FS,
"Opening %s with flags %x", p, flags);
70 fd = open(p, flags, mode);
73 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
74 log_warn(
LD_FS,
"Couldn't set FD_CLOEXEC: %s", strerror(errno));
88 FILE *result = fopen(path, mode);
91 if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) {
92 log_warn(
LD_FS,
"Couldn't set FD_CLOEXEC: %s", strerror(errno));
105 log_debug(
LD_FS,
"Renaming %s to %s", path_old, path_new);
128 if (unlink(to))
return -1;
144 if (utime(fname, NULL)!=0)
156 return unlink(pathname);
166 raw_assert(count < SSIZE_MAX);
168 while (written != count) {
169 result = write(fd, buf+written, count-written);
174 return (ssize_t)count;
191 while (numread < count) {
192 result = read(fd, buf+numread, count-numread);
195 else if (result == 0)
199 return (ssize_t)numread;
217 if (!fname || strlen(fname) == 0) {
220 f = tor_strdup(fname);
222 log_debug(
LD_FS,
"stat()ing %s", f);
226 if (errno == ENOENT) {
231 if (st.st_mode & S_IFDIR) {
233 }
else if (st.st_mode & S_IFREG) {
234 if (st.st_size > 0) {
236 }
else if (st.st_size == 0) {
242 }
else if (st.st_mode & S_IFIFO) {
255 return file_type != FN_ERROR && file_type != FN_NOENT && file_type != FN_DIR;
263 return file_type == FN_DIR;
277 if (!bin && strchr(str,
'\r')) {
279 "We're writing a text string that already contains a CR to %s",
321 const char *open_name;
326 #if (O_BINARY != 0 && O_TEXT != 0)
327 tor_assert((open_flags & (O_BINARY|O_TEXT)) != 0);
330 new_file->
filename = tor_strdup(fname);
331 if (open_flags & O_APPEND) {
335 open_flags &= ~O_APPEND;
340 open_flags |= O_CREAT|O_TRUNC;
341 open_flags &= ~O_EXCL;
345 if (open_flags & O_BINARY)
350 if (new_file->
fd < 0) {
351 log_warn(
LD_FS,
"Couldn't open \"%s\" (%s) for writing: %s",
352 open_name, fname, strerror(errno));
357 log_warn(
LD_FS,
"Couldn't seek to end of file \"%s\": %s", open_name,
363 *data_out = new_file;
368 if (new_file->
fd >= 0)
388 file_data->
binary?
"ab":
"a"))) {
389 log_warn(
LD_FS,
"Couldn't fdopen \"%s\" [%d]: %s", file_data->
filename,
390 file_data->
fd, strerror(errno));
416 finish_writing_to_file_impl(
open_file_t *file_data,
int abort_write)
423 log_warn(
LD_FS,
"Error closing \"%s\": %s", file_data->
filename,
425 abort_write = r = -1;
427 }
else if (file_data->
fd >= 0 && close(file_data->
fd) < 0) {
428 log_warn(
LD_FS,
"Error flushing \"%s\": %s", file_data->
filename,
430 abort_write = r = -1;
438 log_warn(
LD_FS,
"Error replacing \"%s\": %s", file_data->
filename,
440 abort_write = r = -1;
444 int res = unlink(file_data->
tempname);
447 log_warn(
LD_FS,
"Failed to unlink %s: %s",
448 file_data->
tempname, strerror(errno));
467 return finish_writing_to_file_impl(file_data, 0);
475 return finish_writing_to_file_impl(file_data, 1);
483 write_chunks_to_file_impl(
const char *fname,
const smartlist_t *chunks,
496 log_warn(
LD_FS,
"Error writing to \"%s\": %s", fname,
514 write_chunks_to_file(
const char *fname,
const smartlist_t *chunks,
int bin,
517 int flags = OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT);
523 return write_chunks_to_file_impl(fname, chunks, flags);
529 write_bytes_to_file_impl(
const char *fname,
const char *str,
size_t len,
536 r = write_chunks_to_file_impl(fname, chunks, flags);
537 smartlist_free(chunks);
547 return write_bytes_to_file_impl(fname, str, len,
548 OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT));
557 return write_bytes_to_file_impl(fname, str, len,
558 OPEN_FLAGS_APPEND|(bin?O_BINARY:O_TEXT));
567 return write_bytes_to_file_impl(fname, str, len,
568 OPEN_FLAGS_DONT_REPLACE|
569 (bin?O_BINARY:O_TEXT));
585 size_t string_max = 0;
596 string_max = pos + 1024;
597 if (string_max > max_bytes_to_read)
598 string_max = max_bytes_to_read + 1;
599 string = tor_realloc(
string, string_max);
600 r = read(fd,
string + pos, string_max - pos - 1);
602 int save_errno = errno;
609 }
while (r > 0 && pos < max_bytes_to_read);
638 read_file_to_str, (
const char *filename,
int flags,
struct stat *stat_out))
651 int save_errno = errno;
654 log_fn(severity,
LD_FS,
"Could not open \"%s\": %s",filename,
660 if (fstat(fd, &statbuf)<0) {
661 int save_errno = errno;
663 log_warn(
LD_FS,
"Could not fstat \"%s\".",filename);
671 #define FIFO_READ_MAX (1024*1024)
672 if (S_ISFIFO(statbuf.st_mode)) {
675 int save_errno = errno;
676 if (
string && stat_out) {
677 statbuf.st_size = sz;
678 memcpy(stat_out, &statbuf,
sizeof(
struct stat));
693 string = tor_malloc((
size_t)(statbuf.st_size+1));
697 int save_errno = errno;
698 log_warn(
LD_FS,
"Error reading from file \"%s\": %s", filename,
707 if (!bin && strchr(
string,
'\r')) {
708 log_debug(
LD_FS,
"We didn't convert CRLF to LF as well as we hoped "
709 "when reading %s. Coping.",
715 statbuf.st_size = (size_t) r;
717 if (r != statbuf.st_size) {
720 int save_errno = errno;
721 log_warn(
LD_FS,
"Could read only %d of %ld bytes of file \"%s\".",
722 (
int)r, (
long)statbuf.st_size,filename);
731 memcpy(stat_out, &statbuf,
sizeof(
struct stat));
748 if (!fstr || strcmp(str, fstr)) {
757 #if !defined(HAVE_GETDELIM) || defined(TOR_UNIT_TESTS)
758 #include "ext/getdelim.c"
const char * escaped(const char *s)
int tor_fd_seekend(int fd)
Wrappers for reading and writing data to files on disk.
int write_str_to_file(const char *fname, const char *str, int bin)
ssize_t read_all_from_fd(int fd, char *buf, size_t count)
int tor_unlink(const char *pathname)
#define RFTS_IGNORE_MISSING
file_status_t file_status(const char *filename)
int finish_writing_to_file(open_file_t *file_data)
int write_bytes_to_new_file(const char *fname, const char *str, size_t len, int bin)
int start_writing_to_file(const char *fname, int open_flags, int mode, open_file_t **data_out)
int tor_open_cloexec(const char *path, int flags, unsigned mode)
int touch_file(const char *fname)
ssize_t write_all_to_fd(int fd, const char *buf, size_t count)
char * read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) ATTR_MALLOC
int write_str_to_file_if_not_equal(const char *fname, const char *str)
int append_bytes_to_file(const char *fname, const char *str, size_t len, int bin)
FILE * tor_fopen_cloexec(const char *path, const char *mode)
FILE * start_writing_to_stdio_file(const char *fname, int open_flags, int mode, open_file_t **data_out)
int replace_file(const char *from, const char *to)
FILE * fdopen_file(open_file_t *file_data)
int abort_writing_to_file(open_file_t *file_data)
int write_bytes_to_file(const char *fname, const char *str, size_t len, int bin)
int tor_rename(const char *path_old, const char *path_new)
bool is_file(file_status_t file_type)
bool is_dir(file_status_t file_type)
#define log_fn(severity, domain, args,...)
Headers for util_malloc.c.
void clean_fname_for_stat(char *name)
int tor_asprintf(char **strp, const char *fmt,...)
Header file for sandbox.c.
#define sandbox_intern_string(s)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define MOCK_IMPL(rv, funcname, arglist)
Macros to manage assertions, fatal and non-fatal.
void tor_strstrip(char *s, const char *strip)
Header for util_string.c.