I'm familiar with how to use mmap() in C for this (reading large text
files), but I'm not sure how to go about it under CMUCL.

I found this example in comp.lang.lisp, but since it just returns the
pointer (the output of the mmap call as an integer), how do I convert
that pointer into some kind of lisp object/structure that I can use to
read the results, either with (read-sequence) or (read-line)?

   (defun mmap (file offset length &optional write-p)
     (let* ((ofs32 (if (zerop (logand offset #x80000000))
                     offset
                     (- offset #x100000000))) ; Fake up a "(signed-byte 32)"
            (mode (logior #+linux unix::O_SYNC     ; Not on BSD (*sigh*)
                          (if write-p unix:O_RDWR unix:O_RDONLY)))
            (fd (unix:unix-open file mode 0)))
       (if (not fd)
         (error "Can't open ~s: ~s" file (unix:get-unix-error-msg))
         (unwind-protect
             (let ((mode (logior unix:PROT_READ
                                 (if write-p unix:PROT_WRITE 0))))
               (system:sap-int
                 (unix:unix-mmap nil length mode unix:MAP_SHARED fd ofs32)))
           (unix:unix-close fd)))))

Also, when using CMUCL's mmap call, am I forced to open the file with
(unix:unix-open) or can I use (with-open-file) as well?

When I tried the latter, the call to (unix:unix-mmap) returned a null value:

CL-USER> (with-open-file (file-stream "/path/to/very_large_file.txt" :direction
:input)
          (let ((mmap-ptr (unix:unix-mmap nil (file-length
file-stream) unix:PROT_READ unix:MAP_PRIVATE (system:fd-stream-fd
file-stream) 0)))
            mmap-ptr))
NIL

Reply via email to