util: Add write_remainder() helper
We have several places where we want to write(2) a buffer or buffers and we handle short write()s by retrying until everything is successfully written. Add a helper for this in util.c. This version has some differences from the typical write_all() function. First, take an IO vector rather than a single buffer, because that will be useful for some of our cases. Second, allow it to take an parameter to skip the first n bytes of the given buffers. This will be useful for some of the cases we want, and also falls out quite naturally from the implementation. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> [sbrivio: Minor formatting fixes in write_remainder()] Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
24410b37a4
commit
8bdb0883b4
2 changed files with 36 additions and 0 deletions
35
util.c
35
util.c
|
@ -19,6 +19,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "iov.h"
|
||||||
#include "passt.h"
|
#include "passt.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
@ -574,3 +576,36 @@ int do_clone(int (*fn)(void *), char *stack_area, size_t stack_size, int flags,
|
||||||
return clone(fn, stack_area + stack_size / 2, flags, arg);
|
return clone(fn, stack_area + stack_size / 2, flags, arg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* write_remainder() - write the tail of an IO vector to an fd
|
||||||
|
* @fd: File descriptor
|
||||||
|
* @iov: IO vector
|
||||||
|
* @iovcnt: Number of entries in @iov
|
||||||
|
* @skip: Number of bytes of the vector to skip writing
|
||||||
|
*
|
||||||
|
* Return: 0 on success, -1 on error (with errno set)
|
||||||
|
*
|
||||||
|
* #syscalls write writev
|
||||||
|
*/
|
||||||
|
int write_remainder(int fd, const struct iovec *iov, int iovcnt, size_t skip)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while ((i = iov_skip_bytes(iov, iovcnt, skip, &skip)) < iovcnt) {
|
||||||
|
ssize_t rc;
|
||||||
|
|
||||||
|
if (skip) {
|
||||||
|
rc = write(fd, (char *)iov[i].iov_base + skip,
|
||||||
|
iov[i].iov_len - skip);
|
||||||
|
} else {
|
||||||
|
rc = writev(fd, &iov[i], iovcnt - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
skip += rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
1
util.h
1
util.h
|
@ -229,6 +229,7 @@ void write_pidfile(int fd, pid_t pid);
|
||||||
int __daemon(int pidfile_fd, int devnull_fd);
|
int __daemon(int pidfile_fd, int devnull_fd);
|
||||||
int fls(unsigned long x);
|
int fls(unsigned long x);
|
||||||
int write_file(const char *path, const char *buf);
|
int write_file(const char *path, const char *buf);
|
||||||
|
int write_remainder(int fd, const struct iovec *iov, int iovcnt, size_t skip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mod_sub() - Modular arithmetic subtraction
|
* mod_sub() - Modular arithmetic subtraction
|
||||||
|
|
Loading…
Reference in a new issue