Add writev_all() function

Use it in rhizome_write_manifest_file() instead of two separate write(2)
system calls or buffered stdio.
This commit is contained in:
Andrew Bettison 2013-10-12 03:54:18 +10:30
parent 97cbebc91e
commit 0437e4adbb
5 changed files with 53 additions and 8 deletions

16
net.c
View File

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
@ -28,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "conf.h"
#include "net.h"
#include "str.h"
#include "strbuf_helpers.h"
struct in_addr hton_in_addr(in_addr_t addr)
{
@ -85,6 +87,20 @@ ssize_t _write_all(int fd, const void *buf, size_t len, struct __sourceloc __whe
return written;
}
ssize_t _writev_all(int fd, const struct iovec *iov, int iovcnt, struct __sourceloc __whence)
{
size_t len = 0;
int i;
for (i = 0; i < iovcnt; ++i)
len += iov[i].iov_len;
ssize_t written = writev(fd, iov, iovcnt);
if (written == -1)
return WHYF_perror("writev_all: writev(%d,%s len=%zu)", fd, alloca_iovec(iov, iovcnt), len);
if (written != len)
return WHYF_perror("writev_all: writev(%d,%s len=%zu) returned %zd", fd, alloca_iovec(iov, iovcnt), len, (size_t)written);
return written;
}
ssize_t _write_nonblock(int fd, const void *buf, size_t len, struct __sourceloc __whence)
{
ssize_t written = write(fd, buf, len);

2
net.h
View File

@ -35,6 +35,7 @@ struct in_addr hton_in_addr(in_addr_t);
#define set_block(fd) (_set_block(fd, __WHENCE__))
#define read_nonblock(fd,buf,len) (_read_nonblock(fd, buf, len, __WHENCE__))
#define write_all(fd,buf,len) (_write_all(fd, buf, len, __WHENCE__))
#define writev_all(fd,iov,cnt) (_writev_all(fd, (iov), (cnt), __WHENCE__))
#define write_nonblock(fd,buf,len) (_write_nonblock(fd, buf, len, __WHENCE__))
#define write_all_nonblock(fd,buf,len) (_write_all_nonblock(fd, buf, len, __WHENCE__))
#define write_str(fd,str) (_write_str(fd, str, __WHENCE__))
@ -46,6 +47,7 @@ ssize_t _read_nonblock(int fd, void *buf, size_t len, struct __sourceloc __whenc
ssize_t _write_all(int fd, const void *buf, size_t len, struct __sourceloc __whence);
ssize_t _write_nonblock(int fd, const void *buf, size_t len, struct __sourceloc __whence);
ssize_t _write_all_nonblock(int fd, const void *buf, size_t len, struct __sourceloc __whence);
ssize_t _writev_all(int fd, const struct iovec *iov, int iovcnt, struct __sourceloc __whence);
ssize_t _write_str(int fd, const char *str, struct __sourceloc __whence);
ssize_t _write_str_nonblock(int fd, const char *str, struct __sourceloc __whence);
ssize_t recvwithttl(int sock, unsigned char *buffer, size_t bufferlen, int *ttl, struct sockaddr *recvaddr, socklen_t *recvaddrlen);

View File

@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <stdlib.h>
#include <assert.h>
#include <sys/uio.h>
#include "serval.h"
#include "conf.h"
#include "rhizome.h"
@ -656,16 +657,21 @@ int rhizome_write_manifest_file(rhizome_manifest *m, const char *path, char appe
if (fd == -1)
return WHYF_perror("open(%s,O_WRONLY|O_CREAT%s,0666)", alloca_str_toprint(path), append ? "|O_APPEND" : "");
int ret = 0;
if (write_all(fd, m->manifestdata, m->manifest_all_bytes) == -1)
ret = -1;
else if (append) {
unsigned char marker[4];
unsigned char marker[4];
struct iovec iov[2];
int iovcnt = 1;
iov[0].iov_base = m->manifestdata;
iov[0].iov_len = m->manifest_all_bytes;
if (append) {
write_uint16(marker, m->manifest_all_bytes);
marker[2]=0x41;
marker[3]=0x10;
if (write_all(fd, marker, sizeof marker) == -1)
ret = -1;
marker[2] = 0x41;
marker[3] = 0x10;
iov[1].iov_base = marker;
iov[1].iov_len = sizeof marker;
iovcnt = 2;
}
if (writev_all(fd, iov, iovcnt) == -1)
ret = -1;
if (close(fd) == -1)
ret = WHY_perror("close");
return ret;

View File

@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <sys/uio.h>
static inline strbuf _toprint(strbuf sb, char c)
{
@ -377,3 +378,16 @@ strbuf strbuf_append_strftime(strbuf sb, const char *format, const struct tm *tm
strbuf_ncat(sb, buf, n);
return sb;
}
strbuf strbuf_append_iovec(strbuf sb, const struct iovec *iov, int iovcnt)
{
int i;
strbuf_putc(sb, '[');
for (i = 0; i < iovcnt; ++i) {
if (i)
strbuf_puts(sb, ", ");
strbuf_sprintf(sb, "%p#%zu", iov[i].iov_base, iov[i].iov_len);
}
strbuf_putc(sb, ']');
return sb;
}

View File

@ -129,4 +129,11 @@ strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t
struct tm;
strbuf strbuf_append_strftime(strbuf sb, const char *format, const struct tm *tm);
/* Append a representation of a struct iovec[] array.
* @author Andrew Bettison <andrew@servalproject.com>
*/
struct iovec;
strbuf strbuf_append_iovec(strbuf sb, const struct iovec *iov, int iovcnt);
#define alloca_iovec(iov,cnt) strbuf_str(strbuf_append_iovec(strbuf_alloca(200), (iov), (cnt)))
#endif //__STRBUF_HELPERS_H__