;;;; -*- coding: utf-8; fill-column: 78 -*-
changes relative to sbcl-1.0.42
* incompatible change: FD-STREAMS no longer participate in the serve-event
- event-loop by default.
+ event-loop by default. (lp#316072)
** In addition to streams created by explicit calls to MAKE-FD-STREAM this
affects streams from CL:OPEN.
** Streams from SOCKET-MAKE-STREAM still participate in serve-event by
* enhancement: symbols are printed using fully qualified names in several
error and warning messages which are often associated with package
conflicts or mixups (lp#622789, thanks to Attila Lendvai)
- * optimization: where available, use poll(2) instead of select(2) to check
- for blocking IO on a single FD.
* bug fix: SB-BSD-SOCKETS:SOCKET-CONNECT was not thread safe. (lp#505497,
thanks to Andrew Golding)
+ * bug fix: reading /proc files on Linux works. (lp#425199)
* bug fix: DOTIMES accepted literal non-integer reals. (lp#619393, thanks to
Roman Marynchak)
* bug fix: WRITE-TO-STRING compiler macro binding special variable names,
* bug fix: workaround for compiler hang in ORDER-UVL-SETS (lp#308914)
* bug fix: evaluation in debugger REPL works using the global context when
in frames that do not have sufficient debug information.
+ * bug fix: exceeding FD_SETSIZE limit now results in an sensible error
+ (lp#316068)
changes in sbcl-1.0.42 relative to sbcl-1.0.41
* build changes
\f
;;;; sys/select.h
+(defmacro with-fd-setsize ((n) &body body)
+ `(let ((,n (if (< 0 ,n fd-setsize)
+ ,n
+ (error "Cannot select(2) on ~D: above FD_SETSIZE limit."
+ (1- num-descriptors)))))
+ (declare (type (integer 0 #.fd-setsize) ,n))
+ ,@body))
+
;;;; FIXME: Why have both UNIX-SELECT and UNIX-FAST-SELECT?
;;; Perform the UNIX select(2) system call.
(defun unix-fast-select (num-descriptors
read-fds write-fds exception-fds
timeout-secs timeout-usecs)
- (declare (type (integer 0 #.fd-setsize) num-descriptors)
+ (declare (type integer num-descriptors)
(type (or (alien (* (struct fd-set))) null)
read-fds write-fds exception-fds)
(type (or null (unsigned-byte 31)) timeout-secs timeout-usecs))
- (flet ((select (tv-sap)
- (int-syscall ("select" int (* (struct fd-set)) (* (struct fd-set))
- (* (struct fd-set)) (* (struct timeval)))
- num-descriptors read-fds write-fds exception-fds
- tv-sap)))
- (cond ((or timeout-secs timeout-usecs)
- (with-alien ((tv (struct timeval)))
- (setf (slot tv 'tv-sec) (or timeout-secs 0))
- (setf (slot tv 'tv-usec) (or timeout-usecs 0))
- (select (alien-sap (addr tv)))))
- (t
- (unless *interrupts-enabled*
- (note-dangerous-wait "select(2)"))
- (select (int-sap 0))))))
+ (with-fd-setsize (num-descriptors)
+ (flet ((select (tv-sap)
+ (int-syscall ("select" int (* (struct fd-set)) (* (struct fd-set))
+ (* (struct fd-set)) (* (struct timeval)))
+ num-descriptors read-fds write-fds exception-fds
+ tv-sap)))
+ (cond ((or timeout-secs timeout-usecs)
+ (with-alien ((tv (struct timeval)))
+ (setf (slot tv 'tv-sec) (or timeout-secs 0))
+ (setf (slot tv 'tv-usec) (or timeout-usecs 0))
+ (select (alien-sap (addr tv)))))
+ (t
+ (unless *interrupts-enabled*
+ (note-dangerous-wait "select(2)"))
+ (select (int-sap 0)))))))
;;; UNIX-SELECT accepts sets of file descriptors and waits for an event
;;; to happen on one of them or to time out.
;;; they are ready for reading and writing. See the UNIX Programmer's
;;; Manual for more information.
(defun unix-select (nfds rdfds wrfds xpfds to-secs &optional (to-usecs 0))
- (declare (type (integer 0 #.fd-setsize) nfds)
+ (declare (type integer nfds)
(type unsigned-byte rdfds wrfds xpfds)
(type (or (unsigned-byte 31) null) to-secs)
(type (unsigned-byte 31) to-usecs)
(optimize (speed 3) (safety 0) (inhibit-warnings 3)))
- (with-alien ((tv (struct timeval))
- (rdf (struct fd-set))
- (wrf (struct fd-set))
- (xpf (struct fd-set)))
- (cond (to-secs
- (setf (slot tv 'tv-sec) to-secs
- (slot tv 'tv-usec) to-usecs))
- ((not *interrupts-enabled*)
- (note-dangerous-wait "select(2)")))
- (num-to-fd-set rdf rdfds)
- (num-to-fd-set wrf wrfds)
- (num-to-fd-set xpf xpfds)
- (macrolet ((frob (lispvar alienvar)
- `(if (zerop ,lispvar)
- (int-sap 0)
- (alien-sap (addr ,alienvar)))))
- (syscall ("select" int (* (struct fd-set)) (* (struct fd-set))
- (* (struct fd-set)) (* (struct timeval)))
- (values result
- (fd-set-to-num nfds rdf)
- (fd-set-to-num nfds wrf)
- (fd-set-to-num nfds xpf))
- nfds (frob rdfds rdf) (frob wrfds wrf) (frob xpfds xpf)
- (if to-secs (alien-sap (addr tv)) (int-sap 0))))))
+ (with-fd-setsize (nfds)
+ (with-alien ((tv (struct timeval))
+ (rdf (struct fd-set))
+ (wrf (struct fd-set))
+ (xpf (struct fd-set)))
+ (cond (to-secs
+ (setf (slot tv 'tv-sec) to-secs
+ (slot tv 'tv-usec) to-usecs))
+ ((not *interrupts-enabled*)
+ (note-dangerous-wait "select(2)")))
+ (num-to-fd-set rdf rdfds)
+ (num-to-fd-set wrf wrfds)
+ (num-to-fd-set xpf xpfds)
+ (macrolet ((frob (lispvar alienvar)
+ `(if (zerop ,lispvar)
+ (int-sap 0)
+ (alien-sap (addr ,alienvar)))))
+ (syscall ("select" int (* (struct fd-set)) (* (struct fd-set))
+ (* (struct fd-set)) (* (struct timeval)))
+ (values result
+ (fd-set-to-num nfds rdf)
+ (fd-set-to-num nfds wrf)
+ (fd-set-to-num nfds xpf))
+ nfds (frob rdfds rdf) (frob wrfds wrf) (frob xpfds xpf)
+ (if to-secs (alien-sap (addr tv)) (int-sap 0)))))))
;;; Lisp-side implmentations of FD_FOO macros. Abandon all hope who enters
;;; here...