]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'sd/branch-copy'
authorJunio C Hamano <gitster@pobox.com>
Mon, 27 Nov 2017 02:06:35 +0000 (11:06 +0900)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Nov 2017 02:06:35 +0000 (11:06 +0900)
Code clean-up.

* sd/branch-copy:
  config: avoid "write_in_full(fd, buf, len) != len" pattern

1  2 
config.c

diff --combined config.c
index 03ab56d3d8d55bb328572005e98539bd1e423f7e,4457aec089766710a69c45138c87e3c7c2ebd43d..731b9b1de2fa222be838c73b410b9619e234feec
+++ b/config.c
@@@ -6,8 -6,6 +6,8 @@@
   *
   */
  #include "cache.h"
 +#include "config.h"
 +#include "repository.h"
  #include "lockfile.h"
  #include "exec_cmd.h"
  #include "strbuf.h"
@@@ -73,6 -71,13 +73,6 @@@ static int core_compression_seen
  static int pack_compression_seen;
  static int zlib_compression_seen;
  
 -/*
 - * Default config_set that contains key-value pairs from the usual set of config
 - * config files (i.e repo specific .git/config, user wide ~/.gitconfig, XDG
 - * config file and the global /etc/gitconfig)
 - */
 -static struct config_set the_config_set;
 -
  static int config_file_fgetc(struct config_source *conf)
  {
        return getc_unlocked(conf->u.file);
@@@ -213,6 -218,8 +213,6 @@@ static int include_by_gitdir(const stru
  
        if (opts->git_dir)
                git_dir = opts->git_dir;
 -      else if (have_git_dir())
 -              git_dir = get_git_dir();
        else
                goto done;
  
@@@ -238,7 -245,7 +238,7 @@@ again
        }
  
        ret = !wildmatch(pattern.buf + prefix, text.buf + prefix,
 -                       icase ? WM_CASEFOLD : 0, NULL);
 +                       icase ? WM_CASEFOLD : 0);
  
        if (!ret && !already_tried_absolute) {
                /*
@@@ -388,7 -395,8 +388,7 @@@ static int git_config_parse_key_1(cons
  
  out_free_ret_1:
        if (store_key) {
 -              free(*store_key);
 -              *store_key = NULL;
 +              FREE_AND_NULL(*store_key);
        }
        return -CONFIG_INVALID_KEY;
  }
@@@ -596,8 -604,7 +596,8 @@@ static int get_value(config_fn_t fn, vo
         */
        cf->linenr--;
        ret = fn(name->buf, value, data);
 -      cf->linenr++;
 +      if (ret >= 0)
 +              cf->linenr++;
        return ret;
  }
  
@@@ -928,7 -935,7 +928,7 @@@ ssize_t git_config_ssize_t(const char *
        return ret;
  }
  
 -int git_parse_maybe_bool(const char *value)
 +static int git_parse_maybe_bool_text(const char *value)
  {
        if (!value)
                return 1;
        return -1;
  }
  
 -int git_config_maybe_bool(const char *name, const char *value)
 +int git_parse_maybe_bool(const char *value)
  {
 -      int v = git_parse_maybe_bool(value);
 +      int v = git_parse_maybe_bool_text(value);
        if (0 <= v)
                return v;
        if (git_parse_int(value, &v))
  
  int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
  {
 -      int v = git_parse_maybe_bool(value);
 +      int v = git_parse_maybe_bool_text(value);
        if (0 <= v) {
                *is_bool = 1;
                return v;
@@@ -1431,7 -1438,7 +1431,7 @@@ int git_config_from_file(config_fn_t fn
        int ret = -1;
        FILE *f;
  
 -      f = fopen(filename, "r");
 +      f = fopen_or_warn(filename, "r");
        if (f) {
                flockfile(f);
                ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename, filename, f, data);
@@@ -1460,9 -1467,9 +1460,9 @@@ int git_config_from_mem(config_fn_t fn
        return do_config_from(&top, fn, data);
  }
  
 -int git_config_from_blob_sha1(config_fn_t fn,
 +int git_config_from_blob_oid(config_fn_t fn,
                              const char *name,
 -                            const unsigned char *sha1,
 +                            const struct object_id *oid,
                              void *data)
  {
        enum object_type type;
        unsigned long size;
        int ret;
  
 -      buf = read_sha1_file(sha1, &type, &size);
 +      buf = read_sha1_file(oid->hash, &type, &size);
        if (!buf)
                return error("unable to load config blob object '%s'", name);
        if (type != OBJ_BLOB) {
@@@ -1488,11 -1495,11 +1488,11 @@@ static int git_config_from_blob_ref(con
                                    const char *name,
                                    void *data)
  {
 -      unsigned char sha1[20];
 +      struct object_id oid;
  
 -      if (get_sha1(name, sha1) < 0)
 +      if (get_oid(name, &oid) < 0)
                return error("unable to resolve config blob '%s'", name);
 -      return git_config_from_blob_sha1(fn, name, sha1, data);
 +      return git_config_from_blob_oid(fn, name, &oid, data);
  }
  
  const char *git_etc_gitconfig(void)
@@@ -1538,8 -1545,10 +1538,8 @@@ static int do_git_config_sequence(cons
        char *user_config = expand_user_path("~/.gitconfig", 0);
        char *repo_config;
  
 -      if (opts->git_dir)
 -              repo_config = mkpathdup("%s/config", opts->git_dir);
 -      else if (have_git_dir())
 -              repo_config = git_pathdup("config");
 +      if (opts->commondir)
 +              repo_config = mkpathdup("%s/config", opts->commondir);
        else
                repo_config = NULL;
  
        return ret;
  }
  
 -int git_config_with_options(config_fn_t fn, void *data,
 -                          struct git_config_source *config_source,
 -                          const struct config_options *opts)
 +int config_with_options(config_fn_t fn, void *data,
 +                      struct git_config_source *config_source,
 +                      const struct config_options *opts)
  {
        struct config_include_data inc = CONFIG_INCLUDE_INIT;
  
        return do_git_config_sequence(opts, fn, data);
  }
  
 -static void git_config_raw(config_fn_t fn, void *data)
 -{
 -      struct config_options opts = {0};
 -
 -      opts.respect_includes = 1;
 -      if (git_config_with_options(fn, data, NULL, &opts) < 0)
 -              /*
 -               * git_config_with_options() normally returns only
 -               * zero, as most errors are fatal, and
 -               * non-fatal potential errors are guarded by "if"
 -               * statements that are entered only when no error is
 -               * possible.
 -               *
 -               * If we ever encounter a non-fatal error, it means
 -               * something went really wrong and we should stop
 -               * immediately.
 -               */
 -              die(_("unknown error occurred while reading the configuration files"));
 -}
 -
  static void configset_iter(struct config_set *cs, config_fn_t fn, void *data)
  {
        int i, value_index;
  void read_early_config(config_fn_t cb, void *data)
  {
        struct config_options opts = {0};
 -      struct strbuf buf = STRBUF_INIT;
 +      struct strbuf commondir = STRBUF_INIT;
 +      struct strbuf gitdir = STRBUF_INIT;
  
        opts.respect_includes = 1;
  
 -      if (have_git_dir())
 +      if (have_git_dir()) {
 +              opts.commondir = get_git_common_dir();
                opts.git_dir = get_git_dir();
        /*
         * When setup_git_directory() was not yet asked to discover the
         * notably, the current working directory is still the same after the
         * call).
         */
 -      else if (discover_git_directory(&buf))
 -              opts.git_dir = buf.buf;
 -
 -      git_config_with_options(cb, data, NULL, &opts);
 -
 -      strbuf_release(&buf);
 -}
 +      } else if (!discover_git_directory(&commondir, &gitdir)) {
 +              opts.commondir = commondir.buf;
 +              opts.git_dir = gitdir.buf;
 +      }
  
 -static void git_config_check_init(void);
 +      config_with_options(cb, data, NULL, &opts);
  
 -void git_config(config_fn_t fn, void *data)
 -{
 -      git_config_check_init();
 -      configset_iter(&the_config_set, fn, data);
 +      strbuf_release(&commondir);
 +      strbuf_release(&gitdir);
  }
  
  static struct config_set_element *configset_find_element(struct config_set *cs, const char *key)
@@@ -1714,20 -1746,15 +1714,20 @@@ static int configset_add_value(struct c
        return 0;
  }
  
 -static int config_set_element_cmp(const struct config_set_element *e1,
 -                               const struct config_set_element *e2, const void *unused)
 +static int config_set_element_cmp(const void *unused_cmp_data,
 +                                const void *entry,
 +                                const void *entry_or_key,
 +                                const void *unused_keydata)
  {
 +      const struct config_set_element *e1 = entry;
 +      const struct config_set_element *e2 = entry_or_key;
 +
        return strcmp(e1->key, e2->key);
  }
  
  void git_configset_init(struct config_set *cs)
  {
 -      hashmap_init(&cs->config_hash, (hashmap_cmp_fn)config_set_element_cmp, 0);
 +      hashmap_init(&cs->config_hash, config_set_element_cmp, NULL, 0);
        cs->hash_initialized = 1;
        cs->list.nr = 0;
        cs->list.alloc = 0;
@@@ -1848,7 -1875,7 +1848,7 @@@ int git_configset_get_maybe_bool(struc
  {
        const char *value;
        if (!git_configset_get_value(cs, key, &value)) {
 -              *dest = git_config_maybe_bool(key, value);
 +              *dest = git_parse_maybe_bool(value);
                if (*dest == -1)
                        return -1;
                return 0;
@@@ -1865,211 -1892,87 +1865,211 @@@ int git_configset_get_pathname(struct c
                return 1;
  }
  
 -static void git_config_check_init(void)
 +/* Functions use to read configuration from a repository */
 +static void repo_read_config(struct repository *repo)
 +{
 +      struct config_options opts;
 +
 +      opts.respect_includes = 1;
 +      opts.commondir = repo->commondir;
 +      opts.git_dir = repo->gitdir;
 +
 +      if (!repo->config)
 +              repo->config = xcalloc(1, sizeof(struct config_set));
 +      else
 +              git_configset_clear(repo->config);
 +
 +      git_configset_init(repo->config);
 +
 +      if (config_with_options(config_set_callback, repo->config, NULL, &opts) < 0)
 +              /*
 +               * config_with_options() normally returns only
 +               * zero, as most errors are fatal, and
 +               * non-fatal potential errors are guarded by "if"
 +               * statements that are entered only when no error is
 +               * possible.
 +               *
 +               * If we ever encounter a non-fatal error, it means
 +               * something went really wrong and we should stop
 +               * immediately.
 +               */
 +              die(_("unknown error occurred while reading the configuration files"));
 +}
 +
 +static void git_config_check_init(struct repository *repo)
  {
 -      if (the_config_set.hash_initialized)
 +      if (repo->config && repo->config->hash_initialized)
                return;
 -      git_configset_init(&the_config_set);
 -      git_config_raw(config_set_callback, &the_config_set);
 +      repo_read_config(repo);
  }
  
 -void git_config_clear(void)
 +static void repo_config_clear(struct repository *repo)
  {
 -      if (!the_config_set.hash_initialized)
 +      if (!repo->config || !repo->config->hash_initialized)
                return;
 -      git_configset_clear(&the_config_set);
 +      git_configset_clear(repo->config);
  }
  
 -int git_config_get_value(const char *key, const char **value)
 +void repo_config(struct repository *repo, config_fn_t fn, void *data)
  {
 -      git_config_check_init();
 -      return git_configset_get_value(&the_config_set, key, value);
 +      git_config_check_init(repo);
 +      configset_iter(repo->config, fn, data);
  }
  
 -const struct string_list *git_config_get_value_multi(const char *key)
 +int repo_config_get_value(struct repository *repo,
 +                        const char *key, const char **value)
  {
 -      git_config_check_init();
 -      return git_configset_get_value_multi(&the_config_set, key);
 +      git_config_check_init(repo);
 +      return git_configset_get_value(repo->config, key, value);
  }
  
 -int git_config_get_string_const(const char *key, const char **dest)
 +const struct string_list *repo_config_get_value_multi(struct repository *repo,
 +                                                    const char *key)
 +{
 +      git_config_check_init(repo);
 +      return git_configset_get_value_multi(repo->config, key);
 +}
 +
 +int repo_config_get_string_const(struct repository *repo,
 +                               const char *key, const char **dest)
 +{
 +      int ret;
 +      git_config_check_init(repo);
 +      ret = git_configset_get_string_const(repo->config, key, dest);
 +      if (ret < 0)
 +              git_die_config(key, NULL);
 +      return ret;
 +}
 +
 +int repo_config_get_string(struct repository *repo,
 +                         const char *key, char **dest)
 +{
 +      git_config_check_init(repo);
 +      return repo_config_get_string_const(repo, key, (const char **)dest);
 +}
 +
 +int repo_config_get_int(struct repository *repo,
 +                      const char *key, int *dest)
 +{
 +      git_config_check_init(repo);
 +      return git_configset_get_int(repo->config, key, dest);
 +}
 +
 +int repo_config_get_ulong(struct repository *repo,
 +                        const char *key, unsigned long *dest)
 +{
 +      git_config_check_init(repo);
 +      return git_configset_get_ulong(repo->config, key, dest);
 +}
 +
 +int repo_config_get_bool(struct repository *repo,
 +                       const char *key, int *dest)
 +{
 +      git_config_check_init(repo);
 +      return git_configset_get_bool(repo->config, key, dest);
 +}
 +
 +int repo_config_get_bool_or_int(struct repository *repo,
 +                              const char *key, int *is_bool, int *dest)
 +{
 +      git_config_check_init(repo);
 +      return git_configset_get_bool_or_int(repo->config, key, is_bool, dest);
 +}
 +
 +int repo_config_get_maybe_bool(struct repository *repo,
 +                             const char *key, int *dest)
 +{
 +      git_config_check_init(repo);
 +      return git_configset_get_maybe_bool(repo->config, key, dest);
 +}
 +
 +int repo_config_get_pathname(struct repository *repo,
 +                           const char *key, const char **dest)
  {
        int ret;
 -      git_config_check_init();
 -      ret = git_configset_get_string_const(&the_config_set, key, dest);
 +      git_config_check_init(repo);
 +      ret = git_configset_get_pathname(repo->config, key, dest);
        if (ret < 0)
                git_die_config(key, NULL);
        return ret;
  }
  
 +/* Functions used historically to read configuration from 'the_repository' */
 +void git_config(config_fn_t fn, void *data)
 +{
 +      repo_config(the_repository, fn, data);
 +}
 +
 +void git_config_clear(void)
 +{
 +      repo_config_clear(the_repository);
 +}
 +
 +int git_config_get_value(const char *key, const char **value)
 +{
 +      return repo_config_get_value(the_repository, key, value);
 +}
 +
 +const struct string_list *git_config_get_value_multi(const char *key)
 +{
 +      return repo_config_get_value_multi(the_repository, key);
 +}
 +
 +int git_config_get_string_const(const char *key, const char **dest)
 +{
 +      return repo_config_get_string_const(the_repository, key, dest);
 +}
 +
  int git_config_get_string(const char *key, char **dest)
  {
 -      git_config_check_init();
 -      return git_config_get_string_const(key, (const char **)dest);
 +      return repo_config_get_string(the_repository, key, dest);
  }
  
  int git_config_get_int(const char *key, int *dest)
  {
 -      git_config_check_init();
 -      return git_configset_get_int(&the_config_set, key, dest);
 +      return repo_config_get_int(the_repository, key, dest);
  }
  
  int git_config_get_ulong(const char *key, unsigned long *dest)
  {
 -      git_config_check_init();
 -      return git_configset_get_ulong(&the_config_set, key, dest);
 +      return repo_config_get_ulong(the_repository, key, dest);
  }
  
  int git_config_get_bool(const char *key, int *dest)
  {
 -      git_config_check_init();
 -      return git_configset_get_bool(&the_config_set, key, dest);
 +      return repo_config_get_bool(the_repository, key, dest);
  }
  
  int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest)
  {
 -      git_config_check_init();
 -      return git_configset_get_bool_or_int(&the_config_set, key, is_bool, dest);
 +      return repo_config_get_bool_or_int(the_repository, key, is_bool, dest);
  }
  
  int git_config_get_maybe_bool(const char *key, int *dest)
  {
 -      git_config_check_init();
 -      return git_configset_get_maybe_bool(&the_config_set, key, dest);
 +      return repo_config_get_maybe_bool(the_repository, key, dest);
  }
  
  int git_config_get_pathname(const char *key, const char **dest)
  {
 -      int ret;
 -      git_config_check_init();
 -      ret = git_configset_get_pathname(&the_config_set, key, dest);
 -      if (ret < 0)
 -              git_die_config(key, NULL);
 -      return ret;
 +      return repo_config_get_pathname(the_repository, key, dest);
 +}
 +
 +/*
 + * Note: This function exists solely to maintain backward compatibility with
 + * 'fetch' and 'update_clone' storing configuration in '.gitmodules' and should
 + * NOT be used anywhere else.
 + *
 + * Runs the provided config function on the '.gitmodules' file found in the
 + * working directory.
 + */
 +void config_from_gitmodules(config_fn_t fn, void *data)
 +{
 +      if (the_repository->worktree) {
 +              char *file = repo_worktree_path(the_repository, GITMODULES_FILE);
 +              git_config_from_file(fn, file, data);
 +              free(file);
 +      }
  }
  
  int git_config_get_expiry(const char *key, const char **output)
        return ret;
  }
  
 +int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now)
 +{
 +      char *expiry_string;
 +      intmax_t days;
 +      timestamp_t when;
 +
 +      if (git_config_get_string(key, &expiry_string))
 +              return 1; /* no such thing */
 +
 +      if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {
 +              const int scale = 86400;
 +              *expiry = now - days * scale;
 +              return 0;
 +      }
 +
 +      if (!parse_expiry_date(expiry_string, &when)) {
 +              *expiry = when;
 +              return 0;
 +      }
 +      return -1; /* thing exists but cannot be parsed */
 +}
 +
  int git_config_get_untracked_cache(void)
  {
        int val = -1;
@@@ -2156,20 -2037,6 +2156,20 @@@ int git_config_get_max_percent_split_ch
        return -1; /* default value */
  }
  
 +int git_config_get_fsmonitor(void)
 +{
 +      if (git_config_get_pathname("core.fsmonitor", &core_fsmonitor))
 +              core_fsmonitor = getenv("GIT_FSMONITOR_TEST");
 +
 +      if (core_fsmonitor && !*core_fsmonitor)
 +              core_fsmonitor = NULL;
 +
 +      if (core_fsmonitor)
 +              return 1;
 +
 +      return 0;
 +}
 +
  NORETURN
  void git_die_config_linenr(const char *key, const char *filename, int linenr)
  {
@@@ -2210,7 -2077,7 +2210,7 @@@ static struct 
        size_t *offset;
        unsigned int offset_alloc;
        enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state;
 -      int seen;
 +      unsigned int seen;
  } store;
  
  static int matches(const char *key, const char *value)
@@@ -2324,21 -2191,21 +2324,21 @@@ static struct strbuf store_create_secti
        return sb;
  }
  
 -static int store_write_section(int fd, const char *key)
 +static ssize_t write_section(int fd, const char *key)
  {
 -      int success;
 -
        struct strbuf sb = store_create_section(key);
 +      ssize_t ret;
  
 -      success = write_in_full(fd, sb.buf, sb.len) == sb.len;
 +      ret = write_in_full(fd, sb.buf, sb.len) == sb.len;
        strbuf_release(&sb);
  
 -      return success;
 +      return ret;
  }
  
 -static int store_write_pair(int fd, const char *key, const char *value)
 +static ssize_t write_pair(int fd, const char *key, const char *value)
  {
 -      int i, success;
 +      int i;
 +      ssize_t ret;
        int length = strlen(key + store.baselen + 1);
        const char *quote = "";
        struct strbuf sb = STRBUF_INIT;
                case '"':
                case '\\':
                        strbuf_addch(&sb, '\\');
 +                      /* fallthrough */
                default:
                        strbuf_addch(&sb, value[i]);
                        break;
                }
        strbuf_addf(&sb, "%s\n", quote);
  
 -      success = write_in_full(fd, sb.buf, sb.len) == sb.len;
 +      ret = write_in_full(fd, sb.buf, sb.len);
        strbuf_release(&sb);
  
 -      return success;
 +      return ret;
  }
  
  static ssize_t find_beginning_of_line(const char *contents, size_t size,
@@@ -2465,7 -2331,7 +2465,7 @@@ int git_config_set_multivar_in_file_gen
  {
        int fd = -1, in_fd = -1;
        int ret;
 -      struct lock_file *lock = NULL;
 +      struct lock_file lock = LOCK_INIT;
        char *filename_buf = NULL;
        char *contents = NULL;
        size_t contents_sz;
         * The lock serves a purpose in addition to locking: the new
         * contents of .git/config will be written into it.
         */
 -      lock = xcalloc(1, sizeof(struct lock_file));
 -      fd = hold_lock_file_for_update(lock, config_filename, 0);
 +      fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (fd < 0) {
                error_errno("could not lock config file %s", config_filename);
                free(store.key);
                }
  
                store.key = (char *)key;
 -              if (!store_write_section(fd, key) ||
 -                  !store_write_pair(fd, key, value))
 +              if (write_section(fd, key) < 0 ||
 +                  write_pair(fd, key, value) < 0)
                        goto write_err_out;
        } else {
                struct stat st;
                close(in_fd);
                in_fd = -1;
  
 -              if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) {
 -                      error_errno("chmod on %s failed", get_lock_file_path(lock));
 +              if (chmod(get_lock_file_path(&lock), st.st_mode & 07777) < 0) {
 +                      error_errno("chmod on %s failed", get_lock_file_path(&lock));
                        ret = CONFIG_NO_WRITE;
                        goto out_free;
                }
                        /* write the first part of the config */
                        if (copy_end > copy_begin) {
                                if (write_in_full(fd, contents + copy_begin,
 -                                                copy_end - copy_begin) <
 -                                  copy_end - copy_begin)
 +                                                copy_end - copy_begin) < 0)
                                        goto write_err_out;
                                if (new_line &&
 -                                  write_str_in_full(fd, "\n") != 1)
 +                                  write_str_in_full(fd, "\n") < 0)
                                        goto write_err_out;
                        }
                        copy_begin = store.offset[i];
                /* write the pair (value == NULL means unset) */
                if (value != NULL) {
                        if (store.state == START) {
 -                              if (!store_write_section(fd, key))
 +                              if (write_section(fd, key) < 0)
                                        goto write_err_out;
                        }
 -                      if (!store_write_pair(fd, key, value))
 +                      if (write_pair(fd, key, value) < 0)
                                goto write_err_out;
                }
  
                /* write the rest of the config */
                if (copy_begin < contents_sz)
                        if (write_in_full(fd, contents + copy_begin,
 -                                        contents_sz - copy_begin) <
 -                          contents_sz - copy_begin)
 +                                        contents_sz - copy_begin) < 0)
                                goto write_err_out;
  
                munmap(contents, contents_sz);
                contents = NULL;
        }
  
 -      if (commit_lock_file(lock) < 0) {
 +      if (commit_lock_file(&lock) < 0) {
                error_errno("could not write config file %s", config_filename);
                ret = CONFIG_NO_WRITE;
 -              lock = NULL;
                goto out_free;
        }
  
 -      /*
 -       * lock is committed, so don't try to roll it back below.
 -       * NOTE: Since lockfile.c keeps a linked list of all created
 -       * lock_file structures, it isn't safe to free(lock).  It's
 -       * better to just leave it hanging around.
 -       */
 -      lock = NULL;
        ret = 0;
  
        /* Invalidate the config cache */
        git_config_clear();
  
  out_free:
 -      if (lock)
 -              rollback_lock_file(lock);
 +      rollback_lock_file(&lock);
        free(filename_buf);
        if (contents)
                munmap(contents, contents_sz);
        return ret;
  
  write_err_out:
 -      ret = write_error(get_lock_file_path(lock));
 +      ret = write_error(get_lock_file_path(&lock));
        goto out_free;
  
  }
@@@ -2765,7 -2643,7 +2765,7 @@@ static int git_config_copy_or_rename_se
  {
        int ret = 0, remove = 0;
        char *filename_buf = NULL;
 -      struct lock_file *lock;
 +      struct lock_file lock = LOCK_INIT;
        int out_fd;
        char buf[1024];
        FILE *config_file = NULL;
        if (!config_filename)
                config_filename = filename_buf = git_pathdup("config");
  
 -      lock = xcalloc(1, sizeof(struct lock_file));
 -      out_fd = hold_lock_file_for_update(lock, config_filename, 0);
 +      out_fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (out_fd < 0) {
                ret = error("could not lock config file %s", config_filename);
                goto out;
        }
  
        if (!(config_file = fopen(config_filename, "rb"))) {
 +              ret = warn_on_fopen_errors(config_filename);
 +              if (ret)
 +                      goto out;
                /* no config file means nothing to rename, no error */
                goto commit_and_out;
        }
                goto out;
        }
  
 -      if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) {
 +      if (chmod(get_lock_file_path(&lock), st.st_mode & 07777) < 0) {
                ret = error_errno("chmod on %s failed",
 -                                get_lock_file_path(lock));
 +                                get_lock_file_path(&lock));
                goto out;
        }
  
                         * multiple [branch "$name"] sections.
                         */
                        if (copystr.len > 0) {
-                               if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) {
+                               if (write_in_full(out_fd, copystr.buf, copystr.len) < 0) {
 -                                      ret = write_error(get_lock_file_path(lock));
 +                                      ret = write_error(get_lock_file_path(&lock));
                                        goto out;
                                }
                                strbuf_reset(&copystr);
                                }
                                store.baselen = strlen(new_name);
                                if (!copy) {
 -                                      if (!store_write_section(out_fd, new_name)) {
 -                                              ret = write_error(get_lock_file_path(lock));
 +                                      if (write_section(out_fd, new_name) < 0) {
 +                                              ret = write_error(get_lock_file_path(&lock));
                                                goto out;
                                        }
 -
                                        /*
                                         * We wrote out the new section, with
                                         * a newline, now skip the old
                        strbuf_add(&copystr, output, length);
                }
  
 -              if (write_in_full(out_fd, output, length) != length) {
 -                      ret = write_error(get_lock_file_path(lock));
 +              if (write_in_full(out_fd, output, length) < 0) {
 +                      ret = write_error(get_lock_file_path(&lock));
                        goto out;
                }
        }
         * logic in the loop above.
         */
        if (copystr.len > 0) {
-               if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) {
+               if (write_in_full(out_fd, copystr.buf, copystr.len) < 0) {
 -                      ret = write_error(get_lock_file_path(lock));
 +                      ret = write_error(get_lock_file_path(&lock));
                        goto out;
                }
                strbuf_reset(&copystr);
        fclose(config_file);
        config_file = NULL;
  commit_and_out:
 -      if (commit_lock_file(lock) < 0)
 +      if (commit_lock_file(&lock) < 0)
                ret = error_errno("could not write config file %s",
                                  config_filename);
  out:
        if (config_file)
                fclose(config_file);
 -      rollback_lock_file(lock);
 +      rollback_lock_file(&lock);
  out_no_rollback:
        free(filename_buf);
        return ret;