commit 99724ed4012d446155eafdc18fc1337449bd8bcc from: Stefan Sperling date: Sat Mar 10 16:08:23 2018 UTC add a helper function which creates worktree meta files commit - 1451e70d409660e581616fe32e56a7ad79b8b5a2 commit + 99724ed4012d446155eafdc18fc1337449bd8bcc blob - b1ad87e60e9a8962edb1a6865d0ee3b134135872 blob + 62920bb290d79adcb26c0a80eff7f7db0a4d8a1c --- lib/worktree.c +++ lib/worktree.c @@ -31,6 +31,51 @@ #include "got_worktree_priv.h" #include "got_path_priv.h" +static const struct got_error * +create_meta_file(const char *gotpath, const char *name, const char *content) +{ + const struct got_error *err = NULL; + char *path; + int fd = -1; + char buf[4]; + ssize_t n; + + if (asprintf(&path, "%s/%s", gotpath, name) == -1) { + err = got_error(GOT_ERR_NO_MEM); + path = NULL; + goto done; + } + + fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW, + GOT_DEFAULT_FILE_MODE); + if (fd == -1) { + err = got_error_from_errno(); + goto done; + } + + /* The file should be empty. */ + n = read(fd, buf, sizeof(buf)); + if (n != 0) { + err = (n == -1 ? got_error_from_errno() : + got_error(GOT_ERR_WORKTREE_EXISTS)); + goto done; + } + + if (content) { + int len = dprintf(fd, "%s\n", content); + if (len != strlen(content) + 1) { + err = got_error_from_errno(); + goto done; + } + } + +done: + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno(); + free(path); + return err; +} + const struct got_error * got_worktree_init(const char *path, struct got_reference *head_ref, struct got_repository *repo) @@ -39,16 +84,9 @@ got_worktree_init(const char *path, struct got_referen char *abspath = NULL; char *normpath = NULL; char *gotpath = NULL; - char *indexpath = NULL; - char *headpath = NULL; - char *repopath = NULL; - char *formatpath = NULL; char *refstr = NULL; char *path_repos = NULL; char *formatstr = NULL; - char buf[4]; - ssize_t n; - int fd; if (got_path_is_absolute(path)) { abspath = strdup(path); @@ -82,28 +120,9 @@ got_worktree_init(const char *path, struct got_referen } /* Create an empty file index. */ - if (asprintf(&indexpath, "%s/%s", gotpath, GOT_WORKTREE_FILE_INDEX) - == -1) { - err = got_error(GOT_ERR_NO_MEM); + err = create_meta_file(gotpath, GOT_WORKTREE_FILE_INDEX, NULL); + if (err) goto done; - } - fd = open(indexpath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW, - GOT_DEFAULT_FILE_MODE); - if (fd == -1) { - err = got_error_from_errno(); - goto done; - } - n = read(fd, buf, sizeof(buf)); - if (n != 0) { - err = (n == -1 ? got_error_from_errno() : - got_error(GOT_ERR_WORKTREE_EXISTS)); - close(fd); - goto done; - } - if (close(fd) == -1) { - err = got_error_from_errno(); - goto done; - } /* Write the HEAD reference. */ refstr = got_ref_to_str(head_ref); @@ -111,123 +130,33 @@ got_worktree_init(const char *path, struct got_referen err = got_error(GOT_ERR_NO_MEM); goto done; } - if (asprintf(&headpath, "%s/%s", gotpath, GOT_REF_HEAD) == -1) { - err = got_error(GOT_ERR_NO_MEM); + err = create_meta_file(gotpath, GOT_REF_HEAD, refstr); + if (err) goto done; - } - fd = open(headpath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW, - GOT_DEFAULT_FILE_MODE); - if (fd == -1) { - err = got_error_from_errno(); - goto done; - } - n = read(fd, buf, sizeof(buf)); - if (n != 0) { - err = (n == -1 ? got_error_from_errno() : - got_error(GOT_ERR_WORKTREE_EXISTS)); - close(fd); - goto done; - } - n = write(fd, refstr, strlen(refstr)); - if (n != strlen(refstr)) { - err = got_error_from_errno(); - close(fd); - goto done; - } - n = write(fd, "\n", 1); - if (n != 1) { - err = got_error_from_errno(); - close(fd); - goto done; - } - if (close(fd) == -1) { - err = got_error_from_errno(); - goto done; - } /* Store path to repository. */ - if (asprintf(&repopath, "%s/%s", gotpath, GOT_WORKTREE_REPOSITORY) - == -1) { - err = got_error(GOT_ERR_NO_MEM); - goto done; - } - fd = open(repopath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW, - GOT_DEFAULT_FILE_MODE); - if (fd == -1) { - err = got_error_from_errno(); - goto done; - } - n = read(fd, buf, sizeof(buf)); - if (n != 0) { - err = (n == -1 ? got_error_from_errno() : - got_error(GOT_ERR_WORKTREE_EXISTS)); - close(fd); - goto done; - } path_repos = got_repo_get_path(repo); if (path_repos == NULL) { err = got_error(GOT_ERR_NO_MEM); goto done; } - n = write(fd, path_repos, strlen(path_repos)); - if (n != strlen(path_repos)) { - err = got_error_from_errno(); - close(fd); + err = create_meta_file(gotpath, GOT_WORKTREE_REPOSITORY, path_repos); + if (err) goto done; - } - n = write(fd, "\n", 1); - if (n != 1) { - err = got_error_from_errno(); - close(fd); - goto done; - } - if (close(fd) == -1) { - err = got_error_from_errno(); - goto done; - } /* Stamp repository with format file. */ - if (asprintf(&formatpath, "%s/%s", gotpath, GOT_WORKTREE_FORMAT) - == -1) { - err = got_error(GOT_ERR_NO_MEM); - goto done; - } if (asprintf(&formatstr, "%d", GOT_WORKTREE_FORMAT_VERSION) == -1) { err = got_error(GOT_ERR_NO_MEM); goto done; } - fd = open(formatpath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW, - GOT_DEFAULT_FILE_MODE); - if (fd == -1) { - err = got_error_from_errno(); + err = create_meta_file(gotpath, GOT_WORKTREE_FORMAT, formatstr); + if (err) goto done; - } - n = read(fd, buf, sizeof(buf)); - if (n != 0) { - err = (n == -1 ? got_error_from_errno() : - got_error(GOT_ERR_WORKTREE_EXISTS)); - close(fd); - goto done; - } - n = dprintf(fd, "%s\n", formatstr); - if (n != strlen(formatstr) + 1) { - err = got_error_from_errno(); - close(fd); - goto done; - } - if (close(fd) == -1) { - err = got_error_from_errno(); - goto done; - } done: free(abspath); free(normpath); free(gotpath); - free(indexpath); - free(headpath); - free(repopath); - free(formatpath); free(formatstr); free(refstr); free(path_repos);