From: Nikodemus Siivola Date: Wed, 16 Nov 2011 16:18:23 +0000 (+0200) Subject: sb-bsd-sockets: foreign memory leak in GET-PROTOCOL-BY-NAME X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=71c5af561afd99e3bfe4cb76f492567b50893569;p=sbcl.git sb-bsd-sockets: foreign memory leak in GET-PROTOCOL-BY-NAME I blame WITH-ALIEN usage -- it masks the MAKE-ALIEN calls from the casual eye. --- diff --git a/NEWS b/NEWS index 094ae41..d0c7328 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ changes relative to sbcl-1.0.53: result in fasl-dumping internal type objects. (lp#890750) * bug fix: type mismatch on (setf aref) and function return values no longer result in fasl-dumping internal type objects. + * bug fix: SB-BSD-SOCKETS:GET-PROTOCOL-BY-NAME leaked foreign memory. changes in sbcl-1.0.53 relative to sbcl-1.0.52: * enhancement: on 64-bit targets, in src/compiler/generic/early-vm.lisp, diff --git a/contrib/sb-bsd-sockets/inet.lisp b/contrib/sb-bsd-sockets/inet.lisp index e07f828..e4f7ff2 100644 --- a/contrib/sb-bsd-sockets/inet.lisp +++ b/contrib/sb-bsd-sockets/inet.lisp @@ -82,46 +82,53 @@ a list of protocol aliases" (sockint::protoent-name protoent) (let ((index 0)) (loop - for alias = (sb-alien:deref (sockint::protoent-aliases protoent) index) - while (not (sb-alien:null-alien alias)) - do (incf index) - collect (sb-alien::c-string-to-string (sb-alien:alien-sap alias) - (sb-impl::default-external-format) - 'character)))))) + for alias = (sb-alien:deref + (sockint::protoent-aliases protoent) index) + while (not (sb-alien:null-alien alias)) + do (incf index) + collect (sb-alien::c-string-to-string + (sb-alien:alien-sap alias) + (sb-impl::default-external-format) + 'character)))))) #+(and sb-thread os-provides-getprotoby-r) (let ((buffer-length 1024) - (max-buffer 10000)) + (max-buffer 10000) + (result-buf nil) + (buffer nil) + #-solaris + (result nil)) (declare (type fixnum buffer-length) (type fixnum max-buffer)) (loop - (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)))))))) + (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))) + (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 ()