Hi,
I'm working on an epoll interface, but having trouble with nested structs. Below code snippet is just a minor example where things explode. Does anybody have an idea about what I might be missing?
Regards.
(defmacro prog1-let ((var val) &body body) `(let ((,var ,val)) ,@body ,var))
(defmacro maybe-error (test) (let ((errno (gensym))) `(when ,test (let ((,errno *errno*)) (error (foreign-funcall "strerror" :int ,errno :string))))))
(defcvar "errno" :int)
; typedef union epoll_data { ; void *ptr; ; int fd; ; __uint32_t u32; ; __uint64_t u64; ; } epoll_data_t;
(defcstruct data (ptr :pointer) (fd :int) (u32 :uint32) (u64 :uint64))
; struct epoll_event { ; __uint32_t events; /* Epoll events */ ; epoll_data_t data; /* User data variable */ ; };
(defcstruct event (events :uint32) (data data))
; int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
(defcfun "epoll_ctl" :int (epfd :int) (op :int) (fd :int) (event (:pointer event)))
(defun control (epfd op fd events) (with-foreign-object (event-ptr 'event) ;; Set `EVENTS' slot of the `EVENTS'. (setf (foreign-slot-value event-ptr 'event 'events) events) ;; Empty `DATA' slot of the `EVENTS', and set `FD' slot of the `DATA'. (let ((data-ptr (foreign-slot-pointer event-ptr 'event 'data))) (setf (foreign-slot-value data-ptr 'data 'ptr) 0 (foreign-slot-value data-ptr 'data 'u32) 0 (foreign-slot-value data-ptr 'data 'u64) 0 (foreign-slot-value data-ptr 'data 'fd) fd)) (prog1-let (res (foreign-funcall "epoll_ctl" :int epfd :int op :int fd :pointer event-ptr :int)) (maybe-error (minusp res)))))
; in: DEFUN CONTROL ; (SETF (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::PTR) ; 0 ; (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U32) ; 0 ; (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U64) ; 0 ; (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::FD) ; EPOLL::FD) ; --> PROGN SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::FOREIGN-SLOT-SET ; --> SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::MEM-SET ; --> CFFI-SYS:%MEM-SET LET SETF SB-KERNEL:%SET-SAP-REF-32 ; ==> ; EPOLL::DATA-PTR ; ; note: deleting unreachable code
; (EPOLL::PROG1-LET ; (EPOLL::RES ; (CFFI:FOREIGN-FUNCALL "epoll_ctl" :INT EPOLL::EPFD :INT EPOLL::OP :INT ; EPOLL::FD :POINTER EPOLL::EVENT-PTR :INT)) ; (EPOLL::MAYBE-ERROR (< EPOLL::RES 0))) ; --> LET ; ==> ; EPOLL::RES ; ; note: deleting unreachable code
; (SETF (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::PTR) ; 0 ; (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U32) ; 0 ; (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U64) ; 0 ; (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::FD) ; EPOLL::FD) ; --> PROGN SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::FOREIGN-SLOT-SET ; --> SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::MEM-SET ; --> CFFI-SYS:%MEM-SET LET SETF ; ==> ; (SB-KERNEL:%SET-SAP-REF-SAP EPOLL::DATA-PTR 0 #:VALUE174) ; ; caught WARNING: ; Asserted type SB-SYS:SYSTEM-AREA-POINTER conflicts with derived type ; (VALUES (INTEGER 0 0) &OPTIONAL). ; See also: ; The SBCL Manual, Node "Handling of Types" ; ; compilation unit finished ; caught 1 WARNING condition ; printed 2 notes