write_or_die.con commit Avoid errors and warnings when attempting to do I/O on zero bytes (3b97fee)
   1#include "cache.h"
   2
   3int read_in_full(int fd, void *buf, size_t count)
   4{
   5        char *p = buf;
   6        ssize_t total = 0;
   7        ssize_t loaded = 0;
   8
   9        while (count > 0) {
  10                loaded = xread(fd, p, count);
  11                if (loaded <= 0) {
  12                        if (total)
  13                                return total;
  14                        else
  15                                return loaded;
  16                }
  17                count -= loaded;
  18                p += loaded;
  19                total += loaded;
  20        }
  21
  22        return total;
  23}
  24
  25void read_or_die(int fd, void *buf, size_t count)
  26{
  27        ssize_t loaded;
  28
  29        if (!count)
  30                return;
  31        loaded = read_in_full(fd, buf, count);
  32        if (loaded == 0)
  33                die("unexpected end of file");
  34        else if (loaded < 0)
  35                die("read error (%s)", strerror(errno));
  36}
  37
  38int write_in_full(int fd, const void *buf, size_t count)
  39{
  40        const char *p = buf;
  41        ssize_t total = 0;
  42
  43        while (count > 0) {
  44                size_t written = xwrite(fd, p, count);
  45                if (written < 0)
  46                        return -1;
  47                if (!written) {
  48                        errno = ENOSPC;
  49                        return -1;
  50                }
  51                count -= written;
  52                p += written;
  53                total += written;
  54        }
  55
  56        return total;
  57}
  58
  59void write_or_die(int fd, const void *buf, size_t count)
  60{
  61        ssize_t written;
  62
  63        if (!count)
  64                return;
  65        written = write_in_full(fd, buf, count);
  66        if (written == 0)
  67                die("disk full?");
  68        else if (written < 0) {
  69                if (errno == EPIPE)
  70                        exit(0);
  71                die("write error (%s)", strerror(errno));
  72        }
  73}
  74
  75int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)
  76{
  77        ssize_t written;
  78
  79        if (!count)
  80                return 1;
  81        written = write_in_full(fd, buf, count);
  82        if (written == 0) {
  83                fprintf(stderr, "%s: disk full?\n", msg);
  84                return 0;
  85        }
  86        else if (written < 0) {
  87                if (errno == EPIPE)
  88                        exit(0);
  89                fprintf(stderr, "%s: write error (%s)\n",
  90                        msg, strerror(errno));
  91                return 0;
  92        }
  93
  94        return 1;
  95}
  96
  97int write_or_whine(int fd, const void *buf, size_t count, const char *msg)
  98{
  99        ssize_t written;
 100
 101        if (!count)
 102                return 1;
 103        written = write_in_full(fd, buf, count);
 104        if (written == 0) {
 105                fprintf(stderr, "%s: disk full?\n", msg);
 106                return 0;
 107        }
 108        else if (written < 0) {
 109                fprintf(stderr, "%s: write error (%s)\n",
 110                        msg, strerror(errno));
 111                return 0;
 112        }
 113
 114        return 1;
 115}