Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 May 2013 22:19:02 +0000 (UTC)
From:      Garance A Drosehn <gad@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r251044 - head/usr.sbin/lpr/common_source
Message-ID:  <201305272219.r4RMJ2lL081629@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gad
Date: Mon May 27 22:19:01 2013
New Revision: 251044
URL: http://svnweb.freebsd.org/changeset/base/251044

Log:
  Change the closeallfds() routine to use closefrom() when it is
  available (closefrom() was added to FreeBSD in 8.0-release).
  The selection is made at compile-time, as I still compile a
  FreeBSD-based version of lpr&friends on other platforms.
  
  While testing I out that (at least on my system) lpd has been
  closing 11095 fd's, when there are only 6 fd's open.  The old
  code took 120 times more clocktime than calling closefrom().
  (although that was still less than 2/1000-ths of a second!)
  
  Reviewed by:	jilles
  MFC after:	2 weeks

Modified:
  head/usr.sbin/lpr/common_source/common.c
  head/usr.sbin/lpr/common_source/lp.cdefs.h

Modified: head/usr.sbin/lpr/common_source/common.c
==============================================================================
--- head/usr.sbin/lpr/common_source/common.c	Mon May 27 22:18:04 2013	(r251043)
+++ head/usr.sbin/lpr/common_source/common.c	Mon May 27 22:19:01 2013	(r251044)
@@ -757,16 +757,22 @@ fatal(const struct printer *pp, const ch
 
 /*
  * Close all file descriptors from START on up.
- * This is a horrific kluge, since getdtablesize() might return
- * ``infinity'', in which case we will be spending a long time
- * closing ``files'' which were never open.  Perhaps it would
- * be better to close the first N fds, for some small value of N.
  */
 void
 closeallfds(int start)
 {
-	int stop = getdtablesize();
-	for (; start < stop; start++)
-		close(start);
+	int stop;
+
+	if (USE_CLOSEFROM)		/* The faster, modern solution */
+		closefrom(start);
+	else {
+		/* This older logic can be pretty awful on some OS's.  The
+		 * getdtablesize() might return ``infinity'', and then this
+		 * will waste a lot of time closing file descriptors which
+		 * had never been open()-ed. */
+		stop = getdtablesize();
+		for (; start < stop; start++)
+			close(start);
+	}
 }
 

Modified: head/usr.sbin/lpr/common_source/lp.cdefs.h
==============================================================================
--- head/usr.sbin/lpr/common_source/lp.cdefs.h	Mon May 27 22:18:04 2013	(r251043)
+++ head/usr.sbin/lpr/common_source/lp.cdefs.h	Mon May 27 22:19:01 2013	(r251044)
@@ -1,6 +1,6 @@
 /*-
  * ------+---------+---------+---------+---------+---------+---------+---------*
- * Copyright (c) 2003  - Garance Alistair Drosehn <gad@FreeBSD.org>.
+ * Copyright (c) 2003,2013  - Garance Alistair Drosehn <gad@FreeBSD.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -56,6 +56,21 @@
 #endif
 
 /*
+ * FreeBSD added a closefrom() routine in release 8.0.  When compiling
+ * `lpr' on other platforms you might want to include bsd-closefrom.c
+ * from the portable-openssh project.
+ */
+#ifndef	USE_CLOSEFROM
+#  if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#    define	USE_CLOSEFROM	1
+#  endif
+#endif
+/* The macro USE_CLOSEFROM must be defined with a value of 0 or 1. */
+#ifndef	USE_CLOSEFROM
+#  define	USE_CLOSEFROM	0
+#endif
+
+/*
  * __unused is a compiler-specific trick which can be used to avoid
  * warnings about a variable which is defined but never referenced.
  * Some lpr files use this, so define a null version if it was not



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305272219.r4RMJ2lL081629>