Improve error handling when writing
authorMichael Spang <mspang@uwaterloo.ca>
Sat, 24 Oct 2009 17:16:02 +0000 (13:16 -0400)
committerMichael Spang <mspang@uwaterloo.ca>
Sat, 24 Oct 2009 18:47:44 +0000 (14:47 -0400)
src/dmaster.c
src/homedir.c
src/op-adduser.c
src/op-mail.c
src/util.c
src/util.h

index 2e99c57..63f0e83 100644 (file)
@@ -85,7 +85,8 @@ static void setup_pidfile(void) {
     pidlen = snprintf(pidbuf, sizeof(pidbuf), "%d\n", getpid());
     if (pidlen >= sizeof(pidbuf))
         fatal("pid too long");
-    full_write(fd, pidbuf, pidlen);
+    if (full_write(fd, pidbuf, pidlen))
+        fatalpe("write: %s", pidfile);
 }
 
 static void setup_daemon(void) {
index 9d54486..23384ab 100644 (file)
@@ -91,8 +91,8 @@ int ceo_create_home(char *homedir, char *skel, uid_t uid, gid_t gid, char *acces
                     warnpe("read");
                     break;
                 }
-                if (write(destfd, buf, bytes) < 0) {
-                    warnpe("write");
+                if (full_write(destfd, buf, bytes)) {
+                    warnpe("write: %s", src);
                     break;
                 }
             }
@@ -131,25 +131,25 @@ int ceo_create_home(char *homedir, char *skel, uid_t uid, gid_t gid, char *acces
 
     closedir(skeldir);
 
-    if (email && strlen(email) >0) {
-       char dest[PATH_MAX];
-        snprintf(dest, sizeof(dest), "%s/%s", homedir, ".forward"); 
+    if (email && *email) {
+        char dest[PATH_MAX];
+        snprintf(dest, sizeof(dest), "%s/%s", homedir, ".forward");
         int destfd = open(dest, O_WRONLY|O_CREAT|O_EXCL, 0644);
-        if (write(destfd, email, sizeof(char)*strlen(email)) < 0) {
-            warnpe ("write");
-        }
+
+        if (full_write(destfd, email, strlen(email)))
+            warnpe("write: %s", dest);
 
         if (fchown(destfd, uid, gid))
             errorpe("chown: %s", dest);
 
-       close(destfd);
+        close(destfd);
     }
 
     if (chown(homedir, uid, gid)) {
         errorpe("failed to chown %s", homedir);
         return -1;
     }
-    
+
     umask(mask);
 
     return 0;
index 58c8717..c7bf2dd 100644 (file)
@@ -272,7 +272,9 @@ void cmd_adduser(void) {
 
     strbuf_grow(&out, ceo__add_user_response__get_packed_size(out_proto));
     strbuf_setlen(&out, ceo__add_user_response__pack(out_proto, (uint8_t *)out.buf));
-    full_write(STDOUT_FILENO, out.buf, out.len);
+
+    if (full_write(STDOUT_FILENO, out.buf, out.len))
+        fatalpe("write: stdout");
 
     ceo__add_user__free_unpacked(in_proto, &protobuf_c_default_allocator);
     response_delete(out_proto);
index 2d10cf7..0947e55 100644 (file)
@@ -150,7 +150,8 @@ static int32_t update_mail(Ceo__UpdateMail *in, Ceo__UpdateMailResponse *out, ch
             struct strbuf file_contents = STRBUF_INIT;
             strbuf_addf(&file_contents, "%s\n", in->forward);
 
-            full_write(fd, file_contents.buf, file_contents.len);
+            if (full_write(fd, file_contents.buf, file_contents.len))
+                response_message(out, errno, "write: %s: %s", path, strerror(errno));
 
             strbuf_release(&file_contents);
 
@@ -190,7 +191,9 @@ void cmd_update_mail(void) {
 
     strbuf_grow(&out, ceo__update_mail_response__get_packed_size(out_proto));
     strbuf_setlen(&out, ceo__update_mail_response__pack(out_proto, (uint8_t *)out.buf));
-    full_write(STDOUT_FILENO, out.buf, out.len);
+
+    if (full_write(STDOUT_FILENO, out.buf, out.len))
+        fatalpe("write: stdout");
 
     ceo__update_mail__free_unpacked(in_proto, &protobuf_c_default_allocator);
     response_delete(out_proto);
index e693b19..be862d9 100644 (file)
@@ -162,15 +162,17 @@ int spawnv(const char *path, char *const argv[]) {
     return status;
 }
 
-void full_write(int fd, const void *buf, size_t count) {
+int full_write(int fd, const void *buf, size_t count) {
     ssize_t total = 0;
 
     while (total < count) {
         ssize_t wcount = write(fd, (char *)buf + total, count - total);
         if (wcount < 0)
-            fatalpe("write");
+            return wcount;
         total += wcount;
     }
+
+    return 0;
 }
 
 int spawnvem(const char *path, char *const *argv, char *const *envp, const struct strbuf *output, struct strbuf *input, int cap_stderr) {
index c633902..489dff1 100644 (file)
@@ -29,7 +29,7 @@ int spawnv(const char *path, char *const *argv);
 int spawnv_msg(const char *path, char *const *argv, const struct strbuf *output);
 int spawnvem(const char *path, char *const *argv, char *const *envp, const struct strbuf *output, struct strbuf *input, int cap_stderr);
 int spawnvemu(const char *path, char *const *argv, char *const *envp, const struct strbuf *output, struct strbuf *input, int cap_stderr, char *user);
-void full_write(int fd, const void *buf, size_t count);
+int full_write(int fd, const void *buf, size_t count);
 ssize_t full_read(int fd, void *buf, size_t len);
 FILE *fopenat(DIR *d, const char *path, int flags);
 void make_env(char **envp, ...);