Commit 09fe317aa5456c8be46403735c10a133dd02c017

Stefan Sperling 2018-03-11T01:33:02

add function to read worktree meta data file

diff --git a/include/got_error.h b/include/got_error.h
index 128e60e..cd99056 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -40,6 +40,7 @@
 #define GOT_ERR_COMPRESSION	22
 #define GOT_ERR_BAD_OBJ_ID_STR	23
 #define GOT_ERR_WORKTREE_EXISTS	26
+#define GOT_ERR_WORKTREE_META	27
 
 static const struct got_error {
 	int code;
@@ -70,6 +71,7 @@ static const struct got_error {
 	{ GOT_ERR_COMPRESSION,	"compression failed" },
 	{ GOT_ERR_BAD_OBJ_ID_STR,"bad object id string" },
 	{ GOT_ERR_WORKTREE_EXISTS,"worktree already exists" },
+	{ GOT_ERR_WORKTREE_META,"bad worktree meta data" },
 };
 
 const struct got_error * got_error(int code);
diff --git a/lib/worktree.c b/lib/worktree.c
index 986dd17..b05a2c2 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -76,6 +76,58 @@ done:
 	return err;
 }
 
+static const struct got_error *
+read_meta_file(char **content, const char *gotpath, const char *name)
+{
+	const struct got_error *err = NULL;
+	char *path;
+	int fd = -1;
+	ssize_t n;
+	struct stat sb;
+
+	*content = NULL;
+
+	if (asprintf(&path, "%s/%s", gotpath, name) == -1) {
+		err = got_error(GOT_ERR_NO_MEM);
+		path = NULL;
+		goto done;
+	}
+
+	fd = open(path, O_RDONLY | O_EXCL | O_EXLOCK | O_NOFOLLOW);
+	if (fd == -1) {
+		err = got_error_from_errno();
+		goto done;
+	}
+
+	stat(path, &sb);
+	*content = calloc(1, sb.st_size);
+	if (*content == NULL) {
+		err = got_error(GOT_ERR_NO_MEM);
+		goto done;
+	}
+
+	n = read(fd, *content, sb.st_size);
+	if (n != sb.st_size) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	if ((*content)[sb.st_size - 1] != '\n') {
+		err = got_error(GOT_ERR_WORKTREE_META);
+		goto done;
+	}
+	(*content)[sb.st_size - 1] = '\0';
+
+done:
+	if (fd != -1 && close(fd) == -1 && err == NULL)
+		err = got_error_from_errno();
+	free(path);
+	if (err) {
+		free(*content);
+		*content = NULL;
+	}
+	return err;
+}
+
 const struct got_error *
 got_worktree_init(const char *path, struct got_reference *head_ref,
     const char *prefix, struct got_repository *repo)