summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-09-13 06:19:31 +0000
committerNick Mathewson <nickm@torproject.org>2005-09-13 06:19:31 +0000
commitd4fb1fcd6cdaaa7f8ffefbb7c6d44045b5081197 (patch)
tree6d7da2a1110a2d9ee32fa473b4bc3b5e468b562c
parent82b3b6249c796a4b3339d8a20a76593ab3c0479a (diff)
downloadtor-d4fb1fcd6cdaaa7f8ffefbb7c6d44045b5081197.tar.gz
tor-d4fb1fcd6cdaaa7f8ffefbb7c6d44045b5081197.zip
Two new functions like write_bytes_to_file: one takes a list of byte-and-len structs; one appends.
svn:r5024
-rw-r--r--src/common/util.c82
-rw-r--r--src/common/util.h10
2 files changed, 75 insertions, 17 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 8805ef053a..dd02661718 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -884,10 +884,10 @@ write_str_to_file(const char *fname, const char *str, int bin)
return write_bytes_to_file(fname, str, strlen(str), bin);
}
-/** As write_str_to_file, but does not assume a NUL-terminated *
- * string. Instead, we write <b>len</b> bytes, starting at <b>str</b>. */
-int write_bytes_to_file(const char *fname, const char *str, size_t len,
- int bin)
+/* DOCDOC */
+static int
+write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks,
+ int open_flags)
{
size_t tempname_len;
char *tempname;
@@ -896,29 +896,38 @@ int write_bytes_to_file(const char *fname, const char *str, size_t len,
tempname_len = strlen(fname)+16;
tor_assert(tempname_len > strlen(fname)); /*check for overflow*/
tempname = tor_malloc(tempname_len);
- if (tor_snprintf(tempname, tempname_len, "%s.tmp", fname)<0) {
- log(LOG_WARN, "Failed to generate filename");
- goto err;
+ if (open_flags & O_APPEND) {
+ strlcpy(tempname, fname, tempname_len);
+ } else {
+ if (tor_snprintf(tempname, tempname_len, "%s.tmp", fname)<0) {
+ log(LOG_WARN, "Failed to generate filename");
+ goto err;
+ }
}
- if ((fd = open(tempname, O_WRONLY|O_CREAT|O_TRUNC|(bin?O_BINARY:O_TEXT), 0600))
+ if ((fd = open(tempname, open_flags, 0600))
< 0) {
log(LOG_WARN, "Couldn't open \"%s\" for writing: %s", tempname,
strerror(errno));
goto err;
}
- result = write_all(fd, str, len, 0);
- if (result < 0 || (size_t)result != len) {
- log(LOG_WARN, "Error writing to \"%s\": %s", tempname, strerror(errno));
- close(fd);
- goto err;
- }
+ SMARTLIST_FOREACH(chunks, sized_chunk_t *, chunk,
+ {
+ result = write_all(fd, chunk->bytes, chunk->len, 0);
+ if (result < 0 || (size_t)result != chunk->len) {
+ log(LOG_WARN, "Error writing to \"%s\": %s", tempname, strerror(errno));
+ close(fd);
+ goto err;
+ }
+ });
if (close(fd)) {
log(LOG_WARN,"Error flushing to \"%s\": %s", tempname, strerror(errno));
goto err;
}
- if (replace_file(tempname, fname)) {
- log(LOG_WARN, "Error replacing \"%s\": %s", fname, strerror(errno));
- goto err;
+ if (!(open_flags & O_APPEND)) {
+ if (replace_file(tempname, fname)) {
+ log(LOG_WARN, "Error replacing \"%s\": %s", fname, strerror(errno));
+ goto err;
+ }
}
tor_free(tempname);
return 0;
@@ -927,6 +936,45 @@ int write_bytes_to_file(const char *fname, const char *str, size_t len,
return -1;
}
+/* DOCDOC */
+int
+write_chunks_to_file(const char *fname, const smartlist_t *chunks, int bin)
+{
+ int flags = O_WRONLY|O_CREAT|O_TRUNC|(bin?O_BINARY:O_TEXT);
+ return write_chunks_to_file_impl(fname, chunks, flags);
+}
+
+/** As write_str_to_file, but does not assume a NUL-terminated *
+ * string. Instead, we write <b>len</b> bytes, starting at <b>str</b>. */
+int
+write_bytes_to_file(const char *fname, const char *str, size_t len,
+ int bin)
+{
+ int flags = O_WRONLY|O_CREAT|O_TRUNC|(bin?O_BINARY:O_TEXT);
+ int r;
+ sized_chunk_t c = { str, len };
+ smartlist_t *chunks = smartlist_create();
+ smartlist_add(chunks, &c);
+ r = write_chunks_to_file_impl(fname, chunks, flags);
+ smartlist_free(chunks);
+ return r;
+}
+
+/* DOCDOC */
+int
+append_bytes_to_file(const char *fname, const char *str, size_t len,
+ int bin)
+{
+ int flags = O_WRONLY|O_CREAT|O_APPEND|(bin?O_BINARY:O_TEXT);
+ int r;
+ sized_chunk_t c = { str, len };
+ smartlist_t *chunks = smartlist_create();
+ smartlist_add(chunks, &c);
+ r = write_chunks_to_file_impl(fname, chunks, flags);
+ smartlist_free(chunks);
+ return r;
+}
+
/** Read the contents of <b>filename</b> into a newly allocated
* string; return the string on success or NULL on failure.
*/
diff --git a/src/common/util.h b/src/common/util.h
index d2a0051ceb..791b023e25 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -121,6 +121,16 @@ int check_private_dir(const char *dirname, cpd_check_t check);
int write_str_to_file(const char *fname, const char *str, int bin);
int write_bytes_to_file(const char *fname, const char *str, size_t len,
int bin);
+typedef struct sized_chunk_t {
+ const char *bytes;
+ size_t len;
+} sized_chunk_t;
+struct smartlist_t;
+int write_chunks_to_file(const char *fname, const struct smartlist_t *chunks,
+ int bin);
+int append_bytes_to_file(const char *fname, const char *str, size_t len,
+ int bin);
+
char *read_file_to_str(const char *filename, int bin);
char *parse_line_from_str(char *line, char **key_out, char **value_out);
char *expand_filename(const char *filename);