summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVicent Martí <tanoku@gmail.com>2011-11-07 12:04:13 -0800
committerVicent Martí <tanoku@gmail.com>2011-11-07 12:04:13 -0800
commitb0b2dd5ecc2d309875e8dcd744fa5ff0a55b8fe5 (patch)
treee209c574270b89357a1891ed8ebb275e59db3ec9 /src
parent38068dc1d3cf4a0f0dc2ce8c488a1de4621c04b5 (diff)
parent657a3951860f07cf26e2accfe2ada6d62ca5a9f5 (diff)
downloadlibgit2-b0b2dd5ecc2d309875e8dcd744fa5ff0a55b8fe5.tar.gz
Merge pull request #475 from carlosmn/perms
Fix Windows permissions problems
Diffstat (limited to 'src')
-rw-r--r--src/filebuf.c2
-rw-r--r--src/fileops.c25
-rw-r--r--src/posix.c14
-rw-r--r--src/posix.h1
-rw-r--r--src/refs.c12
-rw-r--r--src/win32/posix.h1
-rw-r--r--src/win32/posix_w32.c14
7 files changed, 39 insertions, 30 deletions
diff --git a/src/filebuf.c b/src/filebuf.c
index 1a3fe6d9b..199418032 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -278,7 +278,7 @@ int git_filebuf_commit(git_filebuf *file, mode_t mode)
goto cleanup;
}
- error = git_futils_mv_atomic(file->path_lock, file->path_original);
+ error = p_rename(file->path_lock, file->path_original);
cleanup:
git_filebuf_cleanup(file);
diff --git a/src/fileops.c b/src/fileops.c
index 2030c786d..955bb1bf6 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -8,29 +8,6 @@
#include "fileops.h"
#include <ctype.h>
-int git_futils_mv_atomic(const char *from, const char *to)
-{
-#ifdef GIT_WIN32
- /*
- * Win32 POSIX compilance my ass. If the destination
- * file exists, the `rename` call fails. This is as
- * close as it gets with the Win32 API.
- */
- return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? GIT_SUCCESS : GIT_EOSERR;
-#else
- /* Don't even try this on Win32 */
- if (!link(from, to)) {
- p_unlink(from);
- return GIT_SUCCESS;
- }
-
- if (!rename(from, to))
- return GIT_SUCCESS;
-
- return GIT_ERROR;
-#endif
-}
-
int git_futils_mkpath2file(const char *file_path, const mode_t mode)
{
int error = GIT_SUCCESS;
@@ -216,7 +193,7 @@ int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmod
if (git_futils_mkpath2file(to, dirmode) < GIT_SUCCESS)
return GIT_EOSERR; /* The callee already takes care of setting the correct error message. */
- return git_futils_mv_atomic(from, to); /* The callee already takes care of setting the correct error message. */
+ return p_rename(from, to); /* The callee already takes care of setting the correct error message. */
}
int git_futils_mmap_ro(git_map *out, git_file fd, git_off_t begin, size_t len)
diff --git a/src/posix.c b/src/posix.c
index 7cd0749b6..8c19588ee 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -39,6 +39,20 @@ int p_getcwd(char *buffer_out, size_t size)
return GIT_SUCCESS;
}
+int p_rename(const char *from, const char *to)
+{
+ if (!link(from, to)) {
+ p_unlink(from);
+ return GIT_SUCCESS;
+ }
+
+ if (!rename(from, to))
+ return GIT_SUCCESS;
+
+ return GIT_ERROR;
+
+}
+
#endif
int p_read(git_file fd, void *buf, size_t cnt)
diff --git a/src/posix.h b/src/posix.h
index 55cd35a38..c12b41364 100644
--- a/src/posix.h
+++ b/src/posix.h
@@ -45,6 +45,7 @@ extern int p_write(git_file fd, const void *buf, size_t cnt);
extern int p_open(const char *path, int flags);
extern int p_creat(const char *path, mode_t mode);
extern int p_getcwd(char *buffer_out, size_t size);
+extern int p_rename(const char *from, const char *to);
#ifndef GIT_WIN32
diff --git a/src/refs.c b/src/refs.c
index 563406660..05f935796 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -16,6 +16,8 @@
#define MAX_NESTING_LEVEL 5
+#define GIT_PACKED_REFS_FILE_MODE 0644
+
enum {
GIT_PACKREF_HAS_PEEL = 1,
GIT_PACKREF_WAS_LOOSE = 2
@@ -757,7 +759,7 @@ static int packed_write(git_repository *repo)
total_refs = repo->references.packfile->key_count;
if ((error =
git_vector_init(&packing_list, total_refs, packed_sort)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to write packed reference");
+ return git__rethrow(error, "Failed to init packed refernces list");
/* Load all the packfile into a vector */
{
@@ -776,14 +778,14 @@ static int packed_write(git_repository *repo)
/* Now we can open the file! */
git_path_join(pack_file_path, repo->path_repository, GIT_PACKEDREFS_FILE);
if ((error = git_filebuf_open(&pack_file, pack_file_path, 0)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to write packed reference");
+ return git__rethrow(error, "Failed to write open packed references file");
/* Packfiles have a header... apparently
* This is in fact not required, but we might as well print it
* just for kicks */
if ((error =
git_filebuf_printf(&pack_file, "%s\n", GIT_PACKEDREFS_HEADER)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to write packed reference");
+ return git__rethrow(error, "Failed to write packed references file header");
for (i = 0; i < packing_list.length; ++i) {
struct packref *ref = (struct packref *)git_vector_get(&packing_list, i);
@@ -802,7 +804,7 @@ cleanup:
/* if we've written all the references properly, we can commit
* the packfile to make the changes effective */
if (error == GIT_SUCCESS) {
- error = git_filebuf_commit(&pack_file, GIT_PACK_FILE_MODE);
+ error = git_filebuf_commit(&pack_file, GIT_PACKED_REFS_FILE_MODE);
/* when and only when the packfile has been properly written,
* we can go ahead and remove the loose refs */
@@ -821,7 +823,7 @@ cleanup:
return error == GIT_SUCCESS ?
GIT_SUCCESS :
- git__rethrow(error, "Failed to write packed reference");
+ git__rethrow(error, "Failed to write packed references file");
}
static int _reference_available_cb(const char *ref, void *data)
diff --git a/src/win32/posix.h b/src/win32/posix.h
index 7b5553061..ae6323679 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -48,5 +48,6 @@ extern int p_fsync(int fd);
extern int p_open(const char *path, int flags);
extern int p_creat(const char *path, mode_t mode);
extern int p_getcwd(char *buffer_out, size_t size);
+extern int p_rename(const char *from, const char *to);
#endif
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 4b1b0074d..6f722581e 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -388,3 +388,17 @@ int p_access(const char* path, mode_t mode)
return ret;
}
+
+extern int p_rename(const char *from, const char *to)
+{
+ wchar_t *wfrom = gitwin_to_utf16(from);
+ wchar_t *wto = gitwin_to_utf16(to);
+ int ret;
+
+ ret = MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? GIT_SUCCESS : GIT_EOSERR;
+
+ git__free(wfrom);
+ git__free(wto);
+
+ return ret;
+}