- (sb-alien:with-alien ((result-buf (* sockint::protoent)
- (sb-alien:make-alien sockint::protoent))
- (buffer (* char )
- (sb-alien:make-alien sb-alien:char buffer-length))
- #-solaris
- (result (* (* sockint::protoent))
- (sb-alien:make-alien (* sockint::protoent))))
-
- (let ((res (sockint::getprotobyname-r name
- result-buf
- buffer
- buffer-length
- #-solaris
- result)))
- (if (eql res 0)
- (progn
- #-solaris
- (when (sb-alien::null-alien (sb-alien:deref result 0))
- (error 'unknown-protocol :name name))
- (return-from get-protocol-by-name
- (protoent-to-values result-buf)))
- (let ((errno (sb-unix::get-errno)))
- (if (eql errno sockint::erange)
- (progn
- (incf buffer-length 1024)
- (if (> buffer-length max-buffer)
- (error "Exceeded max-buffer of ~d" max-buffer)))
- (error "Unexpected errno ~d" errno))))))))
- #-sb-thread
- (let ((ent (sockint::getprotobyname name)))
- (if (sb-alien::null-alien ent)
- (error 'unknown-protocol :name name))
- (protoent-to-values ent))))
+ (unwind-protect
+ (progn
+ (setf result-buf (sb-alien:make-alien sockint::protoent)
+ buffer (sb-alien:make-alien sb-alien:char buffer-length))
+ #-solaris
+ (setf result (sb-alien:make-alien (* sockint::protoent)))
+ (when (or (sb-alien:null-alien result-buf)
+ (sb-alien:null-alien buffer)
+ (sb-alien:null-alien result))
+ (error "Could not allocate foreign memory."))
+ (let ((res (sockint::getprotobyname-r
+ name result-buf buffer buffer-length #-solaris result)))
+ (cond ((eql res 0)
+ #-solaris
+ (when (sb-alien::null-alien (sb-alien:deref result 0))
+ (error 'unknown-protocol :name name))
+ (return-from get-protocol-by-name
+ (protoent-to-values result-buf)))
+ (t
+ (let ((errno (sb-unix::get-errno)))
+ (cond ((eql errno sockint::erange)
+ (incf buffer-length 1024)
+ (when (> buffer-length max-buffer)
+ (error "Exceeded max-buffer of ~d" max-buffer)))
+ (t
+ (error "Unexpected errno ~d" errno))))))))
+ (when result-buf
+ (sb-alien:free-alien result-buf))
+ (when buffer
+ (sb-alien:free-alien buffer))
+ #-solaris
+ (when result
+ (sb-alien:free-alien result)))))
+ #-(and sb-thread os-provides-getprotoby-r)
+ (tagbody
+ (flet ((get-it ()
+ (let ((ent (sockint::getprotobyname name)))
+ (if (sb-alien::null-alien ent)
+ (go :error)
+ (return-from get-protocol-by-name (protoent-to-values ent))))))
+ #+sb-thread
+ (sb-thread::with-system-mutex (**getprotoby-lock**)
+ (get-it))
+ #-sb-thread
+ (get-it))
+ :error
+ (error 'unknown-protocol :name name))))