Better %SYS-GETTID.
[iolib.git] / syscalls / os-conditions-unix.lisp
blob637913a39adc841da0b1d3663bde58f0c0326860
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; --- *NIX-specific error conditions.
4 ;;;
6 (in-package :iolib.syscalls)
8 ;;;-------------------------------------------------------------------------
9 ;;; POSIX Syscall Errors
10 ;;;-------------------------------------------------------------------------
12 (define-condition posix-error (syscall-error)
14 (:documentation
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*.
27 (macrolet
28 ((define-posix-errors (keywords)
29 `(progn
30 ,@(loop :for kw :in keywords :collect
31 (let ((cond-name (intern (symbol-name kw)))
32 (code (foreign-enum-value 'errno-values kw)))
33 `(progn
34 (define-condition ,cond-name (posix-error) ()
35 (:default-initargs :code ,code :identifier ,kw))
36 (setf (gethash ,code *posix-error-map*) ',cond-name)))))))
37 (define-posix-errors
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)))
45 (unless error-keyword
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)
49 :handle fd)))
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)))
57 (unless error-keyword
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))))