Tor  0.4.7.0-alpha-dev
files.c
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file files.h
8  *
9  * \brief Wrappers for reading and writing data to files on disk.
10  **/
11 
12 #ifdef _WIN32
13 #include <windows.h>
14 #endif
15 
16 #include "lib/fs/files.h"
17 #include "lib/fs/path.h"
19 #include "lib/log/log.h"
20 #include "lib/log/util_bug.h"
21 #include "lib/log/escape.h"
22 #include "lib/err/torerr.h"
23 #include "lib/malloc/malloc.h"
24 #include "lib/sandbox/sandbox.h"
25 #include "lib/string/printf.h"
26 #include "lib/string/util_string.h"
27 #include "lib/fdio/fdio.h"
28 
29 #ifdef HAVE_SYS_TYPES_H
30 #include <sys/types.h>
31 #endif
32 #ifdef HAVE_SYS_STAT_H
33 #include <sys/stat.h>
34 #endif
35 #ifdef HAVE_UTIME_H
36 #include <utime.h>
37 #endif
38 #ifdef HAVE_SYS_TIME_H
39 #include <sys/time.h>
40 #endif
41 #ifdef HAVE_FCNTL_H
42 #include <fcntl.h>
43 #endif
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47 #include <errno.h>
48 #include <stdio.h>
49 #include <string.h>
50 
51 /** As open(path, flags, mode), but return an fd with the close-on-exec mode
52  * set. */
53 int
54 tor_open_cloexec(const char *path, int flags, unsigned mode)
55 {
56  int fd;
57  const char *p = sandbox_intern_string(path);
58 #ifdef O_CLOEXEC
59  fd = open(p, flags|O_CLOEXEC, mode);
60  if (fd >= 0)
61  return fd;
62  /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
63  * even though we were built on a system with O_CLOEXEC support, we
64  * are running on one without. */
65  if (errno != EINVAL)
66  return -1;
67 #endif /* defined(O_CLOEXEC) */
68 
69  log_debug(LD_FS, "Opening %s with flags %x", p, flags);
70  fd = open(p, flags, mode);
71 #ifdef FD_CLOEXEC
72  if (fd >= 0) {
73  if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
74  log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
75  close(fd);
76  return -1;
77  }
78  }
79 #endif /* defined(FD_CLOEXEC) */
80  return fd;
81 }
82 
83 /** As fopen(path,mode), but ensures that the O_CLOEXEC bit is set on the
84  * underlying file handle. */
85 FILE *
86 tor_fopen_cloexec(const char *path, const char *mode)
87 {
88  FILE *result = fopen(path, mode);
89 #ifdef FD_CLOEXEC
90  if (result != NULL) {
91  if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) {
92  log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
93  fclose(result);
94  return NULL;
95  }
96  }
97 #endif /* defined(FD_CLOEXEC) */
98  return result;
99 }
100 
101 /** As rename(), but work correctly with the sandbox. */
102 int
103 tor_rename(const char *path_old, const char *path_new)
104 {
105  log_debug(LD_FS, "Renaming %s to %s", path_old, path_new);
106  return rename(sandbox_intern_string(path_old),
107  sandbox_intern_string(path_new));
108 }
109 
110 /**
111  * Rename the file <b>from</b> to the file <b>to</b>. On Unix, this is
112  * the same as rename(2). On windows, this removes <b>to</b> first if
113  * it already exists.
114  * Returns 0 on success. Returns -1 and sets errno on failure.
115  */
116 int
117 replace_file(const char *from, const char *to)
118 {
119 #ifndef _WIN32
120  return tor_rename(from, to);
121 #else
122  switch (file_status(to))
123  {
124  case FN_NOENT:
125  break;
126  case FN_FILE:
127  case FN_EMPTY:
128  if (unlink(to)) return -1;
129  break;
130  case FN_ERROR:
131  return -1;
132  case FN_DIR:
133  errno = EISDIR;
134  return -1;
135  }
136  return tor_rename(from,to);
137 #endif /* !defined(_WIN32) */
138 }
139 
140 /** Change <b>fname</b>'s modification time to now. */
141 int
142 touch_file(const char *fname)
143 {
144  if (utime(fname, NULL)!=0)
145  return -1;
146  return 0;
147 }
148 
149 /** Wrapper for unlink() to make it mockable for the test suite; returns 0
150  * if unlinking the file succeeded, -1 and sets errno if unlinking fails.
151  */
152 
153 MOCK_IMPL(int,
154 tor_unlink,(const char *pathname))
155 {
156  return unlink(pathname);
157 }
158 
159 /** Write <b>count</b> bytes from <b>buf</b> to <b>fd</b>. Return the number
160  * of bytes written, or -1 on error. Only use if fd is a blocking fd. */
161 ssize_t
162 write_all_to_fd(int fd, const char *buf, size_t count)
163 {
164  size_t written = 0;
165  ssize_t result;
166  raw_assert(count < SSIZE_MAX);
167 
168  while (written != count) {
169  result = write(fd, buf+written, count-written);
170  if (result<0)
171  return -1;
172  written += result;
173  }
174  return (ssize_t)count;
175 }
176 
177 /** Read from <b>fd</b> to <b>buf</b>, until we get <b>count</b> bytes or
178  * reach the end of the file. Return the number of bytes read, or -1 on
179  * error. Only use if fd is a blocking fd. */
180 ssize_t
181 read_all_from_fd(int fd, char *buf, size_t count)
182 {
183  size_t numread = 0;
184  ssize_t result;
185 
186  if (count > SIZE_T_CEILING || count > SSIZE_MAX) {
187  errno = EINVAL;
188  return -1;
189  }
190 
191  while (numread < count) {
192  result = read(fd, buf+numread, count-numread);
193  if (result<0)
194  return -1;
195  else if (result == 0)
196  break;
197  numread += result;
198  }
199  return (ssize_t)numread;
200 }
201 
202 /** Return:
203  * FN_ERROR if filename can't be read, is NULL, or is zero-length,
204  * FN_NOENT if it doesn't exist,
205  * FN_FILE if it is a non-empty regular file, or a FIFO on unix-like systems,
206  * FN_EMPTY for zero-byte regular files,
207  * FN_DIR if it's a directory, and
208  * FN_ERROR for any other file type.
209  * On FN_ERROR and FN_NOENT, sets errno. (errno is not set when FN_ERROR
210  * is returned due to an unhandled file type.) */
212 file_status(const char *fname)
213 {
214  struct stat st;
215  char *f;
216  int r;
217  if (!fname || strlen(fname) == 0) {
218  return FN_ERROR;
219  }
220  f = tor_strdup(fname);
222  log_debug(LD_FS, "stat()ing %s", f);
223  r = stat(sandbox_intern_string(f), &st);
224  tor_free(f);
225  if (r) {
226  if (errno == ENOENT) {
227  return FN_NOENT;
228  }
229  return FN_ERROR;
230  }
231  if (st.st_mode & S_IFDIR) {
232  return FN_DIR;
233  } else if (st.st_mode & S_IFREG) {
234  if (st.st_size > 0) {
235  return FN_FILE;
236  } else if (st.st_size == 0) {
237  return FN_EMPTY;
238  } else {
239  return FN_ERROR;
240  }
241 #ifndef _WIN32
242  } else if (st.st_mode & S_IFIFO) {
243  return FN_FILE;
244 #endif
245  } else {
246  return FN_ERROR;
247  }
248 }
249 
250 /** Returns true if <b>file_type</b> represents an existing file (even if
251  * empty). Returns false otherwise. */
252 bool
254 {
255  return file_type != FN_ERROR && file_type != FN_NOENT && file_type != FN_DIR;
256 }
257 
258 /** Returns true if <b>file_type</b> represents an existing directory. Returns
259  * false otherwise. */
260 bool
262 {
263  return file_type == FN_DIR;
264 }
265 
266 /** Create a file named <b>fname</b> with the contents <b>str</b>. Overwrite
267  * the previous <b>fname</b> if possible. Return 0 on success, -1 on failure.
268  *
269  * This function replaces the old file atomically, if possible. This
270  * function, and all other functions in util.c that create files, create them
271  * with mode 0600.
272  */
273 MOCK_IMPL(int,
274 write_str_to_file,(const char *fname, const char *str, int bin))
275 {
276 #ifdef _WIN32
277  if (!bin && strchr(str, '\r')) {
278  log_warn(LD_BUG,
279  "We're writing a text string that already contains a CR to %s",
280  escaped(fname));
281  }
282 #endif /* defined(_WIN32) */
283  return write_bytes_to_file(fname, str, strlen(str), bin);
284 }
285 
286 /** Represents a file that we're writing to, with support for atomic commit:
287  * we can write into a temporary file, and either remove the file on
288  * failure, or replace the original file on success. */
289 struct open_file_t {
290  char *tempname; /**< Name of the temporary file. */
291  char *filename; /**< Name of the original file. */
292  unsigned rename_on_close:1; /**< Are we using the temporary file or not? */
293  unsigned binary:1; /**< Did we open in binary mode? */
294  int fd; /**< fd for the open file. */
295  FILE *stdio_file; /**< stdio wrapper for <b>fd</b>. */
296 };
297 
298 /** Try to start writing to the file in <b>fname</b>, passing the flags
299  * <b>open_flags</b> to the open() syscall, creating the file (if needed) with
300  * access value <b>mode</b>. If the O_APPEND flag is set, we append to the
301  * original file. Otherwise, we open a new temporary file in the same
302  * directory, and either replace the original or remove the temporary file
303  * when we're done.
304  *
305  * Return the fd for the newly opened file, and store working data in
306  * *<b>data_out</b>. The caller should not close the fd manually:
307  * instead, call finish_writing_to_file() or abort_writing_to_file().
308  * Returns -1 on failure.
309  *
310  * NOTE: When not appending, the flags O_CREAT and O_TRUNC are treated
311  * as true and the flag O_EXCL is treated as false.
312  *
313  * NOTE: Ordinarily, O_APPEND means "seek to the end of the file before each
314  * write()". We don't do that.
315  */
316 int
317 start_writing_to_file(const char *fname, int open_flags, int mode,
318  open_file_t **data_out)
319 {
320  open_file_t *new_file = tor_malloc_zero(sizeof(open_file_t));
321  const char *open_name;
322  int append = 0;
323 
324  tor_assert(fname);
325  tor_assert(data_out);
326 #if (O_BINARY != 0 && O_TEXT != 0)
327  tor_assert((open_flags & (O_BINARY|O_TEXT)) != 0);
328 #endif
329  new_file->fd = -1;
330  new_file->filename = tor_strdup(fname);
331  if (open_flags & O_APPEND) {
332  open_name = fname;
333  new_file->rename_on_close = 0;
334  append = 1;
335  open_flags &= ~O_APPEND;
336  } else {
337  tor_asprintf(&new_file->tempname, "%s.tmp", fname);
338  open_name = new_file->tempname;
339  /* We always replace an existing temporary file if there is one. */
340  open_flags |= O_CREAT|O_TRUNC;
341  open_flags &= ~O_EXCL;
342  new_file->rename_on_close = 1;
343  }
344 #if O_BINARY != 0
345  if (open_flags & O_BINARY)
346  new_file->binary = 1;
347 #endif
348 
349  new_file->fd = tor_open_cloexec(open_name, open_flags, mode);
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));
353  goto err;
354  }
355  if (append) {
356  if (tor_fd_seekend(new_file->fd) < 0) {
357  log_warn(LD_FS, "Couldn't seek to end of file \"%s\": %s", open_name,
358  strerror(errno));
359  goto err;
360  }
361  }
362 
363  *data_out = new_file;
364 
365  return new_file->fd;
366 
367  err:
368  if (new_file->fd >= 0)
369  close(new_file->fd);
370  *data_out = NULL;
371  tor_free(new_file->filename);
372  tor_free(new_file->tempname);
373  tor_free(new_file);
374  return -1;
375 }
376 
377 /** Given <b>file_data</b> from start_writing_to_file(), return a stdio FILE*
378  * that can be used to write to the same file. The caller should not mix
379  * stdio calls with non-stdio calls. */
380 FILE *
382 {
383  tor_assert(file_data);
384  if (file_data->stdio_file)
385  return file_data->stdio_file;
386  tor_assert(file_data->fd >= 0);
387  if (!(file_data->stdio_file = fdopen(file_data->fd,
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));
391  }
392  return file_data->stdio_file;
393 }
394 
395 /** Combines start_writing_to_file with fdopen_file(): arguments are as
396  * for start_writing_to_file, but */
397 FILE *
398 start_writing_to_stdio_file(const char *fname, int open_flags, int mode,
399  open_file_t **data_out)
400 {
401  FILE *res;
402  if (start_writing_to_file(fname, open_flags, mode, data_out)<0)
403  return NULL;
404  if (!(res = fdopen_file(*data_out))) {
405  abort_writing_to_file(*data_out);
406  *data_out = NULL;
407  }
408  return res;
409 }
410 
411 /** Helper function: close and free the underlying file and memory in
412  * <b>file_data</b>. If we were writing into a temporary file, then delete
413  * that file (if abort_write is true) or replaces the target file with
414  * the temporary file (if abort_write is false). */
415 static int
416 finish_writing_to_file_impl(open_file_t *file_data, int abort_write)
417 {
418  int r = 0;
419 
420  tor_assert(file_data && file_data->filename);
421  if (file_data->stdio_file) {
422  if (fclose(file_data->stdio_file)) {
423  log_warn(LD_FS, "Error closing \"%s\": %s", file_data->filename,
424  strerror(errno));
425  abort_write = r = -1;
426  }
427  } else if (file_data->fd >= 0 && close(file_data->fd) < 0) {
428  log_warn(LD_FS, "Error flushing \"%s\": %s", file_data->filename,
429  strerror(errno));
430  abort_write = r = -1;
431  }
432 
433  if (file_data->rename_on_close) {
434  tor_assert(file_data->tempname && file_data->filename);
435  if (!abort_write) {
436  tor_assert(strcmp(file_data->filename, file_data->tempname));
437  if (replace_file(file_data->tempname, file_data->filename)) {
438  log_warn(LD_FS, "Error replacing \"%s\": %s", file_data->filename,
439  strerror(errno));
440  abort_write = r = -1;
441  }
442  }
443  if (abort_write) {
444  int res = unlink(file_data->tempname);
445  if (res != 0) {
446  /* We couldn't unlink and we'll leave a mess behind */
447  log_warn(LD_FS, "Failed to unlink %s: %s",
448  file_data->tempname, strerror(errno));
449  r = -1;
450  }
451  }
452  }
453 
454  tor_free(file_data->filename);
455  tor_free(file_data->tempname);
456  tor_free(file_data);
457 
458  return r;
459 }
460 
461 /** Finish writing to <b>file_data</b>: close the file handle, free memory as
462  * needed, and if using a temporary file, replace the original file with
463  * the temporary file. */
464 int
466 {
467  return finish_writing_to_file_impl(file_data, 0);
468 }
469 
470 /** Finish writing to <b>file_data</b>: close the file handle, free memory as
471  * needed, and if using a temporary file, delete it. */
472 int
474 {
475  return finish_writing_to_file_impl(file_data, 1);
476 }
477 
478 /** Helper: given a set of flags as passed to open(2), open the file
479  * <b>fname</b> and write all the sized_chunk_t structs in <b>chunks</b> to
480  * the file. Do so as atomically as possible e.g. by opening temp files and
481  * renaming. */
482 static int
483 write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks,
484  int open_flags)
485 {
486  open_file_t *file = NULL;
487  int fd;
488  ssize_t result;
489  fd = start_writing_to_file(fname, open_flags, 0600, &file);
490  if (fd<0)
491  return -1;
492  SMARTLIST_FOREACH(chunks, sized_chunk_t *, chunk,
493  {
494  result = write_all_to_fd(fd, chunk->bytes, chunk->len);
495  if (result < 0) {
496  log_warn(LD_FS, "Error writing to \"%s\": %s", fname,
497  strerror(errno));
498  goto err;
499  }
500  tor_assert((size_t)result == chunk->len);
501  });
502 
503  return finish_writing_to_file(file);
504  err:
505  abort_writing_to_file(file);
506  return -1;
507 }
508 
509 /** Given a smartlist of sized_chunk_t, write them to a file
510  * <b>fname</b>, overwriting or creating the file as necessary.
511  * If <b>no_tempfile</b> is 0 then the file will be written
512  * atomically. */
513 int
514 write_chunks_to_file(const char *fname, const smartlist_t *chunks, int bin,
515  int no_tempfile)
516 {
517  int flags = OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT);
518 
519  if (no_tempfile) {
520  /* O_APPEND stops write_chunks_to_file from using tempfiles */
521  flags |= O_APPEND;
522  }
523  return write_chunks_to_file_impl(fname, chunks, flags);
524 }
525 
526 /** Write <b>len</b> bytes, starting at <b>str</b>, to <b>fname</b>
527  using the open() flags passed in <b>flags</b>. */
528 static int
529 write_bytes_to_file_impl(const char *fname, const char *str, size_t len,
530  int flags)
531 {
532  int r;
533  sized_chunk_t c = { str, len };
534  smartlist_t *chunks = smartlist_new();
535  smartlist_add(chunks, &c);
536  r = write_chunks_to_file_impl(fname, chunks, flags);
537  smartlist_free(chunks);
538  return r;
539 }
540 
541 /** As write_str_to_file, but does not assume a NUL-terminated
542  * string. Instead, we write <b>len</b> bytes, starting at <b>str</b>. */
543 MOCK_IMPL(int,
544 write_bytes_to_file,(const char *fname, const char *str, size_t len,
545  int bin))
546 {
547  return write_bytes_to_file_impl(fname, str, len,
548  OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT));
549 }
550 
551 /** As write_bytes_to_file, but if the file already exists, append the bytes
552  * to the end of the file instead of overwriting it. */
553 int
554 append_bytes_to_file(const char *fname, const char *str, size_t len,
555  int bin)
556 {
557  return write_bytes_to_file_impl(fname, str, len,
558  OPEN_FLAGS_APPEND|(bin?O_BINARY:O_TEXT));
559 }
560 
561 /** Like write_str_to_file(), but also return -1 if there was a file
562  already residing in <b>fname</b>. */
563 int
564 write_bytes_to_new_file(const char *fname, const char *str, size_t len,
565  int bin)
566 {
567  return write_bytes_to_file_impl(fname, str, len,
568  OPEN_FLAGS_DONT_REPLACE|
569  (bin?O_BINARY:O_TEXT));
570 }
571 
572 /**
573  * Read the contents of the open file <b>fd</b> presuming it is a FIFO
574  * (or similar) file descriptor for which the size of the file isn't
575  * known ahead of time. Return NULL on failure, and a NUL-terminated
576  * string on success. On success, set <b>sz_out</b> to the number of
577  * bytes read.
578  */
579 char *
580 read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out)
581 {
582  ssize_t r;
583  size_t pos = 0;
584  char *string = NULL;
585  size_t string_max = 0;
586 
587  if (max_bytes_to_read+1 >= SIZE_T_CEILING) {
588  errno = EINVAL;
589  return NULL;
590  }
591 
592  do {
593  /* XXXX This "add 1K" approach is a little goofy; if we care about
594  * performance here, we should be doubling. But in practice we shouldn't
595  * be using this function on big files anyway. */
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);
601  if (r < 0) {
602  int save_errno = errno;
603  tor_free(string);
604  errno = save_errno;
605  return NULL;
606  }
607 
608  pos += r;
609  } while (r > 0 && pos < max_bytes_to_read);
610 
611  tor_assert(pos < string_max);
612  *sz_out = pos;
613  string[pos] = '\0';
614  return string;
615 }
616 
617 /** Read the contents of <b>filename</b> into a newly allocated
618  * string; return the string on success or NULL on failure.
619  *
620  * If <b>stat_out</b> is provided, store the result of stat()ing the
621  * file into <b>stat_out</b>.
622  *
623  * If <b>flags</b> &amp; RFTS_BIN, open the file in binary mode.
624  * If <b>flags</b> &amp; RFTS_IGNORE_MISSING, don't warn if the file
625  * doesn't exist.
626  *
627  * Unless the RFTS_BIN flag is set in <b>flags</b>, this function will strip
628  * any CR characters in the return value on all platforms.
629  */
630 /*
631  * This function <em>may</em> return an erroneous result if the file
632  * is modified while it is running, but must not crash or overflow.
633  * Right now, the error case occurs when the file length grows between
634  * the call to stat and the call to read_all: the resulting string will
635  * be truncated.
636  */
637 MOCK_IMPL(char *,
638 read_file_to_str, (const char *filename, int flags, struct stat *stat_out))
639 {
640  int fd; /* router file */
641  struct stat statbuf;
642  char *string;
643  ssize_t r;
644  int bin = flags & RFTS_BIN;
645 
646  tor_assert(filename);
647 
648  fd = tor_open_cloexec(filename,O_RDONLY|(bin?O_BINARY:O_TEXT),0);
649  if (fd<0) {
650  int severity = LOG_WARN;
651  int save_errno = errno;
652  if (errno == ENOENT && (flags & RFTS_IGNORE_MISSING))
653  severity = LOG_INFO;
654  log_fn(severity, LD_FS,"Could not open \"%s\": %s",filename,
655  strerror(errno));
656  errno = save_errno;
657  return NULL;
658  }
659 
660  if (fstat(fd, &statbuf)<0) {
661  int save_errno = errno;
662  close(fd);
663  log_warn(LD_FS,"Could not fstat \"%s\".",filename);
664  errno = save_errno;
665  return NULL;
666  }
667 
668 #ifndef _WIN32
669 /** When we detect that we're reading from a FIFO, don't read more than
670  * this many bytes. It's insane overkill for most uses. */
671 #define FIFO_READ_MAX (1024*1024)
672  if (S_ISFIFO(statbuf.st_mode)) {
673  size_t sz = 0;
674  string = read_file_to_str_until_eof(fd, FIFO_READ_MAX, &sz);
675  int save_errno = errno;
676  if (string && stat_out) {
677  statbuf.st_size = sz;
678  memcpy(stat_out, &statbuf, sizeof(struct stat));
679  }
680  close(fd);
681  if (!string)
682  errno = save_errno;
683  return string;
684  }
685 #endif /* !defined(_WIN32) */
686 
687  if ((uint64_t)(statbuf.st_size)+1 >= SIZE_T_CEILING) {
688  close(fd);
689  errno = EINVAL;
690  return NULL;
691  }
692 
693  string = tor_malloc((size_t)(statbuf.st_size+1));
694 
695  r = read_all_from_fd(fd,string,(size_t)statbuf.st_size);
696  if (r<0) {
697  int save_errno = errno;
698  log_warn(LD_FS,"Error reading from file \"%s\": %s", filename,
699  strerror(errno));
700  tor_free(string);
701  close(fd);
702  errno = save_errno;
703  return NULL;
704  }
705  string[r] = '\0'; /* NUL-terminate the result. */
706 
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.",
710  filename);
711  tor_strstrip(string, "\r");
712  r = strlen(string);
713  }
714  if (!bin) {
715  statbuf.st_size = (size_t) r;
716  } else {
717  if (r != statbuf.st_size) {
718  /* Unless we're using text mode on win32, we'd better have an exact
719  * match for 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);
723  tor_free(string);
724  close(fd);
725  errno = save_errno;
726  return NULL;
727  }
728  }
729  close(fd);
730  if (stat_out) {
731  memcpy(stat_out, &statbuf, sizeof(struct stat));
732  }
733 
734  return string;
735 }
736 
737 /** Attempt to read a file <b>fname</b>. If the file's contents is
738  * equal to the string <b>str</b>, return 0. Otherwise, attempt to
739  * overwrite the file with the contents of <b>str</b> and return
740  * the value of write_str_to_file().
741  */
742 int
743 write_str_to_file_if_not_equal(const char *fname, const char *str)
744 {
745  char *fstr = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
746  int rv;
747 
748  if (!fstr || strcmp(str, fstr)) {
749  rv = write_str_to_file(fname, str, 0);
750  } else {
751  rv = 0;
752  }
753  tor_free(fstr);
754  return rv;
755 }
756 
757 #if !defined(HAVE_GETDELIM) || defined(TOR_UNIT_TESTS)
758 #include "ext/getdelim.c"
759 #endif
const char * escaped(const char *s)
Definition: escape.c:126
Header for escape.c.
int tor_fd_seekend(int fd)
Definition: fdio.c:61
Header for fdio.c.
Wrappers for reading and writing data to files on disk.
int write_str_to_file(const char *fname, const char *str, int bin)
Definition: files.c:274
ssize_t read_all_from_fd(int fd, char *buf, size_t count)
Definition: files.c:181
int tor_unlink(const char *pathname)
Definition: files.c:154
#define RFTS_IGNORE_MISSING
Definition: files.h:101
file_status_t file_status(const char *filename)
Definition: files.c:212
int finish_writing_to_file(open_file_t *file_data)
Definition: files.c:465
int write_bytes_to_new_file(const char *fname, const char *str, size_t len, int bin)
Definition: files.c:564
int start_writing_to_file(const char *fname, int open_flags, int mode, open_file_t **data_out)
Definition: files.c:317
int tor_open_cloexec(const char *path, int flags, unsigned mode)
Definition: files.c:54
int touch_file(const char *fname)
Definition: files.c:142
ssize_t write_all_to_fd(int fd, const char *buf, size_t count)
Definition: files.c:162
char * read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) ATTR_MALLOC
Definition: files.c:580
int write_str_to_file_if_not_equal(const char *fname, const char *str)
Definition: files.c:743
file_status_t
Definition: files.h:55
int append_bytes_to_file(const char *fname, const char *str, size_t len, int bin)
Definition: files.c:554
FILE * tor_fopen_cloexec(const char *path, const char *mode)
Definition: files.c:86
FILE * start_writing_to_stdio_file(const char *fname, int open_flags, int mode, open_file_t **data_out)
Definition: files.c:398
int replace_file(const char *from, const char *to)
Definition: files.c:117
FILE * fdopen_file(open_file_t *file_data)
Definition: files.c:381
int abort_writing_to_file(open_file_t *file_data)
Definition: files.c:473
int write_bytes_to_file(const char *fname, const char *str, size_t len, int bin)
Definition: files.c:545
#define RFTS_BIN
Definition: files.h:99
int tor_rename(const char *path_old, const char *path_new)
Definition: files.c:103
bool is_file(file_status_t file_type)
Definition: files.c:253
bool is_dir(file_status_t file_type)
Definition: files.c:261
Headers for log.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_FS
Definition: log.h:70
#define LD_BUG
Definition: log.h:86
#define LOG_WARN
Definition: log.h:53
#define LOG_INFO
Definition: log.h:45
Headers for util_malloc.c.
#define tor_free(p)
Definition: malloc.h:52
void clean_fname_for_stat(char *name)
Definition: path.c:164
Header for path.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Header for printf.c.
Header file for sandbox.c.
#define sandbox_intern_string(s)
Definition: sandbox.h:110
Header for smartlist.c.
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
unsigned rename_on_close
Definition: files.c:292
int fd
Definition: files.c:294
FILE * stdio_file
Definition: files.c:295
unsigned binary
Definition: files.c:293
char * tempname
Definition: files.c:290
char * filename
Definition: files.c:291
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Headers for torerr.c.
#define SIZE_T_CEILING
Definition: torint.h:126
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102
void tor_strstrip(char *s, const char *strip)
Definition: util_string.c:111
Header for util_string.c.