1 min read

Handling errno in foreign code

If you are writing and interfacing with foreign libraries in Chez Scheme, it's often rather important that you can get efficient access to errno. When I say efficient, I also mean efficient developer time, and not just run time. In sticking with my normal goals, I try to minimize the amount of C code that I have to write for foreign code. It's often more fragile and harder to maintain over time.

But Chez Scheme's FFI, while very powerful and simple, simply doesn't have a specific way to manage error reports coming back. How do you get access to the errno? Is your method thread safe? The calling context switches back and forth between Chez Scheme and foreign code could very well cause errno to be overwritten. How do you handle this?

Well, let's go into some Chez Scheme black magic. Beware! This is unsafe and dangerous if you don't know what you are doing! Don't try this at home kids. ;-)

(define errno
  (let ([errno-ent (#%$foreign-entry "errno")])
    (lambda () (foreign-ref 'int errno-ent 0))))
(define errno-message
  (let ([$strerror (foreign-procedure "strerror"
    (lambda (num) ($strerror num))))
(define (call-with-errno thunk receiver)
    (lambda ()
      (critical-section (let ([v (thunk)]) (values v (errno)))))

Alter to taste.