The lock arrays are too small on Windows, leading to buffer overruns
and crashes when a program opens too many files.
The problem is that on Windows, we shouldn't use FD_SETSIZE to get the
max number of file descriptors: this is set to 64 in the mingw
includes. The real maximum is 2048 (according to the crt sources), so
we now hardwire that in.
Also, put in a runtime check that we aren't overruning this array.
MERGE TO STABLE
- * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
+ * (c) The GRASP/AQUA Project, Glasgow University, 1994-2004
- * $Id: lockFile.c,v 1.2 2002/02/07 11:13:30 simonmar Exp $
+ * $Id: lockFile.c,v 1.3 2004/06/02 12:35:11 simonmar Exp $
*
* stdin/stout/stderr Runtime Support
*/
#include "HsBase.h"
*
* stdin/stout/stderr Runtime Support
*/
#include "HsBase.h"
+#include "Rts.h"
+#include "../../ghc/rts/RtsUtils.h" // for barf()
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 256
+#ifdef mingw32_TARGET_OS
+ // The Win32 C runtime has a max of 2048 file descriptors (see
+ // _NHANDLE_ in the crt sources), but mingw defines FD_SETSIZE to
+ // 64.
+# define NUM_FDS 2048
+#else
+# ifndef FD_SETSIZE
+# error No FD_SETSIZE defined!
+# else
+# define NUM_FDS FD_SETSIZE
+# endif
-static Lock readLock[FD_SETSIZE];
-static Lock writeLock[FD_SETSIZE];
+static Lock readLock[NUM_FDS];
+static Lock writeLock[NUM_FDS];
static int readLocks = 0;
static int writeLocks = 0;
static int readLocks = 0;
static int writeLocks = 0;
+ if (fd > NUM_FDS) {
+ barf("lockFile: fd out of range");
+ }
+
while (fstat(fd, &sb) < 0) {
if (errno != EINTR) {
#ifndef _WIN32
while (fstat(fd, &sb) < 0) {
if (errno != EINTR) {
#ifndef _WIN32