@@ -462,7 +462,7 @@ static int write_file(semanage_handle_t * sh,
ERR(sh, "Could not open %s for writing.", filename);
return -1;
}
- if (write(out, data, num_bytes) == -1) {
+ if (write_full(out, data, num_bytes) == -1) {
ERR(sh, "Error while writing to %s.", filename);
close(out);
return -1;
@@ -724,7 +724,7 @@ static int semanage_pipe_data(semanage_handle_t *sh, char *path, char *in_data,
goto cleanup;
}
- retval = write(input_fd[PIPE_WRITE], in_data, in_data_len);
+ retval = write_full(input_fd[PIPE_WRITE], in_data, in_data_len);
if (retval == -1) {
ERR(sh, "Failed to write data to input pipe: %s\n", strerror(errno));
goto cleanup;
@@ -739,7 +739,7 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode,
}
umask(mask);
while (retval == 0 && (amount_read = read(in, buf, sizeof(buf))) > 0) {
- if (write(out, buf, amount_read) != amount_read) {
+ if (write_full(out, buf, amount_read) == -1) {
if (errno)
errsv = errno;
else
@@ -1555,14 +1555,14 @@ int semanage_split_fc(semanage_handle_t * sh)
!strncmp(buf, "HOME_ROOT", 9) || strstr(buf, "ROLE") ||
strstr(buf, "USER")) {
/* This contains one of the template variables, write it to homedir.template */
- if (write(hd, buf, strlen(buf)) < 0) {
+ if (write_full(hd, buf, strlen(buf)) < 0) {
ERR(sh, "Write to %s failed.",
semanage_path(SEMANAGE_TMP,
SEMANAGE_HOMEDIR_TMPL));
goto cleanup;
}
} else {
- if (write(fc, buf, strlen(buf)) < 0) {
+ if (write_full(fc, buf, strlen(buf)) < 0) {
ERR(sh, "Write to %s failed.",
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
goto cleanup;
@@ -1764,7 +1764,7 @@ static int semanage_commit_sandbox(semanage_handle_t * sh)
commit_filename);
return -1;
}
- amount_written = write(fd, write_buf, sizeof(write_buf));
+ amount_written = write_full(fd, write_buf, sizeof(write_buf));
if (amount_written == -1) {
ERR(sh, "Error while writing commit number to %s.",
commit_filename);
@@ -25,6 +25,7 @@
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
+#include <unistd.h>
#include <assert.h>
#define TRUE 1
@@ -328,3 +329,24 @@ semanage_list_t *semanage_slurp_file_filter(FILE * file,
return head.next;
}
+
+int write_full(int fd, const void *buf, size_t len)
+{
+ ssize_t w;
+ const unsigned char *p = buf;
+
+ while (len > 0) {
+ w = write(fd, p, len);
+ if (w == -1) {
+ if (errno == EINTR)
+ continue;
+
+ return -1;
+ }
+
+ p += w;
+ len -= (size_t)w;
+ }
+
+ return 0;
+}
@@ -144,4 +144,17 @@ void semanage_keep_until_space(char *data);
semanage_list_t *semanage_slurp_file_filter(FILE * file,
int (*pred) (const char *))
WARN_UNUSED;
+
+/**
+ * Wrapper around write(2), which retries on short writes.
+ *
+ * @param fd file descriptor to write to
+ * @param buf buffer to be written
+ * @param len number of bytes to be written from buffer
+ *
+ * @return 0 on success, -1 else (with errno set)
+ */
+
+int write_full(int fd, const void *buf, size_t len) WARN_UNUSED;
+
#endif