Skip to content

Commit

Permalink
Win32: Unicode environment (incoming)
Browse files Browse the repository at this point in the history
Convert environment from UTF-16 to UTF-8 on startup.

No changes to getenv() are necessary, as the MSVCRT version is implemented
on top of char **environ.

However, putenv / _wputenv from MSVCRT no longer work, for two reasons:
1. they try to keep environ, _wenviron and the Win32 process environment
in sync, using the default system encoding instead of UTF-8 to convert
between charsets
2. msysgit and MSVCRT use different allocators, memory allocated in git
cannot be freed by the CRT and vice versa

Implement mingw_putenv using the env_setenv helper function from the
environment merge code.

Note that in case of memory allocation failure, putenv now dies with error
message (due to xrealloc) instead of failing with ENOMEM. As git assumes
setenv / putenv to always succeed, this prevents it from continuing with
incorrect settings.

Signed-off-by: Karsten Blees <[email protected]>
Signed-off-by: Stepan Kasal <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
kblees authored and gitster committed Jul 21, 2014
1 parent 7eb2619 commit b729f98
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
15 changes: 15 additions & 0 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,12 @@ char *mingw_getenv(const char *name)
return result;
}

int mingw_putenv(const char *namevalue)
{
environ = env_setenv(environ, namevalue);
return 0;
}

/*
* Note, this isn't a complete replacement for getaddrinfo. It assumes
* that service contains a numerical port, or that it is null. It
Expand Down Expand Up @@ -2052,6 +2058,11 @@ void mingw_startup()
maxlen = wcslen(_wpgmptr);
for (i = 1; i < argc; i++)
maxlen = max(maxlen, wcslen(wargv[i]));
for (i = 0; wenv[i]; i++)
maxlen = max(maxlen, wcslen(wenv[i]));

/* nedmalloc can't free CRT memory, allocate resizable environment list */
environ = xcalloc(i + 1, sizeof(char*));

/* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
maxlen = 3 * maxlen + 1;
Expand All @@ -2064,6 +2075,10 @@ void mingw_startup()
len = xwcstoutf(buffer, wargv[i], maxlen);
__argv[i] = xmemdupz(buffer, len);
}
for (i = 0; wenv[i]; i++) {
len = xwcstoutf(buffer, wenv[i], maxlen);
environ[i] = xmemdupz(buffer, len);
}
free(buffer);

/* initialize critical section for waitpid pinfo_t list */
Expand Down
2 changes: 2 additions & 0 deletions compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ char *mingw_getcwd(char *pointer, int len);

char *mingw_getenv(const char *name);
#define getenv mingw_getenv
int mingw_putenv(const char *namevalue);
#define putenv mingw_putenv

int mingw_gethostname(char *host, int namelen);
#define gethostname mingw_gethostname
Expand Down

0 comments on commit b729f98

Please sign in to comment.