Commit 7dd8a9f71052cc12f8dd9c1eec2e99afbf08df76

Shawn O. Pearce 2008-12-30T23:26:38

Set GIT_EOSERR when the OS errno should be consulted This error code indicates the OS error code has a better value describing the last error, as it is likely a network or local file IO problem identified by a C library function call. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

diff --git a/src/errors.c b/src/errors.c
index deb106b..f348997 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -41,6 +41,9 @@ static struct {
 const char *git_strerror(int num)
 {
 	int i;
+
+	if (num == GIT_EOSERR)
+		return strerror(errno);
 	for (i = 0; i < ARRAY_SIZE(error_codes); i++)
 		if (num == error_codes[i].num)
 			return error_codes[i].str;
diff --git a/src/errors.h b/src/errors.h
index caebc63..ab415d5 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -11,6 +11,11 @@ GIT_INLINE(int) git_int_error(int code)
 	return code;
 }
 
+GIT_INLINE(int) git_os_error(void)
+{
+	return git_int_error(GIT_EOSERR);
+}
+
 GIT_INLINE(void) *git_ptr_error(int code)
 {
 	git_errno = code;
diff --git a/src/fileops.c b/src/fileops.c
index 6522d02..1dd35dc 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -1,6 +1,18 @@
 #include "common.h"
 #include "fileops.h"
 
+int gitfo_open(const char *path, int flags)
+{
+	int fd = open(path, flags);
+	return fd >= 0 ? fd : git_os_error();
+}
+
+int gitfo_creat(const char *path, int mode)
+{
+	int fd = creat(path, mode);
+	return fd >= 0 ? fd : git_os_error();
+}
+
 int gitfo_read(git_file fd, void *buf, size_t cnt)
 {
 	char *b = buf;
@@ -9,11 +21,11 @@ int gitfo_read(git_file fd, void *buf, size_t cnt)
 		if (r < 0) {
 			if (errno == EINTR || errno == EAGAIN)
 				continue;
-			return -1;
+			return git_os_error();
 		}
 		if (!r) {
 			errno = EPIPE;
-			return -1;
+			return git_os_error();
 		}
 		cnt -= r;
 		b += r;
@@ -29,11 +41,11 @@ int gitfo_write(git_file fd, void *buf, size_t cnt)
 		if (r < 0) {
 			if (errno == EINTR || errno == EAGAIN)
 				continue;
-			return -1;
+			return git_os_error();
 		}
 		if (!r) {
 			errno = EPIPE;
-			return -1;
+			return git_os_error();
 		}
 		cnt -= r;
 		b += r;
@@ -43,9 +55,9 @@ int gitfo_write(git_file fd, void *buf, size_t cnt)
 
 off_t gitfo_size(git_file fd)
 {
-	gitfo_statbuf sb;
+	struct stat sb;
 	if (fstat(fd, &sb))
-		return -1;
+		return git_os_error();
 	return sb.st_size;
 }
 
@@ -166,7 +178,7 @@ int gitfo_close_cached(gitfo_cache *ioc)
 	git_file fd;
 
 	if (gitfo_flush_cached(ioc) < 0)
-		return -1;
+		return GIT_ERROR;
 
 	fd = ioc->fd;
 	free(ioc->cache);
@@ -201,7 +213,7 @@ int git_foreach_dirent(const char *wd, int (*fn)(void *, const char *), void *ar
 
 	dir = opendir(wd);
 	if (!dir)
-		return GIT_ERROR;
+		return git_os_error();
 
 	while ((de = readdir(dir))) {
 		size_t de_len;
diff --git a/src/fileops.h b/src/fileops.h
index 9de0a70..336ab27 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -24,7 +24,6 @@
 #define GITFO_BUF_INIT {NULL, 0}
 
 typedef int git_file;
-typedef struct stat gitfo_statbuf;
 typedef struct gitfo_cache gitfo_cache;
 
 typedef struct {  /* file io buffer  */
@@ -33,18 +32,13 @@ typedef struct {  /* file io buffer  */
 } gitfo_buf;
 
 
-#define gitfo_open(path, flags) open(path, flags)
-#define gitfo_creat(path, mode) creat(path, mode)
+extern int gitfo_open(const char *path, int flags);
+extern int gitfo_creat(const char *path, int mode);
 #define gitfo_close(fd) close(fd)
 
 extern int gitfo_read(git_file fd, void *buf, size_t cnt);
 extern int gitfo_write(git_file fd, void *buf, size_t cnt);
-
 extern off_t gitfo_size(git_file fd);
-#define gitfo_lstat(path, buf) lstat(path, buf)
-#define gitfo_fstat(fd, buf) fstat(fd, buf)
-#define gitfo_stat(path, buf) stat(path, buf)
-#define gitfo_fsync(fd) fsync(fd)
 
 extern int gitfo_read_file(gitfo_buf *obj, const char *path);
 extern void gitfo_free_buf(gitfo_buf *obj);
diff --git a/src/git/common.h b/src/git/common.h
index 6397533..75e1e84 100644
--- a/src/git/common.h
+++ b/src/git/common.h
@@ -58,6 +58,9 @@
 /** Not enough space available. */
 #define GIT_ENOMEM (GIT_ERROR - 3)
 
+/** Consult the OS error information. */
+#define GIT_EOSERR (GIT_ERROR - 4)
+
 GIT_BEGIN_DECL
 
 /** A revision traversal pool. */