# HG changeset patch # User Jun Wu # Date 1456495992 0 # Node ID 2ab59ac06b762e4c598cbff41dfdfa27c82b849e # Parent 0a17cfbe54294998efbcd85e7e4a4d21c592b0c0 chg: detect chg started by chg Sometimes people may create a symbol link from hg to chg, or write a wrapper script named hg calling chg. Without $HG and $CHGHG set, this will lead to chg executes itself causing deadlock. The user will notice chg hangs for some time and aborts with a timed out message, without knowing the root cause and how to solve it. This patch sets a dummy environment variable before executing hg to detect this situation, and print a fatal message with some possible solutions. CHGINTERNALMARK is set by chg client to detect the situation that chg is started by chg. It is temporary and should be dropped to avoid possible side effects. diff -r 0a17cfbe5429 -r 2ab59ac06b76 contrib/chg/chg.c --- a/contrib/chg/chg.c Fri Feb 26 14:17:59 2016 +0000 +++ b/contrib/chg/chg.c Fri Feb 26 14:13:12 2016 +0000 @@ -227,6 +227,8 @@ memcpy(argv + baseargvsize, opts->args, sizeof(char *) * opts->argsize); argv[argsize - 1] = NULL; + if (putenv("CHGINTERNALMARK=") != 0) + abortmsg("failed to putenv (errno = %d)", errno); if (execvp(hgcmd, (char **)argv) < 0) abortmsg("failed to exec cmdserver (errno = %d)", errno); free(argv); @@ -490,6 +492,12 @@ if (getenv("CHGDEBUG")) enabledebugmsg(); + if (getenv("CHGINTERNALMARK")) + abortmsg("chg started by chg detected.\n" + "Please make sure ${HG:-hg} is not a symlink or " + "wrapper to chg. Alternatively, set $CHGHG to the " + "path of real hg."); + if (isunsupported(argc - 1, argv + 1)) execoriginalhg(argv); diff -r 0a17cfbe5429 -r 2ab59ac06b76 hgext/chgserver.py --- a/hgext/chgserver.py Fri Feb 26 14:17:59 2016 +0000 +++ b/hgext/chgserver.py Fri Feb 26 14:13:12 2016 +0000 @@ -472,3 +472,8 @@ def uisetup(ui): commandserver._servicemap['chgunix'] = chgunixservice + + # CHGINTERNALMARK is temporarily set by chg client to detect if chg will + # start another chg. drop it to avoid possible side effects. + if 'CHGINTERNALMARK' in os.environ: + del os.environ['CHGINTERNALMARK']