mirror of
https://github.com/git/git.git
synced 2026-03-04 06:27:36 +01:00
wrapper: introduce writev(3p) wrappers
In the preceding commit we have added a compatibility wrapper for the writev(3p) syscall. Introduce some generic wrappers for this function that we nowadays take for granted in the Git codebase. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
50869da7e6
commit
0b2112ccfc
41
wrapper.c
41
wrapper.c
@@ -323,6 +323,47 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
|
||||
return total;
|
||||
}
|
||||
|
||||
ssize_t writev_in_full(int fd, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
ssize_t total_written = 0;
|
||||
|
||||
while (iovcnt) {
|
||||
ssize_t bytes_written = writev(fd, iov, iovcnt);
|
||||
if (bytes_written < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
if (!bytes_written) {
|
||||
errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
total_written += bytes_written;
|
||||
|
||||
/*
|
||||
* We first need to discard any iovec entities that have been
|
||||
* fully written.
|
||||
*/
|
||||
while (iovcnt && (size_t)bytes_written >= iov->iov_len) {
|
||||
bytes_written -= iov->iov_len;
|
||||
iov++;
|
||||
iovcnt--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, we need to adjust the last iovec in case we have
|
||||
* performed a partial write.
|
||||
*/
|
||||
if (iovcnt && bytes_written) {
|
||||
iov->iov_base = (char *) iov->iov_base + bytes_written;
|
||||
iov->iov_len -= bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
return total_written;
|
||||
}
|
||||
|
||||
ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
|
||||
{
|
||||
char *p = buf;
|
||||
|
||||
@@ -47,6 +47,15 @@ ssize_t read_in_full(int fd, void *buf, size_t count);
|
||||
ssize_t write_in_full(int fd, const void *buf, size_t count);
|
||||
ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset);
|
||||
|
||||
/*
|
||||
* Try to write all iovecs. Returns -1 in case an error occurred with a proper
|
||||
* errno set, the number of bytes written otherwise.
|
||||
*
|
||||
* Note that the iovec will be modified as a result of this call to adjust for
|
||||
* partial writes!
|
||||
*/
|
||||
ssize_t writev_in_full(int fd, struct iovec *iov, int iovcnt);
|
||||
|
||||
static inline ssize_t write_str_in_full(int fd, const char *str)
|
||||
{
|
||||
return write_in_full(fd, str, strlen(str));
|
||||
|
||||
@@ -96,6 +96,14 @@ void write_or_die(int fd, const void *buf, size_t count)
|
||||
}
|
||||
}
|
||||
|
||||
void writev_or_die(int fd, struct iovec *iov, int iovlen)
|
||||
{
|
||||
if (writev_in_full(fd, iov, iovlen) < 0) {
|
||||
check_pipe(errno);
|
||||
die_errno("writev error");
|
||||
}
|
||||
}
|
||||
|
||||
void fwrite_or_die(FILE *f, const void *buf, size_t count)
|
||||
{
|
||||
if (fwrite(buf, 1, count, f) != count)
|
||||
|
||||
@@ -7,6 +7,7 @@ void fprintf_or_die(FILE *, const char *fmt, ...);
|
||||
void fwrite_or_die(FILE *f, const void *buf, size_t count);
|
||||
void fflush_or_die(FILE *f);
|
||||
void write_or_die(int fd, const void *buf, size_t count);
|
||||
void writev_or_die(int fd, struct iovec *iov, int iovlen);
|
||||
|
||||
/*
|
||||
* These values are used to help identify parts of a repository to fsync.
|
||||
|
||||
Reference in New Issue
Block a user