Patchwork D8022: chg: pass copies of some envvars so we can detect py37+ modifications

login
register
mail settings
Submitter phabricator
Date Feb. 4, 2020, 9:55 p.m.
Message ID <ea0e0bf2a0a4ce32d4b89acb30c14341@localhost.localdomain>
Download mbox | patch
Permalink /patch/44921/
State Not Applicable
Headers show

Comments

phabricator - Feb. 4, 2020, 9:55 p.m.
spectral updated this revision to Diff 19874.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8022?vs=19656&id=19874

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8022/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8022

AFFECTED FILES
  contrib/chg/chg.c

CHANGE DETAILS




To: spectral, #hg-reviewers
Cc: yuja, mercurial-devel

Patch

diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -201,6 +201,36 @@ 
 	return hgcmd;
 }
 
+static void putsidechannelenv(const char *envname)
+{
+	char *namebuf, *valbuf;
+	const char *existing_val = getenv(envname);
+	size_t existing_val_len = 0, namebuf_len = 0, valbuf_len = 0;
+	size_t envname_len = strlen(envname);
+
+	if (existing_val != NULL) {
+		existing_val_len = strlen(existing_val);
+	}
+
+	namebuf_len = envname_len + 9;
+	namebuf = mallocx(namebuf_len);
+	memcpy(namebuf, "CHGORIG_", 8);
+	memcpy(namebuf + 8, envname, envname_len + 1);
+
+	valbuf_len = existing_val_len + 2;
+	valbuf = mallocx(valbuf_len);
+	valbuf[0] = (existing_val == NULL) ? '0' : '1';
+	if (existing_val != NULL && existing_val_len > 0) {
+		memcpy(valbuf + 1, existing_val, existing_val_len);
+	}
+	valbuf[valbuf_len - 1] = '\0';
+	if (setenv(namebuf, valbuf, 1) != 0) {
+		abortmsgerrno("failed to setenv for stored vars");
+	}
+	free(valbuf);
+	free(namebuf);
+}
+
 static void execcmdserver(const struct cmdserveropts *opts)
 {
 	const char *hgcmd = gethgcmd();
@@ -226,6 +256,14 @@ 
 	}
 	argv[argsize - 1] = NULL;
 
+	char *coerce = getenv("PYTHONCOERCECLOCALE");
+	if (coerce == NULL || coerce[0] != '0') {
+		/* Py3 modifies the environment on execution, we need a side
+		 * channel to get an unmodified environment to `hg serve` for
+		 * some variables */
+		putsidechannelenv("LC_CTYPE");
+	}
+
 	if (putenv("CHGINTERNALMARK=") != 0)
 		abortmsgerrno("failed to putenv");
 	if (execvp(hgcmd, (char **)argv) < 0)