Hi,
While studying the behavior of csh using ktrace I did notice it trying
to close every single fd up to _SC_OPEN_MAX except for the ones in use.
This seems a bit excessive, here's a different approach: since the fds
in use can vary one can't make assumptions about the largest fd in use.
Instead of looping over [0, _SC_OPEN_MAX), close all fds that reside in
between the gaps of fds in use. Once the largest fd in use is reached,
use closefrom().
Comments? OK?
Index: misc.c
===================================================================
RCS file: /cvs/src/bin/csh/misc.c,v
retrieving revision 1.19
diff -u -p -r1.19 misc.c
--- misc.c 14 Aug 2016 19:45:24 -0000 1.19
+++ misc.c 14 Jun 2017 16:50:38 -0000
@@ -38,6 +38,7 @@
#include "csh.h"
#include "extern.h"
+static int fdcmp(int);
static int renum(int, int);
int
@@ -163,6 +164,29 @@ lastchr(Char *cp)
}
/*
+ * Returns 0 if fd is in use, 1 if fd is greater than the largest used file
+ * descriptor and -1 otherwise.
+ */
+static int
+fdcmp(int fd)
+{
+ int fds[] = { SHIN, SHOUT, SHERR, OLDSTD, FSHTTY };
+ int i, max;
+
+ max = -1;
+ for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) {
+ if (fd == fds[i])
+ return (0);
+ if (fds[i] > max)
+ max = fds[i];
+ }
+ if (fd > max)
+ return (1);
+
+ return (-1);
+}
+
+/*
* This routine is called after an error to close up
* any units which may have been left open accidentally.
*/
@@ -173,9 +197,15 @@ closem(void)
int max = sysconf(_SC_OPEN_MAX);
for (f = 0; f < max; f++)
- if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
- f != FSHTTY)
- (void) close(f);
+ switch (fdcmp(f)) {
+ case 0:
+ continue;
+ case 1:
+ closefrom(f);
+ return;
+ default:
+ close(f);
+ }
}
void