summaryrefslogtreecommitdiff
path: root/src/os/unix.c
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2008-11-03 17:14:25 -0800
committerShawn O. Pearce <spearce@spearce.org>2008-11-03 18:43:04 -0800
commit3e9e69098af2014a0c3fe9e46cddcb5365dd538b (patch)
treee0637ddfbea67c8d7f557c709e095af8906e9176 /src/os/unix.c
parentb7c891c629d298f2d82310d8ced2ee2e48084213 (diff)
downloadlibgit2-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.c53
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;
}