Commit f240acce865ec14df0d517d5000316a933e7ffed

Russell Belfer 2013-09-05T11:20:12

Add more file mode permissions macros This adds some more macros for some standard operations on file modes, particularly related to permissions, and then updates a number of places around the code base to use the new macros.

diff --git a/src/checkout.c b/src/checkout.c
index ec9da7e..f3a9b34 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -693,17 +693,14 @@ static int buffer_to_file(
 			buffer, path, file_open_flags, file_mode)) < 0)
 		return error;
 
-	if (st != NULL && (error = p_stat(path, st)) < 0) {
-		giterr_set(GITERR_OS, "Error while statting '%s'", path);
-		return error;
-	}
+	if (st != NULL && (error = p_stat(path, st)) < 0)
+		giterr_set(GITERR_OS, "Error statting '%s'", path);
 
-	if ((file_mode & 0100) != 0 && (error = p_chmod(path, file_mode)) < 0) {
+	else if (GIT_PERMS_EXECUTABLE(file_mode) &&
+			(error = p_chmod(path, file_mode)) < 0)
 		giterr_set(GITERR_OS, "Failed to set permissions on '%s'", path);
-		return error;
-	}
 
-	return 0;
+	return error;
 }
 
 static int blob_content_to_file(
diff --git a/src/diff_print.c b/src/diff_print.c
index 4ddd724..96937d8 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -7,7 +7,7 @@
 #include "common.h"
 #include "diff.h"
 #include "diff_patch.h"
-#include "buffer.h"
+#include "fileops.h"
 
 typedef struct {
 	git_diff_list *diff;
@@ -46,7 +46,7 @@ static char diff_pick_suffix(int mode)
 {
 	if (S_ISDIR(mode))
 		return '/';
-	else if (mode & 0100) /* -V536 */
+	else if (GIT_PERMS_EXECUTABLE(mode)) /* -V536 */
 		/* in git, modes are very regular, so we must have 0100755 mode */
 		return '*';
 	else
diff --git a/src/fileops.c b/src/fileops.c
index 76119e0..92cda82 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -110,7 +110,7 @@ git_off_t git_futils_filesize(git_file fd)
 mode_t git_futils_canonical_mode(mode_t raw_mode)
 {
 	if (S_ISREG(raw_mode))
-		return S_IFREG | GIT_CANONICAL_PERMS(raw_mode);
+		return S_IFREG | GIT_PERMS_CANONICAL(raw_mode);
 	else if (S_ISLNK(raw_mode))
 		return S_IFLNK;
 	else if (S_ISGITLINK(raw_mode))
@@ -972,7 +972,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
 		mode_t usemode = from_st.st_mode;
 
 		if ((info->flags & GIT_CPDIR_SIMPLE_TO_MODE) != 0)
-			usemode = (usemode & 0111) ? 0777 : 0666;
+			usemode = GIT_PERMS_FOR_WRITE(usemode);
 
 		error = git_futils_cp(from->ptr, info->to.ptr, usemode);
 	}
diff --git a/src/fileops.h b/src/fileops.h
index 5adedfc..142eb99 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -223,8 +223,11 @@ extern int git_futils_open_ro(const char *path);
  */
 extern git_off_t git_futils_filesize(git_file fd);
 
+#define GIT_PERMS_EXECUTABLE(MODE)  (((MODE) & 0111) != 0)
+#define GIT_PERMS_CANONICAL(MODE)	(GIT_PERMS_EXECUTABLE(MODE) ? 0755 : 0644)
+#define GIT_PERMS_FOR_WRITE(MODE)   (GIT_PERMS_EXECUTABLE(MODE) ? 0777 : 0666)
+
 #define GIT_MODE_PERMS_MASK			0777
-#define GIT_CANONICAL_PERMS(MODE)	(((MODE) & 0100) ? 0755 : 0644)
 #define GIT_MODE_TYPE(MODE)			((MODE) & ~GIT_MODE_PERMS_MASK)
 #define GIT_MODE_ISBLOB(MODE)		(GIT_MODE_TYPE(MODE) == GIT_MODE_TYPE(GIT_FILEMODE_BLOB))
 
diff --git a/src/index.c b/src/index.c
index 17e4390..9b32222 100644
--- a/src/index.c
+++ b/src/index.c
@@ -284,7 +284,7 @@ static unsigned int index_create_mode(unsigned int mode)
 	if (S_ISDIR(mode) || (mode & S_IFMT) == (S_IFLNK | S_IFDIR))
 		return (S_IFLNK | S_IFDIR);
 
-	return S_IFREG | ((mode & 0100) ? 0755 : 0644);
+	return S_IFREG | GIT_PERMS_CANONICAL(mode);
 }
 
 static unsigned int index_merge_mode(
diff --git a/src/tree.c b/src/tree.c
index 65d01b4..91309e1 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -10,7 +10,7 @@
 #include "tree.h"
 #include "git2/repository.h"
 #include "git2/object.h"
-#include "path.h"
+#include "fileops.h"
 #include "tree-cache.h"
 #include "index.h"
 
@@ -29,19 +29,19 @@ static bool valid_filemode(const int filemode)
 GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode)
 {
 	/* Tree bits set, but it's not a commit */
-	if (filemode & GIT_FILEMODE_TREE && !(filemode & 0100000))
+	if (GIT_MODE_TYPE(filemode) == GIT_FILEMODE_TREE)
 		return GIT_FILEMODE_TREE;
 
-	/* If any of the x bits is set */
-	if (filemode & 0111)
+	/* If any of the x bits are set */
+	if (GIT_PERMS_EXECUTABLE(filemode))
 		return GIT_FILEMODE_BLOB_EXECUTABLE;
 
 	/* 16XXXX means commit */
-	if ((filemode & GIT_FILEMODE_COMMIT) == GIT_FILEMODE_COMMIT)
+	if (GIT_MODE_TYPE(filemode) == GIT_FILEMODE_COMMIT)
 		return GIT_FILEMODE_COMMIT;
 
 	/* 12XXXX means commit */
-	if ((filemode & GIT_FILEMODE_LINK) == GIT_FILEMODE_LINK)
+	if (GIT_MODE_TYPE(filemode) == GIT_FILEMODE_LINK)
 		return GIT_FILEMODE_LINK;
 
 	/* Otherwise, return a blob */