Hi Stelian and Luis,
The Linux mremap call is missing from Osicat. It's quite handy and offers a nicer way of extending a mapping (possibly after ftruncate) than munmap/mmap.
Please review and apply. Note that the unfortunate _GNU_SOURCE addition is necessary!
(Using it for a replacement for anardb with mmap'd databases.)
On Wed, 2009-08-05 at 17:50 +0900, John Fremlin wrote:
Hi Stelian and Luis,
The Linux mremap call is missing from Osicat. It's quite handy and offers a nicer way of extending a mapping (possibly after ftruncate) than munmap/mmap.
Please review and apply. Note that the unfortunate _GNU_SOURCE addition is necessary!
(Using it for a replacement for anardb with mmap'd databases.)
Done, thanks :)
Hi Stelian,
http://www.opengroup.org/onlinepubs/000095399/functions/mmap.html
Existing implementations of mmap() return the value -1 when unsuccessful. Since the casting of this value to type void * cannot be guaranteed by the ISO C standard to be distinct from a successful value, this volume of IEEE Std 1003.1-2001 defines the symbol MAP_FAILED, which a conforming implementation does not return as the result of a successful call.
I guess whoever wrote the mmap wrapper didn't read the manpage as it assumes 0 is the bad value. :-(
Here is a horrible hack for osicat. It should probably be changed to grovel for MAP_FAILED.
diff --git a/posix/early.lisp b/posix/early.lisp index fa53d4f..ad02b98 100644 --- a/posix/early.lisp +++ b/posix/early.lisp @@ -118,6 +118,10 @@ (defun make-from-pointer-function-name (type-name) (format-symbol t "~A-~A-~A-~A" '#:make type-name '#:from '#:pointer))
+(declaim (inline minusone-pointer-p)) +(defun minusone-pointer-p (ptr) + (null-pointer-p (inc-pointer ptr 1))) + (define-parse-method errno-wrapper (base-type &key object error-predicate (return-filter 'identity) (error-generator 'syscall-signal-posix-error)) diff --git a/posix/wrappers.lisp b/posix/wrappers.lisp index 9d7eb0c..d37082c 100644 --- a/posix/wrappers.lisp +++ b/posix/wrappers.lisp @@ -59,7 +59,7 @@ (length ("off_t" off)))
#-windows -(defwrapper "mmap" ("void*" (errno-wrapper :pointer)) +(defwrapper "mmap" ("void*" (errno-wrapper :pointer :error-predicate minusone-pointer-p)) (start :pointer) (length ("size_t" size)) (prot :int) @@ -68,7 +68,7 @@ (offset ("off_t" off)))
#+linux -(defwrapper "mremap" ("void*" (errno-wrapper :pointer)) +(defwrapper "mremap" ("void*" (errno-wrapper :pointer :error-predicate minusone-pointer-p)) (old-address :pointer) (old-size ("size_t" size)) (new-size ("size_t" size))
[The bytemap project has had a correct(?) way of handling this for nearly a year (http://common-lisp.net/project/bytemap/) if anybody is interested in a tested cross-Lisp mmap.]
On Thu, 2009-08-06 at 14:56 +0900, John Fremlin wrote:
Hi Stelian,
http://www.opengroup.org/onlinepubs/000095399/functions/mmap.html
Existing implementations of mmap() return the value -1 when unsuccessful. Since the casting of this value to type void * cannot be guaranteed by the ISO C standard to be distinct from a successful value, this volume of IEEE Std 1003.1-2001 defines the symbol MAP_FAILED, which a conforming implementation does not return as the result of a successful call.
I guess whoever wrote the mmap wrapper didn't read the manpage as it assumes 0 is the bad value. :-(
Here is a horrible hack for osicat. It should probably be changed to grovel for MAP_FAILED.
Done.
[The bytemap project has had a correct(?) way of handling this for nearly a year (http://common-lisp.net/project/bytemap/) if anybody is interested in a tested cross-Lisp mmap.]
If you move the project repo into public_html/git/ it will be picked up by gitweb at http://common-lisp.net/gitweb