Browse Source

faux.ini: Don't use file stream operations

Serj Kalichev 4 years ago
parent
commit
5d9adb9aa4
3 changed files with 59 additions and 14 deletions
  1. 1 0
      faux/file.h
  2. 30 0
      faux/file/file.c
  3. 28 14
      faux/ini/ini.c

+ 1 - 0
faux/file.h

@@ -22,6 +22,7 @@ int faux_file_close(faux_file_t *file);
 int faux_file_fileno(faux_file_t *file);
 bool_t faux_file_eof(const faux_file_t *file);
 char *faux_file_getline(faux_file_t *file);
+ssize_t faux_file_write(faux_file_t *file, const void *buf, size_t n);
 
 C_DECL_END
 

+ 30 - 0
faux/file/file.c

@@ -239,3 +239,33 @@ char *faux_file_getline(faux_file_t *f) {
 	// The last line can be without eol. Consider it as a line too
 	return faux_file_takeaway_rest(f);
 }
+
+
+ssize_t faux_file_write(faux_file_t *f, const void *buf, size_t n) {
+
+	ssize_t bytes_written = 0;
+	size_t left = n;
+	const void *data = buf;
+
+	assert(f);
+	assert(buf);
+	if (!f || !buf)
+		return -1;
+	if (0 == n)
+		return 0;
+
+	do {
+		bytes_written = write(f->fd, data, left);
+		if (bytes_written < 0) {
+			if (EINTR == errno)
+				continue;
+			return -1;
+		}
+		if (0 == bytes_written) // Insufficient space
+			return -1;
+		data += bytes_written;
+		left = left - bytes_written;
+	} while (left > 0);
+
+	return n;
+}

+ 28 - 14
faux/ini/ini.c

@@ -421,10 +421,10 @@ int faux_ini_parse_file(faux_ini_t *ini, const char *fn) {
  */
 int faux_ini_write_file(const faux_ini_t *ini, const char *fn) {
 
-	FILE *fd = NULL;
+	faux_file_t *f = NULL;
 	faux_ini_node_t *iter = NULL;
 	const faux_pair_t *pair = NULL;
-	const char *spaces = " \t";
+	const char *spaces = " \t"; // String with spaces needs quotes
 
 	assert(ini);
 	assert(fn);
@@ -433,28 +433,42 @@ int faux_ini_write_file(const faux_ini_t *ini, const char *fn) {
 	if (!fn || '\0' == *fn)
 		return -1;
 
-	fd = fopen(fn, "w");
-	if (!fd)
+	f = faux_file_open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	if (!f)
 		return -1;
 
 	iter = faux_ini_iter(ini);
 	while ((pair = faux_ini_each(&iter))) {
-		char *quote = NULL;
+		char *quote_name = NULL;
+		char *quote_value = NULL;
 		const char *name = faux_pair_name(pair);
 		const char *value = faux_pair_value(pair);
+		char *line = NULL;
+		ssize_t bytes_written = 0;
 
-		// Print name field
-		// Word with spaces needs quotes
-		quote = faux_str_chars(name, spaces) ? "\"" : "";
-		fprintf(fd, "%s%s%s=", quote, name, quote);
-
-		// Print value field
 		// Word with spaces needs quotes
-		quote = faux_str_chars(value, spaces) ? "\"" : "";
-		fprintf(fd, "%s%s%s\n", quote, value, quote);
+		quote_name = faux_str_chars(name, spaces) ? "\"" : "";
+		quote_value = faux_str_chars(value, spaces) ? "\"" : "";
+
+		// Prepare INI line
+		faux_str_cat(&line, quote_name);
+		faux_str_cat(&line, name);
+		faux_str_cat(&line, quote_name);
+		faux_str_cat(&line, "=");
+		faux_str_cat(&line, quote_value);
+		faux_str_cat(&line, value);
+		faux_str_cat(&line, quote_value);
+		faux_str_cat(&line, "\n");
+
+		bytes_written = faux_file_write(f, line, strlen(line));
+		faux_str_free(line);
+		if (bytes_written < 0) { // Can't write to file
+			faux_file_close(f);
+			return -1;
+		}
 	}
 
-	fclose(fd);
+	faux_file_close(f);
 
 	return 0;
 }