aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libmdsserver/util.c72
-rw-r--r--src/libmdsserver/util.h18
-rw-r--r--src/mds-server/mds-server.c57
3 files changed, 99 insertions, 48 deletions
diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c
index 9eb88fe..a3a1867 100644
--- a/src/libmdsserver/util.c
+++ b/src/libmdsserver/util.c
@@ -172,3 +172,75 @@ int strict_atoi(const char* str, int* value, int min, int max)
return 0;
}
+
+/**
+ * Send a buffer into a file and ignore interruptions
+ *
+ * @param fd The file descriptor
+ * @param buffer The buffer
+ * @param length The length of the buffer
+ * @return Zero on success, -1 on error
+ */
+int full_write(int fd, const char* buffer, size_t length)
+{
+ ssize_t wrote;
+ while (length > 0)
+ {
+ errno = 0;
+ wrote = write(fd, buffer, length);
+ if (errno && (errno != EINTR))
+ return -1;
+ length -= (size_t)max(wrote, 0);
+ buffer += (size_t)max(wrote, 0);
+ }
+ return 0;
+}
+
+
+/**
+ * Read a file completly and ignore interruptions
+ *
+ * @param fd The file descriptor
+ * @return The content of the file, you will need to free it. `NULL` on error.
+ */
+char* full_read(int fd)
+{
+ size_t state_buf_size = 8 << 10;
+ size_t state_buf_ptr = 0;
+ char* state_buf;
+ ssize_t got;
+
+ /* Allocate buffer for data. */
+ if (xmalloc(state_buf, state_buf_size, char))
+ return NULL;
+
+ /* Read the file. */
+ for (;;)
+ {
+ /* Grow buffer if it is too small. */
+ if (state_buf_size == state_buf_ptr)
+ {
+ char* old_buf = state_buf;
+ state_buf = realloc(state_buf, (state_buf_size <<= 1) * sizeof(char));
+ if (state_buf == NULL)
+ {
+ free(old_buf);
+ return NULL;
+ }
+ }
+
+ /* Read from the file into the buffer. */
+ got = read(fd, state_buf + state_buf_ptr, state_buf_size - state_buf_ptr);
+ if ((got < 0) && (errno != EINTR))
+ {
+ free(state_buf);
+ return NULL;
+ }
+ if (got == 0)
+ break;
+ state_buf_ptr += (size_t)got;
+ }
+
+ return state_buf;
+}
+
diff --git a/src/libmdsserver/util.h b/src/libmdsserver/util.h
index 3de6f02..da2cb9f 100644
--- a/src/libmdsserver/util.h
+++ b/src/libmdsserver/util.h
@@ -74,6 +74,24 @@ size_t send_message(int socket, const char* message, size_t length);
*/
int strict_atoi(const char* str, int* value, int min, int max);
+/**
+ * Send a buffer into a file and ignore interruptions
+ *
+ * @param fd The file descriptor
+ * @param buffer The buffer
+ * @param length The length of the buffer
+ * @return Zero on success, -1 on error
+ */
+int full_write(int fd, const char* buffer, size_t length);
+
+/**
+ * Read a file completly and ignore interruptions
+ *
+ * @param fd The file descriptor
+ * @return The content of the file, you will need to free it. `NULL` on error.
+ */
+char* full_read(int fd);
+
#endif
diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c
index bb4f52e..28fd37f 100644
--- a/src/mds-server/mds-server.c
+++ b/src/mds-server/mds-server.c
@@ -1192,7 +1192,6 @@ int marshal_server(int fd)
size_t state_n = 0;
char* state_buf = NULL;
char* state_buf_;
- ssize_t wrote;
ssize_t node;
@@ -1246,20 +1245,14 @@ int marshal_server(int fd)
fd_table_marshal(&client_map, state_buf_);
/* Send the marshalled data into the file. */
- while (state_n > 0)
- {
- errno = 0;
- wrote = write(fd, state_buf, state_n);
- if (errno && (errno != EINTR))
- goto fail;
- state_n -= (size_t)max(wrote, 0);
- state_buf += (size_t)max(wrote, 0);
- }
+ if (full_write(fd, state_buf, state_n) < 0)
+ goto fail;
free(state_buf);
return 0;
fail:
+ perror(*argv);
free(state_buf);
return -1;
}
@@ -1290,9 +1283,6 @@ static size_t unmarshal_remapper(size_t old)
int unmarshal_server(int fd)
{
int with_error = 0;
- size_t state_buf_size = 8 << 10;
- size_t state_buf_ptr = 0;
- ssize_t got;
char* state_buf;
char* state_buf_;
size_t list_size;
@@ -1302,43 +1292,13 @@ int unmarshal_server(int fd)
pthread_t _slave_thread;
- /* Allocate buffer for data. */
- if (xmalloc(state_buf = state_buf_, state_buf_size, char))
+ /* Read the file. */
+ if ((state_buf = state_buf_ = full_read(fd)) == NULL)
{
perror(*argv);
return -1;
}
- /* Read the file. */
- for (;;)
- {
- /* Grow buffer if it is too small. */
- if (state_buf_size == state_buf_ptr)
- {
- char* old_buf = state_buf;
- state_buf = realloc(state_buf, (state_buf_size <<= 1) * sizeof(char));
- if (state_buf == NULL)
- {
- perror(*argv);
- free(old_buf);
- return -1;
- }
- }
-
- /* Read from the file into the buffer. */
- got = read(fd, state_buf + state_buf_ptr, state_buf_size - state_buf_ptr);
- if (got < 0)
- {
- perror(*argv);
- free(state_buf);
- return -1;
- }
- if (got == 0)
- break;
- state_buf_ptr += (size_t)got;
- }
-
-
/* Create memory address remapping table. */
if (hash_table_create(&unmarshal_remap_map))
{
@@ -1409,7 +1369,7 @@ int unmarshal_server(int fd)
if (linked_list_unmarshal(&client_list, state_buf_))
{
perror(*argv);
- /* TODO */
+ abort(); /* Critical. */
}
state_buf_ += list_size / sizeof(char);
@@ -1417,7 +1377,7 @@ int unmarshal_server(int fd)
if (fd_table_unmarshal(&client_map, state_buf_, unmarshal_remapper))
{
perror(*argv);
- /* TODO */
+ abort(); /* Critical. */
}
/* Release the raw data. */
@@ -1427,7 +1387,8 @@ int unmarshal_server(int fd)
if (with_error)
for (i = 0; i < client_map.capacity; i++)
if (client_map.used[i / 64] & ((uint64_t)1 << (i % 64)))
- if (client_map.values[i] == 0) /* Lets not presume that fd-table actually initialise its allocations. */
+ /* Lets not presume that fd-table actually initialise its allocations. */
+ if (client_map.values[i] == 0)
client_map.used[i / 64] &= ~((uint64_t)1 << (i % 64));
/* Remap the linked list and remove non-found elements, and start the clients. */