diff options
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 98 |
1 files changed, 74 insertions, 24 deletions
@@ -50,7 +50,7 @@ static struct config_set the_config_set; static int config_file_fgetc(struct config_source *conf) { - return fgetc(conf->u.file); + return getc_unlocked(conf->u.file); } static int config_file_ungetc(int c, struct config_source *conf) @@ -618,7 +618,7 @@ unsigned long git_config_ulong(const char *name, const char *value) return ret; } -static int git_config_maybe_bool_text(const char *name, const char *value) +int git_parse_maybe_bool(const char *value) { if (!value) return 1; @@ -637,7 +637,7 @@ static int git_config_maybe_bool_text(const char *name, const char *value) int git_config_maybe_bool(const char *name, const char *value) { - int v = git_config_maybe_bool_text(name, value); + int v = git_parse_maybe_bool(value); if (0 <= v) return v; if (git_parse_int(value, &v)) @@ -647,7 +647,7 @@ int git_config_maybe_bool(const char *name, const char *value) int git_config_bool_or_int(const char *name, const char *value, int *is_bool) { - int v = git_config_maybe_bool_text(name, value); + int v = git_parse_maybe_bool(value); if (0 <= v) { *is_bool = 1; return v; @@ -1088,7 +1088,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data) f = fopen(filename, "r"); if (f) { + flockfile(f); ret = do_config_from_file(fn, filename, filename, f, data); + funlockfile(f); fclose(f); } return ret; @@ -1592,6 +1594,30 @@ int git_config_get_pathname(const char *key, const char **dest) return ret; } +int git_config_get_untracked_cache(void) +{ + int val = -1; + const char *v; + + /* Hack for test programs like test-dump-untracked-cache */ + if (ignore_untracked_cache_config) + return -1; + + if (!git_config_get_maybe_bool("core.untrackedcache", &val)) + return val; + + if (!git_config_get_value("core.untrackedcache", &v)) { + if (!strcasecmp(v, "keep")) + return -1; + + error("unknown core.untrackedCache value '%s'; " + "using 'keep' default value", v); + return -1; + } + + return -1; /* default value */ +} + NORETURN void git_die_config_linenr(const char *key, const char *filename, int linenr) { @@ -1846,7 +1872,7 @@ int git_config_set(const char *key, const char *value) * baselen - pointer to int which will hold the length of the * section + subsection part, can be NULL */ -int git_config_parse_key(const char *key, char **store_key, int *baselen_) +static int git_config_parse_key_1(const char *key, char **store_key, int *baselen_, int quiet) { int i, dot, baselen; const char *last_dot = strrchr(key, '.'); @@ -1857,12 +1883,14 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_) */ if (last_dot == NULL || last_dot == key) { - error("key does not contain a section: %s", key); + if (!quiet) + error("key does not contain a section: %s", key); return -CONFIG_NO_SECTION_OR_NAME; } if (!last_dot[1]) { - error("key does not contain variable name: %s", key); + if (!quiet) + error("key does not contain variable name: %s", key); return -CONFIG_NO_SECTION_OR_NAME; } @@ -1873,7 +1901,8 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_) /* * Validate the key and while at it, lower case it for matching. */ - *store_key = xmalloc(strlen(key) + 1); + if (store_key) + *store_key = xmalloc(strlen(key) + 1); dot = 0; for (i = 0; key[i]; i++) { @@ -1884,26 +1913,42 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_) if (!dot || i > baselen) { if (!iskeychar(c) || (i == baselen + 1 && !isalpha(c))) { - error("invalid key: %s", key); + if (!quiet) + error("invalid key: %s", key); goto out_free_ret_1; } c = tolower(c); } else if (c == '\n') { - error("invalid key (newline): %s", key); + if (!quiet) + error("invalid key (newline): %s", key); goto out_free_ret_1; } - (*store_key)[i] = c; + if (store_key) + (*store_key)[i] = c; } - (*store_key)[i] = 0; + if (store_key) + (*store_key)[i] = 0; return 0; out_free_ret_1: - free(*store_key); - *store_key = NULL; + if (store_key) { + free(*store_key); + *store_key = NULL; + } return -CONFIG_INVALID_KEY; } +int git_config_parse_key(const char *key, char **store_key, int *baselen) +{ + return git_config_parse_key_1(key, store_key, baselen, 0); +} + +int git_config_key_is_valid(const char *key) +{ + return !git_config_parse_key_1(key, NULL, NULL, 1); +} + /* * If value==NULL, unset in (remove from) config, * if value_regex!=NULL, disregard key/value pairs where value does not match. @@ -1933,7 +1978,7 @@ int git_config_set_multivar_in_file(const char *config_filename, const char *key, const char *value, const char *value_regex, int multi_replace) { - int fd = -1, in_fd; + int fd = -1, in_fd = -1; int ret; struct lock_file *lock = NULL; char *filename_buf = NULL; @@ -2063,10 +2108,11 @@ int git_config_set_multivar_in_file(const char *config_filename, goto out_free; } close(in_fd); + in_fd = -1; - if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) { + if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) { error("chmod on %s failed: %s", - lock->filename.buf, strerror(errno)); + get_lock_file_path(lock), strerror(errno)); ret = CONFIG_NO_WRITE; goto out_free; } @@ -2122,7 +2168,8 @@ int git_config_set_multivar_in_file(const char *config_filename, } if (commit_lock_file(lock) < 0) { - error("could not commit config file %s", config_filename); + error("could not write config file %s: %s", config_filename, + strerror(errno)); ret = CONFIG_NO_WRITE; lock = NULL; goto out_free; @@ -2146,10 +2193,12 @@ out_free: free(filename_buf); if (contents) munmap(contents, contents_sz); + if (in_fd >= 0) + close(in_fd); return ret; write_err_out: - ret = write_error(lock->filename.buf); + ret = write_error(get_lock_file_path(lock)); goto out_free; } @@ -2250,9 +2299,9 @@ int git_config_rename_section_in_file(const char *config_filename, fstat(fileno(config_file), &st); - if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) { + if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) { ret = error("chmod on %s failed: %s", - lock->filename.buf, strerror(errno)); + get_lock_file_path(lock), strerror(errno)); goto out; } @@ -2273,7 +2322,7 @@ int git_config_rename_section_in_file(const char *config_filename, } store.baselen = strlen(new_name); if (!store_write_section(out_fd, new_name)) { - ret = write_error(lock->filename.buf); + ret = write_error(get_lock_file_path(lock)); goto out; } /* @@ -2299,14 +2348,15 @@ int git_config_rename_section_in_file(const char *config_filename, continue; length = strlen(output); if (write_in_full(out_fd, output, length) != length) { - ret = write_error(lock->filename.buf); + ret = write_error(get_lock_file_path(lock)); goto out; } } fclose(config_file); unlock_and_out: if (commit_lock_file(lock) < 0) - ret = error("could not commit config file %s", config_filename); + ret = error("could not write config file %s: %s", + config_filename, strerror(errno)); out: free(filename_buf); return ret; |