1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
3 ;;; --- *NIX-specific error conditions.
6 (in-package :iolib.syscalls
)
8 ;;;-------------------------------------------------------------------------
9 ;;; POSIX Syscall Errors
10 ;;;-------------------------------------------------------------------------
12 (define-condition posix-error
(syscall-error)
15 "POSIX-ERRORs are signalled whenever ERRNO is set by a POSIX call."))
17 ;;; HASH TABLE mapping error codes to symbols denoting
18 ;;; subtypes of POSIX-ERROR.
19 (defparameter *posix-error-map
* (make-hash-table :test
'eql
))
21 (declaim (inline get-posix-error-condition
))
22 (defun get-posix-error-condition (errno)
23 (gethash errno
*posix-error-map
*))
25 ;;; Define an error condition for each ERRNO value defined in the
26 ;;; ERRNO-VALUES enum type and populate *POSIX-ERROR-MAP*.
28 ((define-posix-errors (keywords)
30 ,@(loop :for kw
:in keywords
:collect
31 (let ((cond-name (intern (symbol-name kw
)))
32 (code (foreign-enum-value 'errno-values kw
)))
34 (define-condition ,cond-name
(posix-error) ()
35 (:default-initargs
:code
,code
:identifier
,kw
))
36 (setf (gethash ,code
*posix-error-map
*) ',cond-name
)))))))
38 #.
(foreign-enum-keyword-list 'errno-values
)))
40 ;;; Instantiates a subclass of POSIX-ERROR matching ERR
41 ;;; ERR must be either an integer denoting an ERRNO value.
42 (defun make-posix-error (errno fd
)
43 (debug-only* (assert (integerp errno
)))
44 (let ((error-keyword (foreign-enum-keyword 'errno-values errno
:errorp nil
)))
46 (bug "A non-existent ~A syscall error has been signaled: ~A, ~A"
47 'errno-values
(or error-keyword
:unknown
) errno
))
48 (make-condition (get-posix-error-condition errno
)
51 (declaim (inline posix-error
))
52 (defun signal-posix-error (&optional
(errno (%sys-errno
)) fd
)
53 (error (make-posix-error errno fd
)))
55 (defun signal-posix-error-kw (error-keyword fd
)
56 (let ((errno (foreign-enum-value 'errno-values error-keyword
:errorp nil
)))
58 (bug "A non-existent ~A syscall error has been signaled: ~A, ~A"
59 'errno-values error-keyword errno
))
60 (error (make-posix-error errno fd
))))