diff options
| author | Shawn O. Pearce <spearce@spearce.org> | 2008-11-03 17:14:25 -0800 |
|---|---|---|
| committer | Shawn O. Pearce <spearce@spearce.org> | 2008-11-03 18:43:04 -0800 |
| commit | 3e9e69098af2014a0c3fe9e46cddcb5365dd538b (patch) | |
| tree | e0637ddfbea67c8d7f557c709e095af8906e9176 /src/os/unix.c | |
| parent | b7c891c629d298f2d82310d8ced2ee2e48084213 (diff) | |
| download | libgit2-3e9e69098af2014a0c3fe9e46cddcb5365dd538b.tar.gz | |
Redefine git_fread, git_fwrite to transfer the whole unit
We never want to accept a short read or a short write when
transferring data to or from a local file.
Either the entire read (or write) completes or the operation
failed and we will not recover gracefully from it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'src/os/unix.c')
| -rw-r--r-- | src/os/unix.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/src/os/unix.c b/src/os/unix.c index d132e9755..767f20ca8 100644 --- a/src/os/unix.c +++ b/src/os/unix.c @@ -26,22 +26,51 @@ #include <errno.h> #include "git/common.h" -ssize_t git_fread(git_file fd, void *buf, size_t cnt) +int git_fopen(git_file *out, const char *path, int flags) { - for (;;) { - ssize_t r = read(fd, buf, cnt); - if (r < 0 && (errno == EINTR || errno == EAGAIN)) - continue; - return r; + int r = open(path, flags); + if (r < 0) + return -1; + *out = r; + return GIT_SUCCESS; +} + +int git_fread(git_file fd, void *buf, size_t cnt) +{ + char *b = buf; + while (cnt) { + ssize_t r = read(fd, b, cnt); + if (r < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!r) { + errno = EPIPE; + return -1; + } + cnt -= r; + b += r; } + return GIT_SUCCESS; } -ssize_t git_fwrite(git_file fd, void *buf, size_t cnt) +int git_fwrite(git_file fd, void *buf, size_t cnt) { - for (;;) { - ssize_t r = write(fd, buf, cnt); - if (r < 0 && (errno == EINTR || errno == EAGAIN)) - continue; - return r; + char *b = buf; + while (cnt) { + ssize_t r = write(fd, b, cnt); + if (r < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!r) { + errno = EPIPE; + return -1; + } + cnt -= r; + b += r; } + return GIT_SUCCESS; } |
