{"thread":{"id":"21846","subject":"Running commands in wrong environment","startedAt":"2009-12-03T19:19:05Z","lastAt":"2009-12-06T14:38:33Z","messageCount":4,"participants":["Marinescu Paul dan","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"129133","messageId":"D6F784B72498304C93A8A4691967698E8EE2C44FE5@REX2.intranet.epfl.ch","threadId":"21846","inReplyTo":null,"subject":"Running commands in wrong environment","fromName":"Marinescu Paul dan","fromEmail":"pauldan.marinescu@epfl.ch","sentAt":"2009-12-03T19:19:05Z","receivedAt":"2009-12-03T19:19:05Z","isPatch":false,"sender":{"key":"pauldan.marinescu@epfl.ch","avatar":null},"body":"\ngit's start_command (run_command.c) executes a command (e.g. hook) but does not verify that it has properly set up the environment. It seems that in the unlikely case where putenv (run_command.c:117) fails, the command may have undesirable effects e.g. GIT_INDEX_FILE should have been set (interactive pre-commit hooks) but the default index will be used instead. It would be safer not to run the command but just exit in that case."},{"id":"129173","messageId":"20091204104441.GD27495@coredump.intra.peff.net","threadId":"21846","inReplyTo":"D6F784B72498304C93A8A4691967698E8EE2C44FE5@REX2.intranet.epfl.ch","subject":"Re: Running commands in wrong environment","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-12-04T10:44:41Z","receivedAt":"2009-12-04T10:44:41Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Dec 03, 2009 at 08:19:05PM +0100, Marinescu Paul dan wrote:\n\n> git's start_command (run_command.c) executes a command (e.g. hook) but\n> does not verify that it has properly set up the environment. It seems\n> that in the unlikely case where putenv (run_command.c:117) fails, the\n> command may have undesirable effects e.g. GIT_INDEX_FILE should have\n> been set (interactive pre-commit hooks) but the default index will be\n> used instead. It would be safer not to run the command but just exit\n> in that case.--\n\nHmm. It is simple enough to patch the one use of putenv, but there are\n34 other calls to setenv, which has the same problem. I am tempted to\nignore it, as it is extremely unlikely for this ever to happen, and\nadding error checking everywhere reduces the code readability.\n\nBut the consequences, as you mention, could include data loss, which\nargues for being on the safe side. In that case, we would probably want\nan \"xsetenv\" to die() if we fail to avoid cluttering the code\neverywhere.\n\nI dunno. If we're going to do it, it is probably maint-worthy. Junio?\n\n-Peff\n"},{"id":"129214","messageId":"7vr5raslqa.fsf@alter.siamese.dyndns.org","threadId":"21846","inReplyTo":"20091204104441.GD27495@coredump.intra.peff.net","subject":"Re: Running commands in wrong environment","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-12-04T17:16:45Z","receivedAt":"2009-12-04T17:16:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> But the consequences, as you mention, could include data loss, which\n> argues for being on the safe side. In that case, we would probably want\n> an \"xsetenv\" to die() if we fail to avoid cluttering the code\n> everywhere.\n>\n> I dunno. If we're going to do it, it is probably maint-worthy. Junio?\n\nMy gut feeling is xsetenv/xputenv would be sufficient.  I do not think we\nmake any setenv/putenv that we do not care about failing, perhaps other\nthan the \"if LESS is not there set it to this default value, as it would\ngive users nicer experience if they use 'less'.\"\n"},{"id":"129328","messageId":"20091206143833.GA26440@coredump.intra.peff.net","threadId":"21846","inReplyTo":"7vr5raslqa.fsf@alter.siamese.dyndns.org","subject":"Re: Running commands in wrong environment","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-12-06T14:38:33Z","receivedAt":"2009-12-06T14:38:33Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Dec 04, 2009 at 09:16:45AM -0800, Junio C Hamano wrote:\n\n> My gut feeling is xsetenv/xputenv would be sufficient.  I do not think we\n> make any setenv/putenv that we do not care about failing, perhaps other\n> than the \"if LESS is not there set it to this default value, as it would\n> give users nicer experience if they use 'less'.\"\n\nHere is a patch. I still feel a little silly writing this. The chances\nthat you will run out of memory doing setenv but _not_ doing any of the\nother git operations seems very low. But it's not too invasive a patch.\n\n-- >8 --\nSubject: [PATCH] wrap setenv and putenv with error-checking\n\nThe setenv and putenv calls can fail if they run out of\nmemory. We would generally ignore such an error and continue\nrunning, meaning in such an instance we could generate\nincorrect results (e.g., if GIT_INDEX_FILE was not set\nbefore running a hook, the hook would operate on the wrong\nindex).\n\nThis patch introduces xsetenv and xputenv wrappers which die\nupon failure. The conversion to use these wrappers is almost\na purely mechanical s/\\t(set|put)env/\\tx\\1env/, with two\nexceptions:\n\n  1. set_git_dir actually checked the return value of setenv\n     and returned an error to its caller. However, most\n     callsites simply ignored the error; the only one that\n     did check immediately called die(). So set_git_dir has\n     had its return value removed, and just calls xsetenv.\n\n  2. The gitsetenv wrapper uses putenv. However, it properly\n     passes on the return value, so calling code using\n     xsetenv does the right thing.\n\nFinally, there is one final callsite to note: in daemon.c,\nwe now call xsetenv to set REMOTE_ADDR. It is OK to die\nhere, though, as we only execute this function after we have\nforked, so we are killing only a single connection, not the\nwhole daemon.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nI didn't do unsetenv. Should we bother? POSIX says it can return an\nerror, but only for feeding it a bogus name argument.\n\n builtin-clone.c   |    2 +-\n builtin-commit.c  |    2 +-\n builtin-grep.c    |    4 ++--\n builtin-help.c    |    4 ++--\n builtin-init-db.c |    2 +-\n builtin-merge.c   |    4 ++--\n builtin-reset.c   |    2 +-\n builtin-revert.c  |    8 ++++----\n cache.h           |    2 +-\n daemon.c          |    2 +-\n environment.c     |    6 ++----\n exec_cmd.c        |    4 ++--\n git-compat-util.h |    2 ++\n git.c             |   14 +++++++-------\n path.c            |    2 +-\n run-command.c     |    2 +-\n setup.c           |    7 +++----\n wrapper.c         |   11 +++++++++++\n 18 files changed, 45 insertions(+), 35 deletions(-)\n\ndiff --git a/builtin-clone.c b/builtin-clone.c\nindex caf3025..e901e2c 100644\n--- a/builtin-clone.c\n+++ b/builtin-clone.c\n@@ -452,7 +452,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tatexit(remove_junk);\n \tsigchain_push_common(remove_junk_on_signal);\n \n-\tsetenv(CONFIG_ENVIRONMENT, mkpath(\"%s/config\", git_dir), 1);\n+\txsetenv(CONFIG_ENVIRONMENT, mkpath(\"%s/config\", git_dir), 1);\n \n \tif (safe_create_leading_directories_const(git_dir) < 0)\n \t\tdie(\"could not create leading directories of '%s'\", git_dir);\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex e93a647..f65df2b 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -756,7 +756,7 @@ static int parse_and_validate_options(int argc, const char *argv[],\n \tif (edit_flag)\n \t\tuse_editor = 1;\n \tif (!use_editor)\n-\t\tsetenv(\"GIT_EDITOR\", \":\", 1);\n+\t\txsetenv(\"GIT_EDITOR\", \":\", 1);\n \n \tif (get_sha1(\"HEAD\", head_sha1))\n \t\tinitial_commit = 1;\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex a5b6719..cb3845a 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -421,13 +421,13 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)\n \t\tstruct strbuf sb = STRBUF_INIT;\n \n \t\tgrep_add_color(&sb, opt->color_match);\n-\t\tsetenv(\"GREP_COLOR\", sb.buf, 1);\n+\t\txsetenv(\"GREP_COLOR\", sb.buf, 1);\n \n \t\tstrbuf_reset(&sb);\n \t\tstrbuf_addstr(&sb, \"mt=\");\n \t\tgrep_add_color(&sb, opt->color_match);\n \t\tstrbuf_addstr(&sb, \":sl=:cx=:fn=:ln=:bn=:se=\");\n-\t\tsetenv(\"GREP_COLORS\", sb.buf, 1);\n+\t\txsetenv(\"GREP_COLORS\", sb.buf, 1);\n \n \t\tstrbuf_release(&sb);\n \ndiff --git a/builtin-help.c b/builtin-help.c\nindex 09ad4b0..886190c 100644\n--- a/builtin-help.c\n+++ b/builtin-help.c\n@@ -329,7 +329,7 @@ static void setup_man_path(void)\n \tif (old_path)\n \t\tstrbuf_addstr(&new_path, old_path);\n \n-\tsetenv(\"MANPATH\", new_path.buf, 1);\n+\txsetenv(\"MANPATH\", new_path.buf, 1);\n \n \tstrbuf_release(&new_path);\n }\n@@ -370,7 +370,7 @@ static void show_man_page(const char *git_cmd)\n static void show_info_page(const char *git_cmd)\n {\n \tconst char *page = cmd_to_page(git_cmd);\n-\tsetenv(\"INFOPATH\", system_path(GIT_INFO_PATH), 1);\n+\txsetenv(\"INFOPATH\", system_path(GIT_INFO_PATH), 1);\n \texeclp(\"info\", \"info\", \"gitman\", page, NULL);\n \tdie(\"no info viewer handled the request\");\n }\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex dd84cae..67fd947 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -445,7 +445,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \tif (is_bare_repository_cfg == 1) {\n \t\tstatic char git_dir[PATH_MAX+1];\n \n-\t\tsetenv(GIT_DIR_ENVIRONMENT,\n+\t\txsetenv(GIT_DIR_ENVIRONMENT,\n \t\t\tgetcwd(git_dir, sizeof(git_dir)), 0);\n \t}\n \ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex 56a1bb6..8e645eb 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -959,7 +959,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \tstrbuf_addstr(&buf, \"merge\");\n \tfor (i = 0; i < argc; i++)\n \t\tstrbuf_addf(&buf, \" %s\", argv[i]);\n-\tsetenv(\"GIT_REFLOG_ACTION\", buf.buf, 0);\n+\txsetenv(\"GIT_REFLOG_ACTION\", buf.buf, 0);\n \tstrbuf_reset(&buf);\n \n \tfor (i = 0; i < argc; i++) {\n@@ -974,7 +974,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\tremotes = &commit_list_insert(commit, remotes)->next;\n \n \t\tstrbuf_addf(&buf, \"GITHEAD_%s\", sha1_to_hex(o->sha1));\n-\t\tsetenv(buf.buf, argv[i], 1);\n+\t\txsetenv(buf.buf, argv[i], 1);\n \t\tstrbuf_reset(&buf);\n \t}\n \ndiff --git a/builtin-reset.c b/builtin-reset.c\nindex 73e6022..ce54934 100644\n--- a/builtin-reset.c\n+++ b/builtin-reset.c\n@@ -220,7 +220,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, options, git_reset_usage,\n \t\t\t\t\t\tPARSE_OPT_KEEP_DASHDASH);\n \treflog_action = args_to_str(argv);\n-\tsetenv(\"GIT_REFLOG_ACTION\", reflog_action, 0);\n+\txsetenv(\"GIT_REFLOG_ACTION\", reflog_action, 0);\n \n \t/*\n \t * Possible arguments are:\ndiff --git a/builtin-revert.c b/builtin-revert.c\nindex 151aa6a..7d26a9f 100644\n--- a/builtin-revert.c\n+++ b/builtin-revert.c\n@@ -188,9 +188,9 @@ static void set_author_ident_env(const char *message)\n \t\t\tfor (timestamp++; *timestamp && isspace(*timestamp);\n \t\t\t\t\ttimestamp++)\n \t\t\t\t; /* do nothing */\n-\t\t\tsetenv(\"GIT_AUTHOR_NAME\", line, 1);\n-\t\t\tsetenv(\"GIT_AUTHOR_EMAIL\", email, 1);\n-\t\t\tsetenv(\"GIT_AUTHOR_DATE\", timestamp, 1);\n+\t\t\txsetenv(\"GIT_AUTHOR_NAME\", line, 1);\n+\t\t\txsetenv(\"GIT_AUTHOR_EMAIL\", email, 1);\n+\t\t\txsetenv(\"GIT_AUTHOR_DATE\", timestamp, 1);\n \t\t\tfree(line);\n \t\t\treturn;\n \t\t}\n@@ -247,7 +247,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \n \tgit_config(git_default_config, NULL);\n \tme = action == REVERT ? \"revert\" : \"cherry-pick\";\n-\tsetenv(GIT_REFLOG_ACTION, me, 0);\n+\txsetenv(GIT_REFLOG_ACTION, me, 0);\n \tparse_args(argc, argv);\n \n \t/* this is copied from the shell script, but it's never triggered... */\ndiff --git a/cache.h b/cache.h\nindex bf468e5..be954f9 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -386,7 +386,7 @@ extern const char *get_git_dir(void);\n extern char *get_object_directory(void);\n extern char *get_index_file(void);\n extern char *get_graft_file(void);\n-extern int set_git_dir(const char *path);\n+extern void set_git_dir(const char *path);\n extern const char *get_git_work_tree(void);\n extern const char *read_gitfile_gently(const char *path);\n extern void set_git_work_tree(const char *tree);\ndiff --git a/daemon.c b/daemon.c\nindex 5783e24..9649a25 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -515,7 +515,7 @@ static int execute(struct sockaddr *addr)\n #endif\n \t\t}\n \t\tloginfo(\"Connection from %s:%d\", addrbuf, port);\n-\t\tsetenv(\"REMOTE_ADDR\", addrbuf, 1);\n+\t\txsetenv(\"REMOTE_ADDR\", addrbuf, 1);\n \t}\n \telse {\n \t\tunsetenv(\"REMOTE_ADDR\");\ndiff --git a/environment.c b/environment.c\nindex 5171d9f..c750520 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -163,10 +163,8 @@ char *get_graft_file(void)\n \treturn git_graft_file;\n }\n \n-int set_git_dir(const char *path)\n+void set_git_dir(const char *path)\n {\n-\tif (setenv(GIT_DIR_ENVIRONMENT, path, 1))\n-\t\treturn error(\"Could not set GIT_DIR to '%s'\", path);\n+\txsetenv(GIT_DIR_ENVIRONMENT, path, 1);\n \tsetup_git_env();\n-\treturn 0;\n }\ndiff --git a/exec_cmd.c b/exec_cmd.c\nindex 408e4e5..132cc58 100644\n--- a/exec_cmd.c\n+++ b/exec_cmd.c\n@@ -64,7 +64,7 @@ void git_set_argv_exec_path(const char *exec_path)\n \t/*\n \t * Propagate this setting to external programs.\n \t */\n-\tsetenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);\n+\txsetenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);\n }\n \n \n@@ -109,7 +109,7 @@ void setup_path(void)\n \telse\n \t\tstrbuf_addstr(&new_path, \"/usr/local/bin:/usr/bin:/bin\");\n \n-\tsetenv(\"PATH\", new_path.buf, 1);\n+\txsetenv(\"PATH\", new_path.buf, 1);\n \n \tstrbuf_release(&new_path);\n }\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 5c59687..ba4b13d 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -351,6 +351,8 @@ extern void *xcalloc(size_t nmemb, size_t size);\n extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);\n extern ssize_t xread(int fd, void *buf, size_t len);\n extern ssize_t xwrite(int fd, const void *buf, size_t len);\n+extern void xsetenv(const char *name, const char *value, int overwrite);\n+extern void xputenv(char *string);\n extern int xdup(int fd);\n extern FILE *xfdopen(int fd, const char *mode);\n extern int xmkstemp(char *template);\ndiff --git a/git.c b/git.c\nindex 11544cd..e2c42cd 100644\n--- a/git.c\n+++ b/git.c\n@@ -40,7 +40,7 @@ int check_pager_config(const char *cmd)\n static void commit_pager_choice(void) {\n \tswitch (use_pager) {\n \tcase 0:\n-\t\tsetenv(\"GIT_PAGER\", \"cat\", 1);\n+\t\txsetenv(\"GIT_PAGER\", \"cat\", 1);\n \t\tbreak;\n \tcase 1:\n \t\tsetup_pager();\n@@ -89,7 +89,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t} else if (!strcmp(cmd, \"--no-replace-objects\")) {\n \t\t\tread_replace_refs = 0;\n-\t\t\tsetenv(NO_REPLACE_OBJECTS_ENVIRONMENT, \"1\", 1);\n+\t\t\txsetenv(NO_REPLACE_OBJECTS_ENVIRONMENT, \"1\", 1);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t} else if (!strcmp(cmd, \"--git-dir\")) {\n@@ -97,14 +97,14 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)\n \t\t\t\tfprintf(stderr, \"No directory given for --git-dir.\\n\" );\n \t\t\t\tusage(git_usage_string);\n \t\t\t}\n-\t\t\tsetenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);\n+\t\t\txsetenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t\t(*argv)++;\n \t\t\t(*argc)--;\n \t\t\thandled++;\n \t\t} else if (!prefixcmp(cmd, \"--git-dir=\")) {\n-\t\t\tsetenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);\n+\t\t\txsetenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t} else if (!strcmp(cmd, \"--work-tree\")) {\n@@ -112,19 +112,19 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)\n \t\t\t\tfprintf(stderr, \"No directory given for --work-tree.\\n\" );\n \t\t\t\tusage(git_usage_string);\n \t\t\t}\n-\t\t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);\n+\t\t\txsetenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t\t(*argv)++;\n \t\t\t(*argc)--;\n \t\t} else if (!prefixcmp(cmd, \"--work-tree=\")) {\n-\t\t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1);\n+\t\t\txsetenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t} else if (!strcmp(cmd, \"--bare\")) {\n \t\t\tstatic char git_dir[PATH_MAX+1];\n \t\t\tis_bare_repository_cfg = 1;\n-\t\t\tsetenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);\n+\t\t\txsetenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);\n \t\t\tif (envchanged)\n \t\t\t\t*envchanged = 1;\n \t\t} else {\ndiff --git a/path.c b/path.c\nindex 2ec950b..575ba1d 100644\n--- a/path.c\n+++ b/path.c\n@@ -336,7 +336,7 @@ char *enter_repo(char *path, int strict)\n \n \tif (access(\"objects\", X_OK) == 0 && access(\"refs\", X_OK) == 0 &&\n \t    validate_headref(\"HEAD\") == 0) {\n-\t\tsetenv(GIT_DIR_ENVIRONMENT, \".\", 1);\n+\t\txsetenv(GIT_DIR_ENVIRONMENT, \".\", 1);\n \t\tcheck_repository_format();\n \t\treturn path;\n \t}\ndiff --git a/run-command.c b/run-command.c\nindex cf2d8f7..b9777e5 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -114,7 +114,7 @@ fail_pipe:\n \t\tif (cmd->env) {\n \t\t\tfor (; *cmd->env; cmd->env++) {\n \t\t\t\tif (strchr(*cmd->env, '='))\n-\t\t\t\t\tputenv((char *)*cmd->env);\n+\t\t\t\t\txputenv((char *)*cmd->env);\n \t\t\t\telse\n \t\t\t\t\tunsetenv(*cmd->env);\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex f67250b..8d878bd 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -362,8 +362,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \tfor (;;) {\n \t\tgitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);\n \t\tif (gitfile_dir) {\n-\t\t\tif (set_git_dir(gitfile_dir))\n-\t\t\t\tdie(\"Repository setup failed\");\n+\t\t\tset_git_dir(gitfile_dir);\n \t\t\tbreak;\n \t\t}\n \t\tif (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))\n@@ -374,9 +373,9 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\t\tinside_work_tree = 0;\n \t\t\tif (offset != len) {\n \t\t\t\tcwd[offset] = '\\0';\n-\t\t\t\tsetenv(GIT_DIR_ENVIRONMENT, cwd, 1);\n+\t\t\t\txsetenv(GIT_DIR_ENVIRONMENT, cwd, 1);\n \t\t\t} else\n-\t\t\t\tsetenv(GIT_DIR_ENVIRONMENT, \".\", 1);\n+\t\t\t\txsetenv(GIT_DIR_ENVIRONMENT, \".\", 1);\n \t\t\tcheck_repository_format_gently(nongit_ok);\n \t\t\treturn NULL;\n \t\t}\ndiff --git a/wrapper.c b/wrapper.c\nindex c9be140..8fa3643 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -305,3 +305,14 @@ int unlink_or_warn(const char *file)\n \treturn rc;\n }\n \n+void xsetenv(const char *name, const char *value, int overwrite)\n+{\n+\tif (setenv(name, value, overwrite) != 0)\n+\t\tdie_errno(\"unable to setenv %s\", name);\n+}\n+\n+void xputenv(char *string)\n+{\n+\tif (putenv(string) != 0)\n+\t\tdie_errno(\"unable to putenv %s\", string);\n+}\n-- \n1.6.6.rc1.44.g4701a\n\n\n\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"}]}