Commit Diff


commit - 00ba99a7be48f532c0673f3e2ada13d7c299b2a0
commit + 3c45a30aebce27db2fb0f5b453695260456bacc9
blob - bc14b937b2e2688bef36d04f7659e90265482817
blob + 3d3ea43dcf4295a664e1352ecbafb88f28096f6a
--- got/got.c
+++ got/got.c
@@ -19,6 +19,7 @@
 #include <sys/limits.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/param.h>
 
 #include <err.h>
 #include <errno.h>
@@ -197,10 +198,25 @@ apply_unveil(const char *repo_path, int repo_read_only
     const char *worktree_path, int create_worktree)
 {
 	const struct got_error *error;
+	static char err_msg[MAXPATHLEN + 36];
 
 	if (create_worktree) {
 		/* Pre-create work tree path to avoid unveiling its parents. */
 		error = got_path_mkdir(worktree_path);
+
+		if (errno == EEXIST) {
+			if (got_dir_is_empty(worktree_path)) {
+				errno = 0;
+				error = NULL;
+			} else {
+				snprintf(err_msg, sizeof(err_msg),
+				    "%s: directory exists but is not empty",
+				    worktree_path);
+				error = got_error_msg(GOT_ERR_BAD_PATH,
+				    err_msg);
+			}
+		}
+
 		if (error && (error->code != GOT_ERR_ERRNO || errno != EISDIR))
 			return error;
 	}
blob - e4dc262d9f534be828275a226b7a4592b85d5a03
blob + b80b464ead9ddd50e8e97e06b4d5fc92a1268f4a
--- include/got_path.h
+++ include/got_path.h
@@ -90,6 +90,9 @@ void got_pathlist_free(struct got_pathlist_head *);
 /* Attempt to create a directory at a given path. */
 const struct got_error *got_path_mkdir(const char *);
 
+/* Determine whether a directory has no files or directories in it. */
+int got_dir_is_empty(const char *);
+
 /* dirname(3) with error handling and dynamically allocated result. */
 const struct got_error *got_path_dirname(char **, const char *);
 
blob - 3cbf1e571016182b989eabf6e95c60e0879b0314
blob + abd5d7f4e126836f6242180512c1307ef26963cd
--- lib/path.c
+++ lib/path.c
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
+#include <dirent.h>
 
 #include "got_error.h"
 #include "got_path.h"
@@ -323,6 +324,29 @@ got_path_mkdir(const char *abspath)
 
 done:
 	return err;
+}
+
+int
+got_dir_is_empty(const char *dir)
+{
+	DIR *d;
+	struct dirent *dent;
+	int empty = 1;
+
+	d = opendir(dir);
+	if (d == NULL)
+		return 1;
+
+	while ((dent = readdir(d)) != NULL) {
+		if (strcmp(dent->d_name, ".") == 0 ||
+		    strcmp(dent->d_name, "..") == 0)
+			continue;
+
+		empty = 0;
+		break;
+	}
+
+	return empty;
 }
 
 const struct got_error *