29#ifdef HAVE_SYS_TYPES_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));
89 FILE *result = fopen(p, mode);
92 if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) {
93 log_warn(
LD_FS,
"Couldn't set FD_CLOEXEC: %s", strerror(errno));
106 log_debug(
LD_FS,
"Renaming %s to %s", path_old, path_new);
129 if (unlink(to))
return -1;
145 if (utime(fname, NULL)!=0)
157 return unlink(pathname);
167 raw_assert(count < SSIZE_MAX);
169 while (written != count) {
170 result = write(fd, buf+written, count-written);
175 return (ssize_t)count;
192 while (numread < count) {
193 result = read(fd, buf+numread, count-numread);
196 else if (result == 0)
200 return (ssize_t)numread;
218 if (!fname || strlen(fname) == 0) {
221 f = tor_strdup(fname);
223 log_debug(
LD_FS,
"stat()ing %s", f);
227 if (errno == ENOENT) {
232 if (st.st_mode & S_IFDIR) {
234 }
else if (st.st_mode & S_IFREG) {
235 if (st.st_size > 0) {
237 }
else if (st.st_size == 0) {
243 }
else if (st.st_mode & S_IFIFO) {
256 return file_type != FN_ERROR && file_type != FN_NOENT && file_type != FN_DIR;
264 return file_type == FN_DIR;
278 if (!bin && strchr(str,
'\r')) {
280 "We're writing a text string that already contains a CR to %s",
322 const char *open_name;
327#if (O_BINARY != 0 && O_TEXT != 0)
328 tor_assert((open_flags & (O_BINARY|O_TEXT)) != 0);
331 new_file->
filename = tor_strdup(fname);
332 if (open_flags & O_APPEND) {
336 open_flags &= ~O_APPEND;
341 open_flags |= O_CREAT|O_TRUNC;
342 open_flags &= ~O_EXCL;
346 if (open_flags & O_BINARY)
351 if (new_file->
fd < 0) {
352 log_warn(
LD_FS,
"Couldn't open \"%s\" (%s) for writing: %s",
353 open_name, fname, strerror(errno));
358 log_warn(
LD_FS,
"Couldn't seek to end of file \"%s\": %s", open_name,
364 *data_out = new_file;
369 if (new_file->
fd >= 0)
389 file_data->
binary?
"ab":
"a"))) {
390 log_warn(
LD_FS,
"Couldn't fdopen \"%s\" [%d]: %s", file_data->
filename,
391 file_data->
fd, strerror(errno));
417finish_writing_to_file_impl(
open_file_t *file_data,
int abort_write)
424 log_warn(
LD_FS,
"Error closing \"%s\": %s", file_data->
filename,
426 abort_write = r = -1;
428 }
else if (file_data->
fd >= 0 && close(file_data->
fd) < 0) {
429 log_warn(
LD_FS,
"Error flushing \"%s\": %s", file_data->
filename,
431 abort_write = r = -1;
439 log_warn(
LD_FS,
"Error replacing \"%s\": %s", file_data->
filename,
441 abort_write = r = -1;
445 int res = unlink(file_data->
tempname);
448 log_warn(
LD_FS,
"Failed to unlink %s: %s",
449 file_data->
tempname, strerror(errno));
468 return finish_writing_to_file_impl(file_data, 0);
476 return finish_writing_to_file_impl(file_data, 1);
484write_chunks_to_file_impl(
const char *fname,
const smartlist_t *chunks,
497 log_warn(
LD_FS,
"Error writing to \"%s\": %s", fname,
515write_chunks_to_file(
const char *fname,
const smartlist_t *chunks,
int bin,
518 int flags = OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT);
524 return write_chunks_to_file_impl(fname, chunks, flags);
530write_bytes_to_file_impl(
const char *fname,
const char *str,
size_t len,
537 r = write_chunks_to_file_impl(fname, chunks, flags);
538 smartlist_free(chunks);
548 return write_bytes_to_file_impl(fname, str, len,
549 OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT));
558 return write_bytes_to_file_impl(fname, str, len,
559 OPEN_FLAGS_APPEND|(bin?O_BINARY:O_TEXT));
568 return write_bytes_to_file_impl(fname, str, len,
569 OPEN_FLAGS_DONT_REPLACE|
570 (bin?O_BINARY:O_TEXT));
587 size_t string_max = 0;
598 string_max = pos + 1024;
599 if (string_max > max_bytes_to_read)
600 string_max = max_bytes_to_read + 1;
601 string = tor_realloc(
string, string_max);
602 r = read(fd,
string + pos, string_max - pos - 1);
604 int save_errno = errno;
611 }
while (r > 0 && pos < max_bytes_to_read);
640read_file_to_str, (
const char *filename,
int flags,
struct stat *stat_out))
653 int save_errno = errno;
656 log_fn(severity,
LD_FS,
"Could not open \"%s\": %s",filename,
662 if (fstat(fd, &statbuf)<0) {
663 int save_errno = errno;
665 log_warn(
LD_FS,
"Could not fstat \"%s\".",filename);
673#define FIFO_READ_MAX (1024*1024)
674 if (S_ISFIFO(statbuf.st_mode)) {
677 int save_errno = errno;
678 if (
string && stat_out) {
679 statbuf.st_size = sz;
680 memcpy(stat_out, &statbuf,
sizeof(
struct stat));
695 string = tor_malloc((
size_t)(statbuf.st_size+1));
699 int save_errno = errno;
700 log_warn(
LD_FS,
"Error reading from file \"%s\": %s", filename,
709 if (!bin && strchr(
string,
'\r')) {
710 log_debug(
LD_FS,
"We didn't convert CRLF to LF as well as we hoped "
711 "when reading %s. Coping.",
717 statbuf.st_size = (size_t) r;
719 if (r != statbuf.st_size) {
722 int save_errno = errno;
723 log_warn(
LD_FS,
"Could read only %d of %ld bytes of file \"%s\".",
724 (
int)r, (
long)statbuf.st_size,filename);
733 memcpy(stat_out, &statbuf,
sizeof(
struct stat));
750 if (!fstr || strcmp(str, fstr)) {
759#if !defined(HAVE_GETDELIM) || defined(TOR_UNIT_TESTS)
760#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.
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(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)
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 * 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)
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)
FILE * tor_fopen_cloexec(const char *path, const char *mode)
int tor_rename(const char *path_old, const char *path_new)
bool is_file(file_status_t file_type)
FILE * fdopen_file(open_file_t *file_data)
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.