changeset 45520:5eee6f4f3d0d

chg: fallback to original hg if stdio fds are missing If stdio fds are missing (ex. fd 0 is not present), chg might open fds that take the numbers 0, and attachio would send the wrong fds to the client, which might cause unwanted behaviors. Avoid that by detecting the missing fds and falling back to the original hg. Differential Revision: https://phab.mercurial-scm.org/D9058
author Jun Wu <quark@fb.com>
date Fri, 18 Sep 2020 16:26:37 -0700
parents 9b16bb3b2349
children e7587430ca23
files contrib/chg/chg.c tests/test-chg.t
diffstat 2 files changed, 24 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/chg/chg.c	Fri Sep 18 08:27:43 2020 -0700
+++ b/contrib/chg/chg.c	Fri Sep 18 16:26:37 2020 -0700
@@ -373,8 +373,15 @@
 }
 
 /*
- * Test whether the command is unsupported or not. This is not designed to
- * cover all cases. But it's fast, does not depend on the server.
+ * Test whether the command and the environment is unsupported or not.
+ *
+ * If any of the stdio file descriptors are not present (rare, but some tools
+ * might spawn new processes without stdio instead of redirecting them to the
+ * null device), then mark it as not supported because attachio won't work
+ * correctly.
+ *
+ * The command list is not designed to cover all cases. But it's fast, and does
+ * not depend on the server.
  */
 static int isunsupported(int argc, const char *argv[])
 {
@@ -384,6 +391,13 @@
 	};
 	unsigned int state = 0;
 	int i;
+	/* use fcntl to test missing stdio fds */
+	if (fcntl(STDIN_FILENO, F_GETFD) == -1 ||
+	    fcntl(STDOUT_FILENO, F_GETFD) == -1 ||
+	    fcntl(STDERR_FILENO, F_GETFD) == -1) {
+		debugmsg("stdio fds are missing");
+		return 1;
+	}
 	for (i = 0; i < argc; ++i) {
 		if (strcmp(argv[i], "--") == 0)
 			break;
--- a/tests/test-chg.t	Fri Sep 18 08:27:43 2020 -0700
+++ b/tests/test-chg.t	Fri Sep 18 16:26:37 2020 -0700
@@ -197,6 +197,14 @@
 
   $ cd ..
 
+missing stdio
+-------------
+
+  $ CHGDEBUG=1 chg version -q 0<&-
+  chg: debug: * stdio fds are missing (glob)
+  chg: debug: * execute original hg (glob)
+  Mercurial Distributed SCM * (glob)
+
 server lifecycle
 ----------------