chg: close file descriptors when starting the daemon stable
authorMathias De Mare <mathias.de_mare@nokia.com>
Mon, 02 Nov 2020 11:58:34 +0100
branchstable
changeset 45802 8711dc13474c
parent 45801 91c41ea14598
child 45822 61d63a774490
child 45848 41aaf960dc00
chg: close file descriptors when starting the daemon It's good practice to close file descriptors when forking to start a daemon. This did not appear to happen yet, which results in flock hanging in one location in our system (because the chg daemon keeps the locked file open). Differential Revision: https://phab.mercurial-scm.org/D9268
contrib/chg/chg.c
--- a/contrib/chg/chg.c	Sat Oct 31 17:42:31 2020 -0400
+++ b/contrib/chg/chg.c	Mon Nov 02 11:58:34 2020 +0100
@@ -8,6 +8,7 @@
  */
 
 #include <assert.h>
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -269,6 +270,31 @@
 		}
 	}
 
+	/* close any open files to avoid hanging locks */
+	DIR *dp = opendir("/proc/self/fd");
+	if (dp != NULL) {
+		debugmsg("closing files based on /proc contents");
+		struct dirent *de;
+		while ((de = readdir(dp))) {
+			char *end;
+			long fd_value = strtol(de->d_name, &end, 10);
+			if (end == de->d_name) {
+				/* unable to convert to int (. or ..) */
+				continue;
+			}
+			if (errno == ERANGE) {
+				debugmsg("tried to parse %s, but range error occurred", de->d_name);
+				continue;
+			}
+			if (fd_value > STDERR_FILENO) {
+				int res = close(fd_value);
+				if (res) {
+					debugmsg("tried to close fd %ld: %d (errno: %d)", fd_value, res, errno);
+				}
+			}
+		}
+	}
+
 	if (putenv("CHGINTERNALMARK=") != 0)
 		abortmsgerrno("failed to putenv");
 	if (execvp(hgcmd, (char **)argv) < 0)