From 7333ed1788b4f2b162a35003044d77a716732a1f Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Mon, 28 Jul 2014 20:26:40 +0200 Subject: setup: convert setup_git_directory_gently_1 et al. to strbuf Convert setup_git_directory_gently_1() and its helper functions setup_explicit_git_dir(), setup_discovered_git_dir() and setup_bare_git_dir() to use a struct strbuf to hold the current working directory. Replacing the PATH_MAX-sized buffer used before removes a path length limition on some file systems. The functions are converted all in one go because they all read and write the variable cwd. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- setup.c | 87 +++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 44 insertions(+), 43 deletions(-) (limited to 'setup.c') diff --git a/setup.c b/setup.c index 0a22f8bd1d..937dad503c 100644 --- a/setup.c +++ b/setup.c @@ -387,7 +387,7 @@ const char *read_gitfile(const char *path) } static const char *setup_explicit_git_dir(const char *gitdirenv, - char *cwd, int len, + struct strbuf *cwd, int *nongit_ok) { const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); @@ -441,7 +441,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, die_errno("Could not chdir to '%s'", git_work_tree_cfg); if (!getcwd(core_worktree, PATH_MAX)) die_errno("Could not get directory '%s'", git_work_tree_cfg); - if (chdir(cwd)) + if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); set_git_work_tree(core_worktree); } @@ -459,21 +459,20 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, worktree = get_git_work_tree(); /* both get_git_work_tree() and cwd are already normalized */ - if (!strcmp(cwd, worktree)) { /* cwd == worktree */ + if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */ set_git_dir(gitdirenv); free(gitfile); return NULL; } - offset = dir_inside_of(cwd, worktree); + offset = dir_inside_of(cwd->buf, worktree); if (offset >= 0) { /* cwd inside worktree? */ set_git_dir(real_path(gitdirenv)); if (chdir(worktree)) die_errno("Could not chdir to '%s'", worktree); - cwd[len++] = '/'; - cwd[len] = '\0'; + strbuf_addch(cwd, '/'); free(gitfile); - return cwd + offset; + return cwd->buf + offset; } /* cwd outside worktree */ @@ -483,7 +482,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, } static const char *setup_discovered_git_dir(const char *gitdir, - char *cwd, int offset, int len, + struct strbuf *cwd, int offset, int *nongit_ok) { if (check_repository_format_gently(gitdir, nongit_ok)) @@ -491,17 +490,17 @@ static const char *setup_discovered_git_dir(const char *gitdir, /* --work-tree is set without --git-dir; use discovered one */ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { - if (offset != len && !is_absolute_path(gitdir)) + if (offset != cwd->len && !is_absolute_path(gitdir)) gitdir = xstrdup(real_path(gitdir)); - if (chdir(cwd)) + if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); - return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok); + return setup_explicit_git_dir(gitdir, cwd, nongit_ok); } /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */ if (is_bare_repository_cfg > 0) { - set_git_dir(offset == len ? gitdir : real_path(gitdir)); - if (chdir(cwd)) + set_git_dir(offset == cwd->len ? gitdir : real_path(gitdir)); + if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); return NULL; } @@ -512,18 +511,18 @@ static const char *setup_discovered_git_dir(const char *gitdir, set_git_dir(gitdir); inside_git_dir = 0; inside_work_tree = 1; - if (offset == len) + if (offset == cwd->len) return NULL; /* Make "offset" point to past the '/', and add a '/' at the end */ offset++; - cwd[len++] = '/'; - cwd[len] = 0; - return cwd + offset; + strbuf_addch(cwd, '/'); + return cwd->buf + offset; } /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */ -static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongit_ok) +static const char *setup_bare_git_dir(struct strbuf *cwd, int offset, + int *nongit_ok) { int root_len; @@ -536,20 +535,20 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { const char *gitdir; - gitdir = offset == len ? "." : xmemdupz(cwd, offset); - if (chdir(cwd)) + gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset); + if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); - return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok); + return setup_explicit_git_dir(gitdir, cwd, nongit_ok); } inside_git_dir = 1; inside_work_tree = 0; - if (offset != len) { - if (chdir(cwd)) + if (offset != cwd->len) { + if (chdir(cwd->buf)) die_errno("Cannot come back to cwd"); - root_len = offset_1st_component(cwd); - cwd[offset > root_len ? offset : root_len] = '\0'; - set_git_dir(cwd); + root_len = offset_1st_component(cwd->buf); + strbuf_setlen(cwd, offset > root_len ? offset : root_len); + set_git_dir(cwd->buf); } else set_git_dir("."); @@ -617,10 +616,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) { const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT); struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; - static char cwd[PATH_MAX + 1]; + static struct strbuf cwd = STRBUF_INIT; const char *gitdirenv, *ret; char *gitfile; - int len, offset, offset_parent, ceil_offset = -1; + int offset, offset_parent, ceil_offset = -1; dev_t current_device = 0; int one_filesystem = 1; @@ -632,9 +631,9 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) if (nongit_ok) *nongit_ok = 0; - if (!getcwd(cwd, sizeof(cwd) - 1)) + if (strbuf_getcwd(&cwd)) die_errno("Unable to read current working directory"); - offset = len = strlen(cwd); + offset = cwd.len; /* * If GIT_DIR is set explicitly, we're not going @@ -643,7 +642,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) */ gitdirenv = getenv(GIT_DIR_ENVIRONMENT); if (gitdirenv) - return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok); + return setup_explicit_git_dir(gitdirenv, &cwd, nongit_ok); if (env_ceiling_dirs) { int empty_entry_found = 0; @@ -651,11 +650,11 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1); filter_string_list(&ceiling_dirs, 0, canonicalize_ceiling_entry, &empty_entry_found); - ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs); + ceil_offset = longest_ancestor_length(cwd.buf, &ceiling_dirs); string_list_clear(&ceiling_dirs, 0); } - if (ceil_offset < 0 && has_dos_drive_prefix(cwd)) + if (ceil_offset < 0 && has_dos_drive_prefix(cwd.buf)) ceil_offset = 1; /* @@ -683,7 +682,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) if (gitdirenv) { ret = setup_discovered_git_dir(gitdirenv, - cwd, offset, len, + &cwd, offset, nongit_ok); free(gitfile); return ret; @@ -691,29 +690,31 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) free(gitfile); if (is_git_directory(".")) - return setup_bare_git_dir(cwd, offset, len, nongit_ok); + return setup_bare_git_dir(&cwd, offset, nongit_ok); offset_parent = offset; - while (--offset_parent > ceil_offset && cwd[offset_parent] != '/'); + while (--offset_parent > ceil_offset && cwd.buf[offset_parent] != '/'); if (offset_parent <= ceil_offset) - return setup_nongit(cwd, nongit_ok); + return setup_nongit(cwd.buf, nongit_ok); if (one_filesystem) { - dev_t parent_device = get_device_or_die("..", cwd, offset); + dev_t parent_device = get_device_or_die("..", cwd.buf, + offset); if (parent_device != current_device) { if (nongit_ok) { - if (chdir(cwd)) + if (chdir(cwd.buf)) die_errno("Cannot come back to cwd"); *nongit_ok = 1; return NULL; } - cwd[offset] = '\0'; + strbuf_setlen(&cwd, offset); die("Not a git repository (or any parent up to mount point %s)\n" - "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", cwd); + "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", + cwd.buf); } } if (chdir("..")) { - cwd[offset] = '\0'; - die_errno("Cannot change to '%s/..'", cwd); + strbuf_setlen(&cwd, offset); + die_errno("Cannot change to '%s/..'", cwd.buf); } offset = offset_parent; } -- cgit v1.3 From 56b9f6e738af6f5238f57a29e96103cf61e3f8cd Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Mon, 28 Jul 2014 20:30:39 +0200 Subject: use xgetcwd() to get the current directory or die Convert several calls of getcwd() and die() to use xgetcwd() instead. This way we get rid of fixed-size buffers (which can be too small depending on the used file system) and gain consistent error messages. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/init-db.c | 17 ++++++++--------- builtin/rev-parse.c | 6 +++--- dir.c | 12 ++++++++---- setup.c | 6 +++--- trace.c | 7 ++++--- 5 files changed, 26 insertions(+), 22 deletions(-) (limited to 'setup.c') diff --git a/builtin/init-db.c b/builtin/init-db.c index 56f85e239a..f6dd1727ec 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -426,8 +426,9 @@ int init_db(const char *template_dir, unsigned int flags) static int guess_repository_type(const char *git_dir) { - char cwd[PATH_MAX]; const char *slash; + char *cwd; + int cwd_is_git_dir; /* * "GIT_DIR=. git init" is always bare. @@ -435,9 +436,10 @@ static int guess_repository_type(const char *git_dir) */ if (!strcmp(".", git_dir)) return 1; - if (!getcwd(cwd, sizeof(cwd))) - die_errno(_("cannot tell cwd")); - if (!strcmp(git_dir, cwd)) + cwd = xgetcwd(); + cwd_is_git_dir = !strcmp(git_dir, cwd); + free(cwd); + if (cwd_is_git_dir) return 1; /* * "GIT_DIR=.git or GIT_DIR=something/.git is usually not. @@ -572,11 +574,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) git_work_tree_cfg = xstrdup(real_path(rel)); free(rel); } - if (!git_work_tree_cfg) { - git_work_tree_cfg = xcalloc(PATH_MAX, 1); - if (!getcwd(git_work_tree_cfg, PATH_MAX)) - die_errno (_("Cannot access current working directory")); - } + if (!git_work_tree_cfg) + git_work_tree_cfg = xgetcwd(); if (work_tree) set_git_work_tree(real_path(work_tree)); else diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 1a6122d3ae..a88123ad3e 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -734,7 +734,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } if (!strcmp(arg, "--git-dir")) { const char *gitdir = getenv(GIT_DIR_ENVIRONMENT); - static char cwd[PATH_MAX]; + char *cwd; int len; if (gitdir) { puts(gitdir); @@ -744,10 +744,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) puts(".git"); continue; } - if (!getcwd(cwd, PATH_MAX)) - die_errno("unable to get current working directory"); + cwd = xgetcwd(); len = strlen(cwd); printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : ""); + free(cwd); continue; } if (!strcmp(arg, "--resolve-git-dir")) { diff --git a/dir.c b/dir.c index 797805d6a1..2c50ccfb49 100644 --- a/dir.c +++ b/dir.c @@ -1500,12 +1500,16 @@ int dir_inside_of(const char *subdir, const char *dir) int is_inside_dir(const char *dir) { - char cwd[PATH_MAX]; + char *cwd; + int rc; + if (!dir) return 0; - if (!getcwd(cwd, sizeof(cwd))) - die_errno("can't find the current directory"); - return dir_inside_of(cwd, dir) >= 0; + + cwd = xgetcwd(); + rc = (dir_inside_of(cwd, dir) >= 0); + free(cwd); + return rc; } int is_empty_dir(const char *path) diff --git a/setup.c b/setup.c index 937dad503c..72a4978ba5 100644 --- a/setup.c +++ b/setup.c @@ -434,16 +434,16 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, if (is_absolute_path(git_work_tree_cfg)) set_git_work_tree(git_work_tree_cfg); else { - char core_worktree[PATH_MAX]; + char *core_worktree; if (chdir(gitdirenv)) die_errno("Could not chdir to '%s'", gitdirenv); if (chdir(git_work_tree_cfg)) die_errno("Could not chdir to '%s'", git_work_tree_cfg); - if (!getcwd(core_worktree, PATH_MAX)) - die_errno("Could not get directory '%s'", git_work_tree_cfg); + core_worktree = xgetcwd(); if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); set_git_work_tree(core_worktree); + free(core_worktree); } } else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) { diff --git a/trace.c b/trace.c index 08180a90bc..3523667f6f 100644 --- a/trace.c +++ b/trace.c @@ -158,13 +158,12 @@ void trace_repo_setup(const char *prefix) { static const char *key = "GIT_TRACE_SETUP"; const char *git_work_tree; - char cwd[PATH_MAX]; + char *cwd; if (!trace_want(key)) return; - if (!getcwd(cwd, PATH_MAX)) - die("Unable to get current working directory"); + cwd = xgetcwd(); if (!(git_work_tree = get_git_work_tree())) git_work_tree = "(null)"; @@ -176,6 +175,8 @@ void trace_repo_setup(const char *prefix) trace_printf_key(key, "setup: worktree: %s\n", quote_crnl(git_work_tree)); trace_printf_key(key, "setup: cwd: %s\n", quote_crnl(cwd)); trace_printf_key(key, "setup: prefix: %s\n", quote_crnl(prefix)); + + free(cwd); } int trace_want(const char *key) -- cgit v1.3