Commit 0aa603363e39e51e8313a2952710f565141080cb

Edward Thomson 2015-05-19T14:07:03

Merge pull request #3132 from libgit2/cmn/path-direach-cberror Provide error messages for git_path_direach operations

diff --git a/src/fileops.c b/src/fileops.c
index 0587c44..b7b5515 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -703,6 +703,9 @@ static int cp_by_fd(int ifd, int ofd, bool close_fd_when_done)
 		error = (int)len;
 	}
 
+	if (error < 0)
+		giterr_set(GITERR_OS, "write error while copying file");
+
 	if (close_fd_when_done) {
 		p_close(ifd);
 		p_close(ofd);
@@ -861,7 +864,8 @@ static int _cp_r_callback(void *ref, git_buf *from)
 
 	/* make symlink or regular file */
 	if (info->flags & GIT_CPDIR_LINK_FILES) {
-		error = p_link(from->ptr, info->to.ptr);
+		if ((error = p_link(from->ptr, info->to.ptr)) < 0)
+			giterr_set(GITERR_OS, "failed to link '%s'", from->ptr);
 	} else if (S_ISLNK(from_st.st_mode)) {
 		error = cp_link(from->ptr, info->to.ptr, (size_t)from_st.st_size);
 	} else {
diff --git a/src/path.c b/src/path.c
index df6762c..81b4d51 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1060,11 +1060,13 @@ int git_path_direach(
 		if ((error = git_buf_put(path, de_path, de_len)) < 0)
 			break;
 
+		giterr_clear();
 		error = fn(arg, path);
 
 		git_buf_truncate(path, wd_len); /* restore path */
 
-		if (error != 0) {
+		/* Only set our own error if the callback did not set one already */
+		if (error != 0 && !giterr_last()) {
 			giterr_set_after_callback(error);
 			break;
 		}