Browse Source

faux: faux_read_block(), faux_write_block()

Serj Kalichev 4 years ago
parent
commit
7e25a7475b
3 changed files with 94 additions and 23 deletions
  1. 69 21
      faux/base/io.c
  2. 2 0
      faux/faux.h
  3. 23 2
      faux/file/private.h

+ 69 - 21
faux/base/io.c

@@ -10,9 +10,8 @@
 
 /** @brief Writes data to file.
  *
- * The system write() can be interrupted by signal or can write less bytes
- * than specified. This function will continue to write data until all data
- * will be written or error occured.
+ * The system write() can be interrupted by signal. This function will retry to
+ * write in a case of interrupted call.
  *
  * @param [in] fd File descriptor.
  * @param [in] buf Buffer to write.
@@ -22,8 +21,6 @@
 ssize_t faux_write(int fd, const void *buf, size_t n) {
 
 	ssize_t bytes_written = 0;
-	size_t left = n;
-	const void *data = buf;
 
 	assert(fd != -1);
 	assert(buf);
@@ -33,27 +30,55 @@ ssize_t faux_write(int fd, const void *buf, size_t n) {
 		return 0;
 
 	do {
-		bytes_written = write(fd, data, left);
-		if (bytes_written < 0) {
-			if (EINTR == errno)
-				continue;
+		bytes_written = write(fd, buf, n);
+	} while ((bytes_written < 0) && (EINTR == errno));
+
+	return bytes_written;
+}
+
+
+/** @brief Writes data block to file.
+ *
+ * The system write() can be interrupted by signal or can write less bytes
+ * than specified. This function will continue to write data until all data
+ * will be written or error occured.
+ *
+ * @param [in] fd File descriptor.
+ * @param [in] buf Buffer to write.
+ * @param [in] n Number of bytes to write.
+ * @return Number of bytes written.
+ * < n then insufficient space or error (but some data was already written).
+ * < 0 - error.
+ */
+ssize_t faux_write_block(int fd, const void *buf, size_t n) {
+
+	ssize_t bytes_written = 0;
+	size_t total_written = 0;
+	size_t left = n;
+	const void *data = buf;
+
+	do {
+		bytes_written = faux_write(fd, data, left);
+		if (bytes_written < 0) { // Error
+			if (total_written != 0)
+				return total_written;
 			return -1;
 		}
 		if (0 == bytes_written) // Insufficient space
-			return -1;
+			return total_written;
 		data += bytes_written;
 		left = left - bytes_written;
+		total_written += bytes_written;
 	} while (left > 0);
 
-	return n;
+	return total_written;
 }
 
 
 /** @brief Reads data from file.
  *
- * The system read() can be interrupted by signal or can read less bytes
- * than specified. This function will continue to read data until all data
- * will be readed or error occured.
+ * The system read() can be interrupted by signal. This function will retry to
+ * read if it was interrupted by signal.
  *
  * @param [in] fd File descriptor.
  * @param [in] buf Buffer to write.
@@ -63,9 +88,6 @@ ssize_t faux_write(int fd, const void *buf, size_t n) {
 ssize_t faux_read(int fd, void *buf, size_t n) {
 
 	ssize_t bytes_readed = 0;
-	ssize_t total_readed = 0;
-	size_t left = n;
-	void *data = buf;
 
 	assert(fd != -1);
 	assert(buf);
@@ -74,20 +96,46 @@ ssize_t faux_read(int fd, void *buf, size_t n) {
 	if (0 == n)
 		return 0;
 
+	do {
+		bytes_readed = read(fd, buf, n);
+	} while ((bytes_readed < 0) && (EINTR == errno));
+
+	return bytes_readed;
+}
+
+
+/** @brief Reads data block from file.
+ *
+ * The system read() can be interrupted by signal or can read less bytes
+ * than specified. This function will continue to read data until all data
+ * will be readed or error occured.
+ *
+ * @param [in] fd File descriptor.
+ * @param [in] buf Buffer to write.
+ * @param [in] n Number of bytes to write.
+ * @return Number of bytes readed.
+ * < n EOF or error (but some data was already readed).
+ * < 0 Error.
+ */
+size_t faux_read_block(int fd, void *buf, size_t n) {
+
+	ssize_t bytes_readed = 0;
+	size_t total_readed = 0;
+	size_t left = n;
+	void *data = buf;
+
 	do {
 		bytes_readed = read(fd, data, left);
 		if (bytes_readed < 0) {
-			if (EINTR == errno)
-				continue;
-			if (total_readed > 0)
+			if (total_readed != 0)
 				return total_readed;
 			return -1;
 		}
 		if (0 == bytes_readed) // EOF
 			return total_readed;
 		data += bytes_readed;
-		total_readed += bytes_readed;
 		left = left - bytes_readed;
+		total_readed += bytes_readed;
 	} while (left > 0);
 
 	return total_readed;

+ 2 - 0
faux/faux.h

@@ -67,6 +67,8 @@ void *faux_zmalloc(size_t size);
 // IO
 ssize_t faux_write(int fd, const void *buf, size_t n);
 ssize_t faux_read(int fd, void *buf, size_t n);
+ssize_t faux_write_block(int fd, const void *buf, size_t n);
+size_t faux_read_block(int fd, void *buf, size_t n);
 
 C_DECL_END
 

+ 23 - 2
faux/file/private.h

@@ -1,8 +1,8 @@
 #include "faux/faux.h"
 #include "faux/file.h"
 
-/** @brief Chunk size to allocate buffer */
-#define FAUX_FILE_CHUNK_SIZE 128
+
+// Chunk class
 
 struct faux_chunk_s {
 	void *buf; // Allocated buffer
@@ -13,6 +13,27 @@ struct faux_chunk_s {
 
 typedef struct faux_chunk_s faux_chunk_t;
 
+C_DECL_BEGIN
+
+faux_chunk_t *faux_chunk_new(size_t size);
+void faux_chunk_free(faux_chunk_t *chunk);
+size_t faux_chunk_len(faux_chunk_t *chunk);
+ssize_t faux_chunk_inc_len(faux_chunk_t *chunk, size_t inc_len);
+ssize_t faux_chunk_dec_len(faux_chunk_t *chunk, size_t dec_len);
+ssize_t faux_chunk_size(faux_chunk_t *chunk);
+void *faux_chunk_buf(faux_chunk_t *chunk);
+void *faux_chunk_write_pos(faux_chunk_t *chunk);
+void *faux_chunk_read_pos(faux_chunk_t *chunk);
+ssize_t faux_chunk_left(faux_chunk_t *chunk);
+
+C_DECL_END
+
+
+// File class
+
+/** @brief Chunk size to allocate buffer */
+#define FAUX_FILE_CHUNK_SIZE 128
+
 struct faux_file_s {
 	int fd; // File descriptor
 	char *buf; // Data buffer