00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #endif
00034
00035 #include <assert.h>
00036 #include <errno.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039
00040 #include "rdd.h"
00041 #include "writer.h"
00042
00043
00044
00045 static int fd_write(RDD_WRITER *w, const unsigned char *buf, unsigned nbyte);
00046 static int fd_close(RDD_WRITER *w);
00047 static int fd_compare_address(RDD_WRITER *w, struct addrinfo *address, int *result);
00048
00049 static RDD_WRITE_OPS fd_write_ops = {
00050 fd_write,
00051 fd_close,
00052 fd_compare_address
00053 };
00054
00055 typedef struct _RDD_FD_WRITER {
00056 int fd;
00057 } RDD_FD_WRITER;
00058
00059 int
00060 rdd_open_fd_writer(RDD_WRITER **self, int fd)
00061 {
00062 RDD_WRITER *w = 0;
00063 RDD_FD_WRITER *state = 0;
00064 int rc = RDD_OK;
00065
00066 if (self == 0) {
00067 return RDD_BADARG;
00068 }
00069 if (fd < 0) {
00070 return RDD_BADARG;
00071 }
00072
00073 rc = rdd_new_writer(&w, &fd_write_ops, sizeof(RDD_FD_WRITER));
00074 if (rc != RDD_OK) {
00075 return rc;
00076 }
00077 state = (RDD_FD_WRITER *) w->state;
00078 state->fd = fd;
00079
00080 *self = w;
00081 return RDD_OK;
00082 }
00083
00084
00085
00086 static int
00087 fd_write(RDD_WRITER *w, const unsigned char *buf, unsigned nbyte)
00088 {
00089 RDD_FD_WRITER *state = w->state;
00090 int n;
00091
00092 while (nbyte > 0) {
00093 if ((n = write(state->fd, buf, nbyte)) < 0) {
00094 #if defined(RDD_SIGNALS)
00095 if (errno == EINTR) continue;
00096 #endif
00097 if (errno == ENOSPC) {
00098 return RDD_ESPACE;
00099 } else {
00100 return RDD_EWRITE;
00101 }
00102 }
00103 buf += n;
00104 nbyte -= n;
00105 }
00106
00107 return RDD_OK;
00108 }
00109
00110 static int
00111 fd_close(RDD_WRITER *self)
00112 {
00113 RDD_FD_WRITER *state = self->state;
00114 int rc;
00115 if (fsync(state->fd) < 0) {
00116 rc = RDD_ECLOSE;
00117 }
00118
00119 if ((rc = close(state->fd)) < 0) {
00120 return RDD_ECLOSE;
00121 }
00122 return RDD_OK;
00123 }
00124
00125 static int
00126 fd_compare_address(RDD_WRITER *self, struct addrinfo *address, int *result)
00127 {
00128 if (self == 0) {
00129 return RDD_BADARG;
00130 }
00131 if (result == 0) {
00132 return RDD_BADARG;
00133 }
00134
00135 *result = (address == 0);
00136 return RDD_OK;
00137 }