Commits

David Krentzlin  committed 62c873b

initial import

  • Participants

Comments (0)

Files changed (113)

File sendfile.import.scm

+;;;; sendfile.import.scm - GENERATED BY CHICKEN 4.6.3 -*- Scheme -*-
+
+(eval '(import chicken scheme extras posix srfi-4 foreign lolevel))
+(##sys#register-compiled-module
+  'sendfile
+  (list)
+  '((force-implementation . sendfile#force-implementation)
+    (*last-selected-implementation* . sendfile#*last-selected-implementation*)
+    (read-write-buffer-size . sendfile#read-write-buffer-size)
+    (implementation-selector . sendfile#implementation-selector)
+    (impl:mmapped . sendfile#impl:mmapped)
+    (impl:sendfile . sendfile#impl:sendfile)
+    (impl:read-write-loop/fd . sendfile#impl:read-write-loop/fd)
+    (impl:read-write-loop/port . sendfile#impl:read-write-loop/port)
+    (mmap-available . sendfile#mmap-available)
+    (sendfile-available . sendfile#sendfile-available)
+    (sendfile . sendfile#sendfile))
+  (list)
+  (list))
+
+;; END OF FILE

File sendfile.meta

+((egg "sendfile.egg")
+ (files "sendfile.setup" "sendfile.meta" "strategies/sendfile.linux.scm" "strategies/sendfile.solaris.scm" "strategies/mmap.scm" "strategies/rw.scm" "strategies/sendfile.bsd.scm" "strategies/sendfile.macos.scm" "sendfile.release-info" "sendfile.scm" "tests/offset-test.txt" "tests/run.scm" "tests/test-utils.scm")
+ (license "BSD")
+ (category net)
+ (author "David Krentzlin")
+ (test-depends test)
+ (synopsis "Sending a file over the network"))

File sendfile.release-info

+(repo svn "http://anonymous@code.call-cc.org/svn/chicken-eggs/release/4/{egg-name}")
+(uri meta-file "http://anonymous@code.call-cc.org/svn/chicken-eggs/release/4/{egg-name}/tags/{egg-release}/{egg-name}.meta")
+(release "1.6.0")
+(release "1.6.1")
+(release "1.6.2")
+(release "1.6.3")
+(release "1.7")
+(release "1.7.1")
+(release "1.7.2")
+(release "1.7.3")

File sendfile.scm

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Sendfile Egg for the Chicken Scheme system.
+;;              
+;; This eggs provides a capability to utilize
+;; the sendfile system-call. However it is
+;; not a mere wrapper to call this function if
+;; available, but rather its semantics may be stated as:
+;;
+;; "Send the file as fast as possible to its destination."
+;;
+;; Please report bugs to <http://trac.callcc.org/>
+;;
+;; Copyright (c) 2007 David Krentzlin 
+;;
+;; Permission is hereby granted, free of charge, to any person obtaining a
+;; copy of this software and associated documentation files (the "Software"),
+;; to deal in the Software without restriction, including without limitation
+;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
+;; and/or sell copies of the Software, and to permit persons to whom the
+;; Software is furnished to do so, subject to the following conditions:
+;;
+;; The above copyright notice and this permission notice shall be included
+;; in all copies or substantial portions of the Software.
+;; 
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+;; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+;; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+;; OTHER DEALINGS IN THE SOFTWARE.
+;; 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(module sendfile
+(force-implementation *last-selected-implementation* read-write-buffer-size
+ implementation-selector impl:mmapped impl:sendfile impl:read-write-loop/fd
+ impl:read-write-loop/port mmap-available sendfile-available sendfile)
+(import chicken scheme)
+(require-library posix lolevel srfi-4)
+(import extras posix srfi-4 foreign lolevel)
+
+
+(define (kilobytes num)  (* num 1024))
+(define (megabytes num)  (* (kilobytes num) 1024))
+
+(define-foreign-variable %bufsize int "BUFSIZ")
+
+;;set to either 'sendfile 'mmapped 'read-write or 'nothing
+(define force-implementation (make-parameter 'nothing))
+
+
+;;the buffer used in read write loops
+;;the client may adjust this to meet its need
+(define read-write-buffer-size (make-parameter %bufsize))
+
+;;the current chunk-size specifies how big the slices are that
+;;we read/write in the three scenarios. This is parameterized
+;;because different methods to send the file may work better with
+;;differently sized chunks.
+;; We've chosen 64k for two reasons:
+;; 1) as chicken does not have native threads, a smaller chunksize
+;;    means a shorter period of time that the thread blocks. 
+;; 2) it is half the typical max readahead size in Linux 2.6, giving the
+;;    kernel some time to populate the page cache in between
+;;    subsequent sendfile() calls.
+(define %current-chunk-size (make-parameter (kilobytes 64)))
+
+;;compute the next chunk to send out of offset and the length
+;;of the remaining buffer. This is really just a convenience-procedure
+;;that uses (the possibly parameterized) (chunk-size)
+
+(define (next-chunk-size current-offset target-offset)
+  (let ((distance (- target-offset current-offset)))
+    (if (> distance (%current-chunk-size)) (%current-chunk-size) distance)))
+
+
+;; yield control to other threads so that
+;; we don't block them
+(define (%yield)
+    (##sys#call-with-current-continuation
+     (lambda (return)
+       (let ((ct ##sys#current-thread))
+         (##sys#setslot ct 1 (lambda () (return (##core#undefined))))
+         (##sys#schedule) ) ) ) )
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Conditions
+;;
+;; Todo:
+;; Add conditions for
+;; * invalid implementation forced
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(define strerror (foreign-lambda c-string "strerror" int))
+
+(define (make-exn-condition location message arguments)
+  (apply make-property-condition
+         'exn
+         (append
+          (if location (list 'location location) '())
+          (if message (list 'message message) '())
+          (if (and arguments (not (null? arguments))) (list 'arguments arguments) '()))) )
+
+(define (make-sendfile-condition location message arguments)
+  (make-composite-condition
+   (make-exn-condition location message arguments)
+   (make-property-condition 'sendfile)) )
+
+(define (errno-argument)
+  (let ((err (errno)))
+    (if (zero? err)
+        '()
+        (let ((str (strerror err)))
+          (if (or (not str) (zero? (string-length str)))
+              (list (number->string err))
+              (list str) ) ) ) ) )
+
+(define (complain with-errno? msg . args)
+  (abort (make-sendfile-condition #f msg (if with-errno?
+                                             (begin
+                                               (##sys#update-errno)
+                                               (append (errno-argument) args))
+                                             args))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Strategies / Implementations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; this global is set by the implementations used
+;; so that the client programmer knows what was going on
+;; under the hood
+(define *last-selected-implementation* #f)
+
+(define mmap-available (cond-expand
+                         (mmap #t)
+                         (else #f)))
+
+(define sendfile-available (cond-expand
+                             (sendfile #t)
+                             (else #f)))
+
+;;mmap
+(cond-expand
+  (mmap (include "strategies/mmap.scm"))
+  (else
+   (define (impl:mmapped . args)
+     (complain #f "Mmap is not available on your system"))))
+
+;;sendfile
+(cond-expand
+  (sendfile
+   (cond-expand
+     (linux
+      (include "strategies/sendfile.linux.scm"))
+     ((or netbsd openbsd freebsd)
+      (include "strategies/sendfile.bsd.scm"))
+     (macosx
+      (include "strategies/sendfile.macos.scm"))
+     (sun
+      (include "strategies/sendfile.solaris.scm"))
+     (else)))
+  (else))
+
+(cond-expand
+  (sendfile
+   (define (impl:sendfile src dst offset bytes)
+     (set!  *last-selected-implementation* 'sendfile)
+     
+     (let loop ((offset offset) (target-offset (+ offset bytes)))
+       (if (= offset  target-offset)
+           bytes
+           (let* ((next-chunk (next-chunk-size offset (+ offset bytes)))
+                  (new-offset (%sendfile-implementation src dst offset next-chunk)))
+             (cond
+              ((eqv? -2.0 new-offset)   ; EAGAIN/EINTR
+               (when (write-timeout)
+                 (##sys#thread-block-for-timeout!
+                  ##sys#current-thread
+                  (+ (current-milliseconds) (write-timeout))))
+               (##sys#thread-block-for-i/o! ##sys#current-thread dst #:output)
+               (%yield)
+               (when (##sys#slot ##sys#current-thread 13)
+                 (complain #f "write operation timed out"))
+               (loop offset target-offset))
+              ((negative? new-offset)
+               (complain #t "sendfile failed"))
+              (else
+               (loop new-offset target-offset))))))))
+  (else
+   (define (impl:sendfile . args)
+     (complain #f "Sendfile is not available on your system"))))
+
+;; read-write-loop
+(include "strategies/rw.scm")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Highlevel Interface
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Select the implementation based on the amount of bytes to send
+;; It tries to select the apropriate implementation but is not fool-proof
+(define (default-selector len)
+  (cond
+   ((> len (megabytes 1) impl:read-write-loop/fd ))
+   (else
+    (cond-expand
+      (sendfile impl:sendfile)
+      (mmap     impl:mmapped)
+      (else     impl:read-write-loop/fd)))))
+
+(define implementation-selector (make-parameter default-selector))
+
+(define (port-has-fd? obj)
+  (unless (port? obj)
+    (complain #f "supplied argument is not a port"))
+  (handle-exceptions exn #f (port->fileno obj) #t))
+
+(define (->fileno obj)
+  (cond
+   ((fixnum? obj) obj)
+   ((port? obj) (port->fileno obj))
+   (else (complain #f "supplied argument is neither port nor descriptor"))))
+
+
+(define (ensure-sane-offset/bytes size offset bytes)
+  (cond
+   ((negative? offset)                    (complain #f "Offset must be >= 0 but was" offset))
+   ((and bytes (negative? bytes))         (complain #f "Bytes must be >= 0 but was " bytes))
+   ((and bytes (> (+ offset bytes) size)) (complain #f "Bytes + offset exceeds filesize" ))
+   (else #t)))
+
+(define (sendfile src dst #!key (offset 0) (bytes #f))
+    (let* ((src (->fileno src))
+           (size (file-size src))
+           (len  (or bytes (- size offset))))
+      
+      ;; ensure sane offset/bytes
+      (ensure-sane-offset/bytes size offset bytes)
+      (if (or (and (eq? (force-implementation) 'read-write-port) (port? dst))
+              (and (port? dst) (not (port-has-fd? dst))))
+          (impl:read-write-loop/port src dst offset len)
+          (begin
+            (flush-output dst) ; Implementations below use non-buffered I/O
+            (let ((dst (->fileno dst)))
+              (case (force-implementation)
+                ((sendfile)
+                 (if sendfile-available
+                     (impl:sendfile src dst offset len)
+                     (complain #f "implementation sendfile was forced but is not available")))
+                ((mmapped)
+                 (if mmap-available
+                     (impl:mmapped src dst offset len)
+                     (complain #f "implementation mmap was forced but is not available")))
+                ((read-write)      (impl:read-write-loop/fd src dst offset len))
+                ((nothing)
+                 (let ((impl ((implementation-selector) size)))
+                   (impl src dst offset len)))
+                (else
+                 (complain #f "invalid implementation forced. Allowed values are (sendfile mmapped read-write read-write-port nothing)"))))))))
+
+) ; module

File sendfile.setup

+(define madvise-test #<<CODE
+#include "sys/mman.h"
+int main (){
+  char *buff;
+  madvise(buff,0,MADV_WILLNEED);
+  return 0;
+}            
+CODE
+)
+
+(define posix-fadvise-test #<<CODE
+#define _XOPEN_SOURCE 600
+#include <fcntl.h>
+int main(){
+  int fake_fd = 0;
+  posix_fadvise(fake_fd,0,0,POSIX_FADV_SEQUENTIAL);    
+  return posix_fadvise(fake_fd,0,0,POSIX_FADV_NOREUSE);
+}
+CODE
+)
+
+(define sendfile-bsd-test #<<CODE
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+int main(){
+  int src,dst;         
+  off_t offset,res;
+  return sendfile(src,dst,offset,0,NULL,&res,0);      
+}           
+CODE
+)
+
+(define sendfile-macos-test #<<CODE
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+int main(){
+  int src,dst;         
+  off_t offset,res;
+  return sendfile(src,dst,offset,&res,0,0);      
+}           
+CODE
+)
+
+(define sendfile-sun-test #<<CODE
+#include <sys/sendfile.h>
+int main(){
+  int dst;         
+  sendfilevec_t fvec;
+  size_t written;        
+  return sendfile(dst,&fvec,1,&written);
+}
+CODE
+)
+
+(define sendfile-linux-test #<<CODE
+#include <sys/sendfile.h>
+int main(){
+  int in,out;
+  off_t offset;     
+  return sendfile(in,out,&offset,0);
+}
+CODE
+)
+
+(define mmap-test #<<CODE
+#include <sys/mman.h>
+int main(){
+   int src;         
+   return mmap(0, 100, PROT_READ | PROT_WRITE, MAP_SHARED,src, 0);
+}           
+CODE
+)  
+
+
+
+(define madvise? (try-compile madvise-test compile-only: #t))
+(define posix-fadvise? (try-compile posix-fadvise-test compile-only: #t))
+(define mmap? (try-compile mmap-test compile-only: #t))
+(define sendfile?
+          (cond-expand
+          (linux   
+           (try-compile sendfile-linux-test compile-only: #t))
+          ((or netbsd openbsd freebsd) 
+           (try-compile sendfile-bsd-test compile-only: #t))
+          (macosx
+           (try-compile sendfile-macos-test compile-only: #t))
+          (sun
+           (try-compile sendfile-sun-test compile-only: #t))
+          (else #f)))
+
+
+(let ((features '()))
+  (when madvise?
+    (set! features (cons '-D (cons 'madvise features))))
+  (when posix-fadvise?
+    (set! features (cons '-D (cons 'posix-fadvise features))))
+  (when mmap?
+    (set! features (cons '-D (cons 'mmap features))))
+  (when sendfile?
+    (set! features (cons '-D (cons 'sendfile features))))
+  (compile -s -O2 -d0 ,@features sendfile.scm -j sendfile)
+  (compile -s -O2 -d0 sendfile.import.scm)
+  (compile -c -O2 -d0 ,@features sendfile.scm  -unit sendfile -o sendfile-static.o)
+  (install-extension 
+    'sendfile
+    '("sendfile.so" "sendfile.import.so" "sendfile-static.o")
+    '((version "1.7.4")
+     (static "sendfile-static.o")
+     (documentation "sendfile.html"))))
+
+;; cleanup temp-files
+;; remove this in production
+(system "rm *.o")
+

File sendfile/branches/README

+Hmm, not quite sure what you're asking... you haven't really defined the "problem".
+
+The alignment restriction simply means that any offset value you provide has to be a multiple of the page size. For most systems, that will be a multiple of 4096.
+
+For instance, if you want to mmap 100 bytes starting at offset 50, then you have to use an offset of 0 (not 100, not 100 * 4096, not any other value), and a length of at least 150.
+
+You could do that. Alternatively, you could give 0 and just look at a correspondingly higher byte in the mmaped region. It's up to you.
+
+mmap just provides a "view" onto some file descriptor. The view must be aligned to a page boundary, but it can essentially have any length. You can look at any byte within the view.
+
+
+TODO:
+
+clean up the mmap code. It's too hard to follow
+

File sendfile/tags/1.6.0/os-dep.h

+/* NetBSD hat kein sendfile() also mmaped oder read-write*/
+/* linux ab 2.4 haben sendfile fuer >= 2.6 sendfile funktioniert nur fuer socket */
+/* freebsd ab 3.0 haben sendfile */
+/* solaris ab 8.0 haben sendfilev */
+/* windows NT hat TransmitFile */
+/* MacOS 10.5 haben sendfile */
+
+#include <chicken.h>
+
+#ifdef MADV_SEQUENTIAL
+#define HAVE_MADVISE 1
+#else
+#define MADV_SEQUENTIAL 0
+#define MADV_WILLNEED 0
+#define HAVE_MADVISE 0
+#endif
+
+#ifdef __CYGWIN__
+#define HAVE_MADVISE 0
+#endif
+
+#ifdef __linux
+
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/sendfile.h>
+ #include <sys/mman.h>
+ #include <linux/version.h>
+ #include <fcntl.h>
+
+ double sendfile_implementation(int src,int dst,double offset,size_t to_send);
+
+ #define HAVE_SENDFILE 1
+ #define HAVE_MMAP 1
+ #define USE_LINUX_IMPL
+ #define _XOPEN_SOURCE 600
+ #if defined(POSIX_FADV_SEQUENTIAL) && defined(POSIX_FADV_NOREUSE)
+  #define HAVE_POSIX_FADVISE 
+ #endif
+
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+
+ #include <sys/socket.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+
+ double sendfile_implementation(int src,int dst,double offset,size_t to_send);
+ #define USE_BSD_IMPL
+ #define HAVE_MMAP 1
+ #if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) || defined(__DragonFly__)
+  #define HAVE_SENDFILE 1
+  #include <sys/uio.h>
+ #else
+  #define HAVE_SENDFILE 0
+ #endif
+
+#elif (defined(__APPLE__) && defined(__MACH__))
+
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/uio.h>
+ #include <sys/mman.h>
+
+ double sendfile_implementation(int src,int dst,double offset,size_t to_send);
+ #define HAVE_MMAP 1
+
+ /* Not foolproof but does stop compilation when < MacOS 10.5
+  * Should also state that the MIN_ALLOWED is 10.5 but that requires
+  * compiler option setting.
+  */
+ #include <AvailabilityMacros.h>
+ #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
+   #define HAVE_SENDFILE 1
+   #define USE_DARWIN_IMPL
+ #else
+   #define HAVE_SENDFILE 0
+ #endif
+
+#elif defined(sun) || defined(__sun)
+
+ double sendfile_implementation(int src,int dst,double offset,size_t to_send);
+ #ifdef __SunOS_5_8
+   #define HAVE_SENDFILE 1
+   #define HAVE_MMAP 1
+   #define USE_SOLARIS_IMPL
+   #include <sys/sendfile.h>
+   #include <sys/mman.h>
+ #else
+   #define HAVE_SENDFILE 0
+ #endif
+
+#elif defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
+
+ #define MADV_SEQUENTIAL 0
+ #define HAVE_SENDFILE 0
+ #define HAVE_MMAP 0
+ double sendfile_implementation(int src,int dst,double offset,int to_send);
+
+#else
+
+ #define MADV_SEQUENTIAL 0
+ #define HAVE_SENDFILE 0
+ #define HAVE_MMAP 0
+ double sendfile_implementation(int src,int dst,double offset,size_t to_send);
+
+#endif
+
+
+
+
+
+
+
+

File sendfile/tags/1.6.0/sendfile-implementation.c

+#include <unistd.h>
+#include <errno.h>
+#include "os-dep.h"
+
+
+/* gnu linux sendfile syscall */
+/* changes mostly inspired by lighttpd (a very nice http server) 
+   keep up the good work folks. */
+
+#ifdef HAVE_POSIX_FADVISE
+#define READ_AHEAD (4 * 1024 * 1024)
+#endif
+
+
+#ifndef HAVE_MADVISE
+/* stub out madivise */
+int madvise(char* a, unsigned b, int c){
+  return 0;
+}
+#endif
+
+
+#if defined(USE_LINUX_IMPL)
+
+double sendfile_implementation(int src,int dst,double offset,size_t to_send){
+  int res;
+  off_t curoffset = (off_t)offset;
+
+
+#ifdef HAVE_POSIX_FADVISE
+  if((posix_fadvise(src,0,0,POSIX_FADV_SEQUENTIAL) < 0) && errno != ENOSYS)
+    return -1;
+#endif
+
+  res = sendfile(dst,src,&curoffset,to_send);
+  
+	if(res < 0){
+		if(errno == EAGAIN || errno == EINTR)
+			 return -2;
+		return -1;
+	}  
+  
+#ifdef HAVE_POSIX_FADVISE
+  if(((off_t)offset & ~(READ_AHEAD - 1)) != (((off_t)offset + res) & ~(READ_AHEAD - 1)))
+    if(posix_fadvise(src,((off_t)offset + res) & ~(READ_AHEAD - 1),READ_AHEAD,POSIX_FADV_NOREUSE) < 0)
+      return -1;
+#endif
+  return (double)curoffset;
+}
+
+#elif defined(USE_BSD_IMPL)
+
+/* FreeBSD,DragonFly BSD */
+double sendfile_implementation(int src,int dst,double offset,size_t to_send){
+  size_t res = 0;
+  off_t tmpoffset = (off_t)offset;
+
+#ifdef HAVE_POSIX_FADVISE
+  if((posix_fadvise(src,0,0,POSIX_FADV_SEQUENTIAL) < 0) && errno != ENOSYS)
+    return -1;
+#endif
+
+
+  if(sendfile(src,dst,offset,to_send,NULL,&res,0) < 0){
+    if(errno == EAGAIN)
+			return -2;
+		return -1;
+  }
+
+#ifdef HAVE_POSIX_FADVISE
+  if(((off_t)offset & ~(READ_AHEAD - 1)) != (((off_t)offset + res) & ~(READ_AHEAD - 1)))
+    if(posix_fadvise(src,((off_t)offset + res) & ~(READ_AHEAD - 1),READ_AHEAD,POSIX_FADV_NOREUSE) < 0)
+      return -1;
+#endif
+
+  return (double)(offset + res);
+}
+
+#elif defined(USE_DARWIN_IMPL)
+
+/* Darwin 9.0+ */
+double sendfile_implementation(int src,int dst,double offset,size_t to_send){
+  off_t res = to_send;
+  //struct sf_hdtr hdtr;
+  
+  //memset(&hdtr,0,sizeof(hdtr));
+  if(sendfile(src,dst,(off_t)offset,&res,NULL/*&hdtr*/,0) < 0){
+    if(errno == EAGAIN)
+			return -2;
+		return -1;
+  }
+
+  return (double)(offset + res);
+}
+
+#elif defined(USE_SOLARIS_IMPL)
+
+double sendfile_implementation(int src,int dst,double offset,size_t to_send){
+  sendfilevec_t fvec;
+  size_t written;
+  
+  fvec.sfv_fd = src;
+  fvec.sfv_flag = 0;
+  fvec.sfv_len = to_send;
+  fvec.sfv_off = (off_t)offset;
+    
+  if(sendfilev(dst,&fvec,1,&written) == -1){
+    if(errno == EAGAIN)
+			return -2;
+		return -1;
+  }
+
+  return (double)(offset + written);
+}
+
+
+#else
+
+double sendfile_implementation(int src,int dst,double offset,size_t to_send){
+  return 0;
+}
+
+
+#endif
+
+
+

File sendfile/tags/1.6.0/sendfile.doc.scm

+(use eggdoc)
+;(use eggdoc-zb)
+
+(define examples `( (pre #<<EOF
+(use sendfile)
+
+;;in all the examples
+;;we use a generic procedure with-prepared-environment
+;;which we assume provides us with the input and outputports
+;;needed. Most of the time the output-port will be a socket
+;;and the input-port may be connected to a file
+;;the size of the input-file was gathered as well
+
+
+;; use the standard interface and let the system decide what to do
+(with-prepared-environment
+ (lambda (in out len)
+   (sendfile in out)))
+
+;; force a specific method to use: Part I
+
+;;read-write
+;;notice that you can force a specific transmission method
+;;via the srfi parameter sendfile:force-implementation
+;;there are four possible values: 'sendfile,'read-write-loop,'mmapped,'nothing
+;;'nothing is the default, if this is set, sendfile will decide which implementation to use
+;;based on the systems capabilities and the filesize
+(with-prepared-environment
+ (lambda (in out len)
+   (parameterize ((sendfile:force-implementation 'read-write))
+     (sendfile in out))))
+
+;;force a specific method to use: Part II
+
+;;sometimes you may want to decide which method to
+;;use based on the size of the file.
+;;there is an srfi-parameter called sendfile:implementation-selector
+;;which does just that. See documentation for details
+(with-prepared-environment
+ (lambda (in out)
+   (paramaterize ((sendfile:implementation-selector) (lambda (len)
+                                                       (if (> len 1024)
+                                                           sendfile:sendfile
+                                                           sendfile:read-write-loop)))
+                 (sendfile in out))))
+
+EOF
+)))
+
+(define doc
+  `((eggdoc:begin
+    (name "sendfile")
+    (description "faster filetransfer over the network")
+    (author "David Krentzlin")
+    (history
+     (version "1.5.0" "The 'force parameter has been removed from (sendfile), its a parameter now instead. Bugfix for the read-write-loop, that causes corrupted files to be sent.")
+     (version "1.4.3" "MacOS X 10.5 support, fix of BSD & default 'sendfile_implementation' argument order, better error information")
+     (version "1.3.0" "make it compile on windows")
+     (version "1.2.0" "allmost complete rewrite")
+     (version "1.1.0" "Enhanced portability")
+     (version "1.0.0" "Initial release"))
+    (usage)
+    (download "sendfile.egg")
+    (documentation
+     (p "This extension provides a way to do filetransfers with zero-copy-semantics if applicable. It provides an interface to the sendfile syscall on
+ systems that support it. On other systems it emulates it with the help of memory-mapped IO. Sendfile is very configurable and tries to do the best based
+ on the actual file. See below to learn what it provides.")
+     
+     (p "NOTE: theoretically read-write-loop and mmapped-io can be used for file-to-file-transfers, where sendfile can only be used for file-network-transfers.")
+     
+     (subsection "sending a file. the main interface"
+       (group            
+        (procedure "(sendfile source destination)"
+          (p "Tries to send the file identified by `source` to `destination` as fast as possible. Unless a specific technique is forced it will decide what method to use from the systems capabilities and the filesize.")
+
+          (p "source ... can be either a port to the inputfile or a filedescriptor of an allready opened file."
+
+          (p "destination ... can be either a port to the outputfile (socket) or a filedescriptor (socketdesciptor) of an allready opened file (socket)")))))
+     
+     (subsection "sending a file with the sendfile-syscall"
+      (group            
+        (procedure "(sendfile:sendfile source destination len)"
+          (p "If it is available this is the interface to the sendfile-implementation of your operating system")
+
+          (p "source ... is the filedescriptor of an allready opened file")
+          (p "destination ... is the filedescriptor of an allready opened file (MUST be a socket)")
+          (p "len ... is the size of the file in bytes as e.g. retrieved by (file-size)")
+          (p "This procedure returns the amount of bytes successfully written."))))
+
+     (subsection "sending a file with memory-mapped-io"
+      (group            
+        (procedure "(sendfile:mmapped source destination len)"
+          (p "Sends a file by mapping it into the memory and do repeated writes.")
+          (p "source ... is the filedescriptor of an allready opened file")
+          (p "destination ... is the filedescriptor of an allready opened file (can be a socket)")
+          (p "len ... is the size of the file in bytes as e.g. retrieved by (file-size)")
+          (p "This procedure returns the amount of bytes successfully written."))))
+
+     (subsection "sending a file with a read-write-loop"
+      (group            
+        (procedure "(sendfile:read-write-loop source destination len)"
+          (p "Sends a file by performing repeated reads and writes.")
+
+          (p "source ... is the filedescriptor of an allready opened file")
+          (p "destination ... is the filedescriptor of an allready opened file (can be a socket)")
+          (p "len ... is the size of the file in bytes as e.g. retrieved by (file-size)")
+          (p "This procedure returns the amount of bytes successfully written."))))
+
+     (subsection "test if sendfile is nativly available"
+      (group            
+        (definition "sendfile:os-dep:sendfile-available?"
+          (p "Is set to #t if the sendfile-syscall is available and #f if not"))))
+
+     (subsection "test if mmap() is available"
+      (group            
+        (definition "sendfile:os-dep:mmap-available?"
+          (p "Is set to #t if the mmap() is available and #f if not"))))
+
+     (subsection "Parameters"
+      (group            
+        (parameter "sendfile:read-write-buffer-size"
+          (p "The size of the buffer that is used in sendfile:read-write-loop"))
+        (parameter "sendfile:force-implementation"
+          (p "Causes sendfile to allways use the transmission-method specified by this parameter.
+             Possible values are 'sendfile,'mmapped,'read-write and 'nothing.
+            It defaults to 'nothing, where (sendfile) will decide which method to use based on the system's capabilities and sendfile:implementation-selector"))
+        (parameter "sendfile:implementation-selector"
+          (p "A one-argument procedure that gets the size of the file in question passed and is expected to return a procedure to use (either of sendfile:mmapped,sendfile:sendfile,sendfile:read-write-loop)"))))
+          
+                   
+
+     (examples ,examples)))))
+
+(eggdoc->html doc)

File sendfile/tags/1.6.0/sendfile.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!-- Generated by eggdoc Revision: 1.20  -->
+<html>
+<head>
+<title>Eggs Unlimited - sendfile</title><style type="text/css"> <!--
+      CODE {
+            color: #666666;
+          }
+/*   DT.definition EM { font-weight: bold; font-style: normal; } */
+
+     DT.definition { 
+                   background: #eee;
+                   color: black;
+                   padding: 0.2em 1em 0.2em 0.7em;
+                   margin-left: 0.2em;
+border: 1px solid #bbc;
+                   font-family: "Andale Mono", monospace;
+                   /* font-size: 1.2em; */
+                   
+                 }
+     DD {
+                   margin-top: 0.8em;
+                   margin-bottom: 0.8em;
+     }
+     DIV.subsection {
+                    border-top: 1px solid #448;
+                    padding-left: 1em;
+                    margin-bottom: 1.2em;
+     }
+     DIV.subsubsection {
+                    border-top: 1px dotted #99c;
+                    /* border-left: 1px solid #99c; */
+                    padding-left: 1em;
+                    margin-bottom: 1.2em;
+     }
+     DIV.subsubsubsection {
+                    border-top: 1px solid #ddf;
+                    padding-left: 1em;
+                    margin-bottom: 1.2em;
+     }
+
+	 DIV.section {
+		 margin-bottom: 1.5em;
+	 }
+	 a:link {
+		 color: #336;
+	 }
+	 a:visited { color: #666; }
+	 a:active  { color: #966; }
+	 a:hover   { color: #669; }
+	 body { margin: 0; padding: 0; background: #fff; color: #000; font: 9pt "Lucida Grande", "Verdana", sans-serif; }
+	 H2 {
+		 background: #336;
+		 color: #fff;
+		 padding-top: 0.5em;
+		 padding-bottom: 0.5em;
+		 padding-left: 16px;
+		 margin: 0 0 1em 0;
+	}
+	UL LI {
+		list-style: none;
+	}
+	TT {
+		font-family: "Andale Mono", monospace;
+		/* font-size: 1.2em; */
+	}
+	H3 {
+		color: #113;
+		margin-bottom: 0.5em;
+	}
+	H4, H5, H6 {
+		color: #113;
+		margin-bottom: 1.0em;
+	}
+	H5 {
+		font-weight: normal;
+                font-style: italic;
+		font-size: 100%;
+		margin-top: 1.2em;
+	}
+	H6 {
+		font-weight: bold;
+		font-size: 85%;
+		margin-top: 1.2em;
+	}
+     DIV#eggheader {
+         text-align: center;
+		 float: right;
+		 margin-right: 2em;
+     }
+     DIV#header IMG {
+            /* display: block; margin-left: auto; margin-right: auto;  */
+            /* float: right; */
+            border: none;  /* firefox */
+     }
+     DIV#footer {
+                background: #bbd;
+                padding: 0.7em ;
+                border-top: 1px solid #cce;
+     }
+     DIV#footer hr {
+                display: none;
+     }
+     DIV#footer a {
+                float: left;
+     }
+     DIV#revision-history {
+         float: right;
+     }
+     
+     DIV#body {
+		 margin: 1em 1em 1em 16px;
+	 }
+
+     DIV#examples PRE {
+       background: #eef;
+       padding: 0.1em;
+       border: 1px solid #aac;
+     }
+     PRE#license, DIV#examples PRE {
+       padding: 0.5em;
+     }
+     DIV#examples PRE {
+       /* font-size: 85%; */
+     }
+     PRE { font-family: "Andale Mono", monospace; }
+     TABLE {
+       background: #eef;
+       padding: 0.2em;
+       border: 1px solid #aac;
+       border-collapse: collapse;
+       width: 100%;
+     }
+     TABLE.symbol-table TD.symbol {
+          width: 15em;
+          font-family: "Andale Mono", monospace;
+          /* font-size: 1.2em; */
+     }
+     TH {
+       text-align: left;
+       border-bottom: 1px solid #aac;
+       padding: 0.25em 0.5em 0.25em 0.5em;
+     } 
+     TD { padding: 0.25em 0.5em 0.25em 0.5em; }
+     --></style></head>
+<body>
+<div id="header">
+<h2>sendfile</h2>
+<div id="eggheader"><a href="index.html">
+<img src="egg.jpg" alt="[Picture of an egg]" /></a></div></div>
+<div id="body">
+<div class="section">
+<h3>Description</h3>faster filetransfer over the network</div>
+<div class="section">
+<h3>Author</h3>David Krentzlin</div>
+<div class="section">
+<h3>Version</h3>
+<ul>
+<li>1.5.0 The 'force parameter has been removed from (sendfile), its a parameter now instead. Bugfix for the read-write-loop, that causes corrupted files to be sent.</li>
+<li>1.4.3 MacOS X 10.5 support, fix of BSD &amp; default 'sendfile_implementation' argument order, better error information</li>
+<li>1.3.0 make it compile on windows</li>
+<li>1.2.0 allmost complete rewrite</li>
+<li>1.1.0 Enhanced portability</li>
+<li>1.0.0 Initial release</li></ul></div>
+<div class="section">
+<h3>Usage</h3><tt>(require-extension sendfile)</tt></div>
+<div class="section">
+<h3>Download</h3><a href="sendfile.egg">sendfile.egg</a></div>
+<div class="section">
+<h3>Documentation</h3>
+<p>This extension provides a way to do filetransfers with zero-copy-semantics if applicable. It provides an interface to the sendfile syscall on
+ systems that support it. On other systems it emulates it with the help of memory-mapped IO. Sendfile is very configurable and tries to do the best based
+ on the actual file. See below to learn what it provides.</p>
+<p>NOTE: theoretically read-write-loop and mmapped-io can be used for file-to-file-transfers, where sendfile can only be used for file-network-transfers.</p>
+<div class="subsection">
+<h4>sending a file. the main interface</h4>
+<dl>
+<dt class="definition"><strong>procedure:</strong> (sendfile source destination)</dt>
+<dd>
+<p>Tries to send the file identified by `source` to `destination` as fast as possible. Unless a specific technique is forced it will decide what method to use from the systems capabilities and the filesize.</p>
+<p>source ... can be either a port to the inputfile or a filedescriptor of an allready opened file.
+<p>destination ... can be either a port to the outputfile (socket) or a filedescriptor (socketdesciptor) of an allready opened file (socket)</p></p></dd></dl></div>
+<div class="subsection">
+<h4>sending a file with the sendfile-syscall</h4>
+<dl>
+<dt class="definition"><strong>procedure:</strong> (sendfile:sendfile source destination len)</dt>
+<dd>
+<p>If it is available this is the interface to the sendfile-implementation of your operating system</p>
+<p>source ... is the filedescriptor of an allready opened file</p>
+<p>destination ... is the filedescriptor of an allready opened file (MUST be a socket)</p>
+<p>len ... is the size of the file in bytes as e.g. retrieved by (file-size)</p>
+<p>This procedure returns the amount of bytes successfully written.</p></dd></dl></div>
+<div class="subsection">
+<h4>sending a file with memory-mapped-io</h4>
+<dl>
+<dt class="definition"><strong>procedure:</strong> (sendfile:mmapped source destination len)</dt>
+<dd>
+<p>Sends a file by mapping it into the memory and do repeated writes.</p>
+<p>source ... is the filedescriptor of an allready opened file</p>
+<p>destination ... is the filedescriptor of an allready opened file (can be a socket)</p>
+<p>len ... is the size of the file in bytes as e.g. retrieved by (file-size)</p>
+<p>This procedure returns the amount of bytes successfully written.</p></dd></dl></div>
+<div class="subsection">
+<h4>sending a file with a read-write-loop</h4>
+<dl>
+<dt class="definition"><strong>procedure:</strong> (sendfile:read-write-loop source destination len)</dt>
+<dd>
+<p>Sends a file by performing repeated reads and writes.</p>
+<p>source ... is the filedescriptor of an allready opened file</p>
+<p>destination ... is the filedescriptor of an allready opened file (can be a socket)</p>
+<p>len ... is the size of the file in bytes as e.g. retrieved by (file-size)</p>
+<p>This procedure returns the amount of bytes successfully written.</p></dd></dl></div>
+<div class="subsection">
+<h4>test if sendfile is nativly available</h4>
+<dl>
+<dt class="definition">sendfile:os-dep:sendfile-available?</dt>
+<dd>
+<p>Is set to #t if the sendfile-syscall is available and #f if not</p></dd></dl></div>
+<div class="subsection">
+<h4>test if mmap() is available</h4>
+<dl>
+<dt class="definition">sendfile:os-dep:mmap-available?</dt>
+<dd>
+<p>Is set to #t if the mmap() is available and #f if not</p></dd></dl></div>
+<div class="subsection">
+<h4>Parameters</h4>
+<dl>
+<dt class="definition"><strong>parameter:</strong> sendfile:read-write-buffer-size</dt>
+<dd>
+<p>The size of the buffer that is used in sendfile:read-write-loop</p></dd>
+<dt class="definition"><strong>parameter:</strong> sendfile:force-implementation</dt>
+<dd>
+<p>Causes sendfile to allways use the transmission-method specified by this parameter.
+             Possible values are 'sendfile,'mmapped,'read-write and 'nothing.
+            It defaults to 'nothing, where (sendfile) will decide which method to use based on the system's capabilities and sendfile:implementation-selector</p></dd>
+<dt class="definition"><strong>parameter:</strong> sendfile:implementation-selector</dt>
+<dd>
+<p>A one-argument procedure that gets the size of the file in question passed and is expected to return a procedure to use (either of sendfile:mmapped,sendfile:sendfile,sendfile:read-write-loop)</p></dd></dl></div>
+<div class="section">
+<h3>Examples</h3>
+<div id="examples">
+<pre>(use sendfile)
+
+;;in all the examples
+;;we use a generic procedure with-prepared-environment
+;;which we assume provides us with the input and outputports
+;;needed. Most of the time the output-port will be a socket
+;;and the input-port may be connected to a file
+;;the size of the input-file was gathered as well
+
+
+;; use the standard interface and let the system decide what to do
+(with-prepared-environment
+ (lambda (in out len)
+   (sendfile in out)))
+
+;; force a specific method to use: Part I
+
+;;read-write
+;;notice that you can force a specific transmission method
+;;via the srfi parameter sendfile:force-implementation
+;;there are four possible values: 'sendfile,'read-write-loop,'mmapped,'nothing
+;;'nothing is the default, if this is set, sendfile will decide which implementation to use
+;;based on the systems capabilities and the filesize
+(with-prepared-environment
+ (lambda (in out len)
+   (parameterize ((sendfile:force-implementation 'read-write))
+     (sendfile in out))))
+
+;;force a specific method to use: Part II
+
+;;sometimes you may want to decide which method to
+;;use based on the size of the file.
+;;there is an srfi-parameter called sendfile:implementation-selector
+;;which does just that. See documentation for details
+(with-prepared-environment
+ (lambda (in out)
+   (paramaterize ((sendfile:implementation-selector) (lambda (len)
+                                                       (if (&gt; len 1024)
+                                                           sendfile:sendfile
+                                                           sendfile:read-write-loop)))
+                 (sendfile in out))))
+</pre></div></div></div></div>
+<div id="footer">
+<hr /><a href="index.html">&lt; Egg index</a>
+<div id="revision-history">$Revision$ $Date$</div>&nbsp;</div></body></html>

File sendfile/tags/1.6.0/sendfile.meta

+((egg "sendfile.egg")
+ (files "sendfile.doc.scm" "sendfile.scm" "sendfile-implementation.c"  "os-dep.h" "sendfile.setup" "sendfile.html")
+ (eggdoc "sendfile.doc.scm")
+ (license "BSD")
+ (category net)
+ (author "David Krentzlin")
+ (synopsis "Sending a file over the network"))

File sendfile/tags/1.6.0/sendfile.scm

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Sendfile Egg for the Chicken Scheme system.
+;;              
+;; This eggs provides a capability to utilize
+;; the sendfile system-call. However it is
+;; not a mere wrapper to call this function if
+;; available, but rather its semantics may be stated as:
+;;
+;; "Send the file as fast as possible to its destination."
+;;
+;; Please report bugs to <http://trac.callcc.org/>
+;;
+;; Copyright (c) 2007 David Krentzlin 
+;;
+;;
+;; Thanks to Peter Bex for supplying patches and testing it on NetBSD
+;;
+;; Permission is hereby granted, free of charge, to any person obtaining a
+;; copy of this software and associated documentation files (the "Software"),
+;; to deal in the Software without restriction, including without limitation
+;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
+;; and/or sell copies of the Software, and to permit persons to whom the
+;; Software is furnished to do so, subject to the following conditions:
+;;
+;; The above copyright notice and this permission notice shall be included
+;; in all copies or substantial portions of the Software.
+;; 
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+;; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+;; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+;; OTHER DEALINGS IN THE SOFTWARE.
+;; 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+
+;;sendfile attempts to send a file from the sourcefile out to a tcp-socket
+;;as fast as possible. On systems that provide sendfile(2) syscalls
+;;this syscall will be used if apropriate on other systems memory-mapped write
+;;will be used to emulate this. And if even this fails a normal system-write
+;;will be used to send the data
+
+
+;;TODO
+;;add -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES to sendfile.setup ?
+
+(require-library lolevel posix extras srfi-13 srfi-4)
+(foreign-declare "#include \"os-dep.h\"\n")
+
+(module sendfile
+  (force-implementation
+   *last-selected-implementation*
+   read-write-buffer-size
+   implementation-selector
+   impl:mmapped
+   impl:sendfile
+   impl:read-write-loop/fd
+   impl:read-write-loop/port
+   os-dep:sendfile-available?
+   os-dep:mmap-available?
+   sendfile)
+  (import scheme chicken posix srfi-4 (only lolevel pointer-offset))
+          
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  ;; Helpers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+  ;;we need to know the wordsize to calculate the
+  ;;biggest representable fixnum. This is used as the
+  ;;size to be passed to sendfile
+  (define-foreign-variable %word-size int "C_WORD_SIZE")
+
+  ;;is the sendfile(2) avilable?
+  (define-foreign-variable %have-native-sendfile int "HAVE_SENDFILE")
+  (define os-dep:sendfile-available? (= %have-native-sendfile 1))
+
+  ;;is mmap nativly available?
+  (define-foreign-variable %have-mmap int "HAVE_MMAP")
+  (define os-dep:mmap-available? (= %have-mmap 1))
+
+  
+  ;;system-specific defines that are used to fine-tune somethings if
+  ;;they are available
+  (define-foreign-variable %have-madvise int "HAVE_MADVISE")
+  (define-foreign-variable %madvise-sequential int "MADV_SEQUENTIAL")
+  (define-foreign-variable %madvise-will-need int "MADV_WILLNEED")
+
+  
+  (define-foreign-variable %bufsize int "BUFSIZ")
+
+  
+  ;;the buffer used in read write loops
+  ;;the client may adjust this to meet its need
+  (define read-write-buffer-size (make-parameter %bufsize))
+
+  ;;advise the kernel for a specific buffer
+  ;;this is used in  mmapped io if supported
+  (define (%madvise buff len behav)
+    (if (= %have-madvise 1)
+        ((foreign-lambda int "madvise" (pointer char) unsigned-integer int) buff len behav)))
+
+  
+  ;;the sendfile implementation
+  ;;note that we pass a flonum instead of an integer as we need
+  ;;to be able to represent abritrary sizes on non-64bit systems as well
+  ;;also (file-size) currently returns a float for big-files
+  (define %sendfile-implementation
+    (foreign-lambda double "sendfile_implementation" int int double unsigned-integer))
+
+
+
+  ;;some helpers that make things cleaner
+  (define (kilobytes num) (* num 1024))
+  (define (megabytes num)  (* (kilobytes num) 1024))
+
+  ;;the current chunk-size specifies how big the slices are that
+  ;;we read/write in the three scenarios. This is parameterized
+  ;;because different methods to send the file may work better with
+  ;;differently sized chunks
+  (define %current-chunk-size (make-parameter (kilobytes 512)))
+
+  ;;compute the next chunk to send out of offset and the length
+  ;;of the remaining buffer. This is really just a convenience-procedure
+  ;;that uses (the possibly parameterized) (chunk-zize)
+  (define (%next-chunk-size len offset)
+    (if (> (- len offset) (%current-chunk-size))
+        (%current-chunk-size)
+        (- len offset)))
+
+  (define *last-selected-implementation* #f)
+
+  (define write-timeout (make-parameter #f))
+
+  ;;copied from tcp
+  (define (%yield)
+    (##sys#call-with-current-continuation
+     (lambda (return)
+       (let ((ct ##sys#current-thread))
+         (##sys#setslot ct 1 (lambda () (return (##core#undefined))))
+         (##sys#schedule) ) ) ) )
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  ;; Conditions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  (define strerror (foreign-lambda c-string "strerror" int))
+
+  (define (make-exn-condition location message arguments)
+    (apply make-property-condition
+           'exn
+           (append
+            (if location (list 'location location) '())
+            (if message (list 'message message) '())
+            (if (and arguments (not (null? arguments))) (list 'arguments arguments) '()))) )
+
+  (define (make-sendfile-condition location message arguments)
+    (make-composite-condition
+     (make-exn-condition location message arguments)
+     (make-property-condition 'sendfile)) )
+
+  (define (errno-argument)
+    (let ((err (errno)))
+      (if (zero? err)
+          '()
+          (let ((str (strerror err)))
+            (if (or (not str) (zero? (string-length str)))
+                (list (number->string err))
+                (list str) ) ) ) ) )
+
+  (define (%error msg . args)
+    (abort (make-sendfile-condition #f msg (append (errno-argument) args))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; The three implementations follow now.
+;; sendfile implements three distinct strategies to send the file over the wire.
+;; Which method is used depends on the system's capabilities and the size of the file
+;; 1) it uses sendfile(2)
+;; 2) it uses mmapped-io. This means chunks of the file are mmapped into the process-memory
+;;    and written to the socket
+;; 3) it uses read-writes repeatetly. This is the simplest (NOT the slowest in all cases) strategy.
+;;    It simply reads a chunk of the file and writes it out to the socket
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;MMAPPED-SEND
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  (define (impl:mmapped src dst len)
+    (set!  *last-selected-implementation* 'mmapped)
+    
+    (unless os-dep:mmap-available?
+      (%error  "mmap is not available on this system"))
+    
+    (define sys:write (foreign-lambda integer "write" integer c-pointer unsigned-integer))
+
+    (define (send-chunk ptr size write-timeout)
+      ;;don't bother adivices for data smaller than 64k
+      (when (> size (kilobytes 64)) (%madvise ptr size %madvise-will-need))
+      (let loop ((bytes-left size) (work-ptr (pointer-offset ptr 0)))
+        (if (zero? bytes-left)
+            #t
+            (let ((result (sys:write dst work-ptr bytes-left)))
+              (cond
+               ((and (negative? result) (= errno/again (##sys#update-errno)))
+                (when write-timeout
+                  (##sys#thread-block-for-timeout!
+                   ##sys#current-thread
+                   (fx+ (##sys#fudge 16) write-timeout)))
+                (##sys#thread-block-for-i/o! ##sys#current-thread dst #f)
+                (%yield)
+                (when (##sys#slot ##sys#current-thread 13)
+                  (%error "write operation timed out"))
+                (loop bytes-left work-ptr)) ;retry
+               ((negative? result) #f)
+               (else
+                (loop (- bytes-left result) (pointer-offset work-ptr result))))))))
+    
+    (parameterize ((%current-chunk-size (kilobytes 512)))
+      (let loop ((offset 0.0))
+        (cond
+         ((= offset len) len)
+         (else
+          (let* ((next-chunk (%next-chunk-size len offset))
+                 (mem-file (map-file-to-memory #f next-chunk prot/read map/shared src offset))
+                 (write-timeout (write-timeout)))
+            (unless (send-chunk (memory-mapped-file-pointer mem-file) next-chunk write-timeout)
+              (unmap-file-from-memory mem-file)
+              (##sys#update-errno)
+              (%error "write-failed"))
+            (unmap-file-from-memory mem-file)
+            (loop (+ offset next-chunk))))))))
+  
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; SENDFILE(2)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  (define (impl:sendfile src dst len )
+    (set!  *last-selected-implementation* 'sendfile)
+    
+    (unless os-dep:sendfile-available?
+      (%error "sendfile is not available on this system"))
+    
+    (parameterize ((%current-chunk-size (inexact->exact (- (expt 2 (- %word-size 3)) 1))))
+      (let loop ((offset 0.0))
+        (cond
+         ((= offset len)  len)
+         (else
+          (let* ((next-chunk (%next-chunk-size len offset))
+                 (new-offset (%sendfile-implementation src dst offset next-chunk)))
+            (cond
+             ((eqv? -2.0 new-offset)  ; EAGAIN/EINTR
+              (when (write-timeout)
+                (##sys#thread-block-for-timeout!
+                 ##sys#current-thread
+                 (fx+ (##sys#fudge 16) (write-timeout))))
+              (##sys#thread-block-for-i/o! ##sys#current-thread dst #f)
+              (%yield)
+              (when (##sys#slot ##sys#current-thread 13)
+                (%error "write operation timed out"))
+              (loop offset))
+             ((negative? new-offset)
+              (##sys#update-errno)
+              (%error "sendfile failed"))
+             (else
+              (loop new-offset)))))))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;READ-WRITE-LOOP
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
+  (define (impl:read-write-loop/port src dst len)
+    (set!  *last-selected-implementation* 'read-write-loop)
+    
+    (let* ((buffsize (read-write-buffer-size))
+           (buffer (make-string buffsize)))
+      (let loop ((n len))
+        (if (not (positive? n))
+            len
+            (let* ((to-read (fxmin buffsize (inexact->exact n)))
+                   (read-bytes (cadr (file-read src to-read buffer))))
+              ;(display (substring buffer 0 (sub1 read-bytes)))
+              (display (substring buffer 0 read-bytes) dst)
+              (loop (- n read-bytes)))))))
+
+  
+  (define (impl:read-write-loop/fd src dst len)
+    (set!  *last-selected-implementation* 'read-write-loop)
+    
+    (let* ((buffsize (read-write-buffer-size))
+           (buffer (make-string buffsize))
+           (write-timeout (write-timeout))
+           (write/offset (foreign-lambda* int ((int dst) (c-string buff) (unsigned-integer offset) (unsigned-integer bytes))
+                                          "C_return(write(dst,buff + offset,bytes));"))
+           (write-bytes (lambda (size)
+                          (let loop ((left size) (offset 0))
+                            (let ((written-bytes (write/offset dst buffer offset left)))
+                              (cond
+                               ((zero? left) #t)
+                               ((and (negative? written-bytes) (= errno/again (##sys#update-errno)))
+                                (when write-timeout
+                                  (##sys#thread-block-for-timeout!
+                                   ##sys#current-thread
+                                   (fx+ (##sys#fudge 16) write-timeout)))
+                                (##sys#thread-block-for-i/o! ##sys#current-thread dst #f)
+                                (%yield)
+                                (when (##sys#slot ##sys#current-thread 13)
+                                  (%error "write operation timed out"))
+                                (loop left offset))
+                               ((negative? written-bytes)
+                                (##sys#update-errno)
+                                (%error "write failed"))
+                               (else (loop (fx- left written-bytes) (fx+ offset written-bytes)))))))))
+      (let loop ((n len))
+        (if (not (positive? n))
+            len
+            (let* ((to-read (fxmin buffsize (inexact->exact n)))
+                   (read-bytes (cadr (file-read src to-read buffer))))
+              (write-bytes read-bytes)
+              (loop (- n read-bytes)))))))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; The single interface procedure
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  (define (default-selector len)
+    (cond
+     ((< len (megabytes 1)) impl:read-write-loop/fd)
+     (os-dep:sendfile-available? impl:sendfile)
+     (os-dep:mmap-available? impl:mmapped)
+     (else impl:read-write-loop/fd)))
+  
+  
+  (define (port-has-fd? obj)
+    (unless (port? obj)
+      (%error "supplied argument is not a port"))
+    (handle-exceptions exn #f (port->fileno obj) #t))
+
+  (define (->fileno obj)
+    (cond
+     ((fixnum? obj) obj)
+     ((port? obj) (port->fileno obj))
+     (else (%error "supplied argument is neither port nor descriptor"))))
+  
+  ;;set to either 'sendfile 'mmapped 'read-write or 'nothing
+  (define force-implementation (make-parameter 'nothing))
+
+  (define implementation-selector (make-parameter default-selector))
+
+  (define (sendfile src dst)
+    (let ((size (file-size src)))
+      (if (and (port? dst) (not (port-has-fd? dst)))
+          (impl:read-write-loop/port src dst size)
+          (let ((src (->fileno src))
+                (dst (->fileno dst)))
+            (case (force-implementation)
+              ((sendfile)   (impl:sendfile src dst size))
+              ((mmapped)    (impl:mmapped src dst size))
+              ((read-write) (impl:read-write-loop/fd src dst size))
+              ((nothing)
+               (let ((impl ((implementation-selector) size)))
+                 (impl src dst size)))
+              (else
+               (%error "invalid implementation forced. Allowed values are (sendfile mmapped read-write nothing)")))))))
+;;module
+  
+)

File sendfile/tags/1.6.0/sendfile.setup

+(run (csc -s -d0 -O2 -j sendfile sendfile.scm sendfile-implementation.c))
+(run (csc -s -d0 -O2 sendfile.import.scm))
+(run (csc -c -d0 -O2 sendfile.scm sendfile-implementation.c -unit sendfile -o sendfile-static.o))
+(install-extension 
+  'sendfile
+  '("sendfile.so" "sendfile.import.so" "sendfile-static.o")
+  '((version "1.5.2")
+    (static "sendfile-static.o")
+    (documentation "sendfile.html")))

File sendfile/tags/1.6.0/tests/outfile.data

+Oct 18 19:46:26 notebox syslogd 1.4.1#20ubuntu4: restart.
+Oct 18 20:14:15 notebox kernel: [ 2407.784594] SoftMAC: Open Authentication completed with 00:13:49:a1:23:74
+Oct 18 20:36:18 notebox -- MARK --
+Oct 18 20:44:13 notebox kernel: [ 4206.316557] SoftMAC: Open Authentication completed with 00:13:49:a1:23:74
+Oct 18 20:56:18 notebox -- MARK --
+Oct 18 21:16:19 notebox -- MARK --
+Oct 18 21:36:19 notebox -- MARK --
+Oct 18 21:56:19 notebox -- MARK --
+Oct 18 22:00:42 notebox kernel: [ 8795.669578] agpgart: Putting AGP V2 device at 0000:00:0b.0 into 1x mode
+Oct 18 22:00:42 notebox kernel: [ 8795.669600] agpgart: Putting AGP V2 device at 0000:00:10.0 into 1x mode
+Oct 18 22:00:42 notebox kernel: [ 8795.678742] [drm] Setting GART location based on new memory map
+Oct 18 22:00:42 notebox kernel: [ 8795.678760] [drm] Can't use AGP base @0x00000000, won't fit
+Oct 18 22:00:42 notebox kernel: [ 8795.678775] [drm] Loading R300 Microcode
+Oct 18 22:00:42 notebox kernel: [ 8795.678856] [drm] writeback test succeeded in 1 usecs
+Oct 18 22:01:02 notebox exiting on signal 15
+Oct 19 20:10:30 notebox syslogd 1.4.1#20ubuntu4: restart.
+Oct 19 20:10:30 notebox kernel: Inspecting /boot/System.map-2.6.20-16-powerpc
+Oct 19 20:10:31 notebox kernel: Loaded 23102 symbols from /boot/System.map-2.6.20-16-powerpc.
+Oct 19 20:10:31 notebox kernel: Symbols match kernel version 2.6.20.
+Oct 19 20:10:31 notebox kernel: No module symbols loaded - kernel modules not enabled. 
+Oct 19 20:10:31 notebox kernel: [    0.000000] Using PowerMac machine description
+Oct 19 20:10:31 notebox kernel: [    0.000000] Total memory = 512MB; using 1024kB for hash table (at cff00000)
+Oct 19 20:10:31 notebox kernel: [    0.000000] Linux version 2.6.20-16-powerpc (root@royal) (gcc version 4.1.2 (Ubuntu 4.1.2-0ubuntu4)) #3 Thu Aug 30 23:43:24 UTC 2007 (Ubuntu 2.6.20-16.31-powerpc)
+Oct 19 20:10:31 notebox kernel: [    0.000000] Found initrd at 0xc1900000:0xc2056000
+Oct 19 20:10:31 notebox kernel: [    0.000000] Found UniNorth memory controller & host bridge @ 0xf8000000 revision: 0xd2
+Oct 19 20:10:31 notebox kernel: [    0.000000] Mapped at 0xfdfc0000
+Oct 19 20:10:31 notebox kernel: [    0.000000] Found a Intrepid mac-io controller, rev: 0, mapped at 0xfdf40000
+Oct 19 20:10:31 notebox kernel: [    0.000000] PowerMac motherboard: PowerBook G4 15"
+Oct 19 20:10:31 notebox kernel: [    0.000000] via-pmu: Server Mode is disabled
+Oct 19 20:10:31 notebox kernel: [    0.000000] PMU driver v2 initialized for Core99, firmware: 0c
+Oct 19 20:10:31 notebox kernel: [    0.000000] Found UniNorth PCI host bridge at 0x00000000f0000000. Firmware bus number: 0->1
+Oct 19 20:10:31 notebox kernel: [    0.000000] Found UniNorth PCI host bridge at 0x00000000f2000000. Firmware bus number: 0->1
+Oct 19 20:10:31 notebox kernel: [    0.000000] Found UniNorth PCI host bridge at 0x00000000f4000000. Firmware bus number: 0->1
+Oct 19 20:10:31 notebox kernel: [    0.000000] nvram: Checking bank 0...
+Oct 19 20:10:31 notebox kernel: [    0.000000] nvram: gen0=728, gen1=729
+Oct 19 20:10:31 notebox kernel: [    0.000000] nvram: Active bank is: 1
+Oct 19 20:10:31 notebox kernel: [    0.000000] nvram: OF partition at 0x410
+Oct 19 20:10:31 notebox kernel: [    0.000000] nvram: XP partition at 0x1020
+Oct 19 20:10:31 notebox kernel: [    0.000000] nvram: NR partition at 0x1120
+Oct 19 20:10:31 notebox kernel: [    0.000000] Zone PFN ranges:
+Oct 19 20:10:31 notebox kernel: [    0.000000]   DMA             0 ->   131072
+Oct 19 20:10:31 notebox kernel: [    0.000000]   Normal     131072 ->   131072
+Oct 19 20:10:31 notebox kernel: [    0.000000]   HighMem    131072 ->   131072
+Oct 19 20:10:31 notebox kernel: [    0.000000] early_node_map[1] active PFN ranges
+Oct 19 20:10:31 notebox kernel: [    0.000000]     0:        0 ->   131072
+Oct 19 20:10:31 notebox kernel: [    0.000000] Built 1 zonelists.  Total pages: 130048
+Oct 19 20:10:31 notebox kernel: [    0.000000] Kernel command line: root=/dev/hda3 ro quiet splash 
+Oct 19 20:10:31 notebox kernel: [    0.000000] mpic: Setting up MPIC " MPIC 1   " version 1.2 at 80040000, max 4 CPUs
+Oct 19 20:10:31 notebox kernel: [    0.000000] mpic: ISU size: 64, shift: 6, mask: 3f
+Oct 19 20:10:31 notebox kernel: [    0.000000] mpic: Initializing for 64 sources
+Oct 19 20:10:31 notebox kernel: [    0.000000] PID hash table entries: 2048 (order: 11, 8192 bytes)
+Oct 19 20:10:31 notebox kernel: [    0.000000] GMT Delta read from XPRAM: 0 minutes, DST: off
+Oct 19 20:10:31 notebox kernel: [   24.012898] Console: colour dummy device 80x25
+Oct 19 20:10:31 notebox kernel: [   24.013433] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
+Oct 19 20:10:31 notebox kernel: [   24.014167] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
+Oct 19 20:10:31 notebox kernel: [   24.045612] Memory: 506880k/524288k available (3220k kernel code, 16876k reserved, 120k data, 293k bss, 188k init)
+Oct 19 20:10:31 notebox kernel: [   24.116643] Security Framework v1.0.0 initialized
+Oct 19 20:10:31 notebox kernel: [   24.116666] SELinux:  Disabled at boot.
+Oct 19 20:10:31 notebox kernel: [   24.116701] Mount-cache hash table entries: 512
+Oct 19 20:10:31 notebox kernel: [   24.117050] device-tree: Duplicate name in /cpus/PowerPC,G4@0, renamed to "l2-cache#1"
+Oct 19 20:10:31 notebox kernel: [   24.119908] NET: Registered protocol family 16
+Oct 19 20:10:31 notebox kernel: [   24.120363] KeyWest i2c @0xf8001003 irq 42 /uni-n@f8000000/i2c@f8001000
+Oct 19 20:10:31 notebox kernel: [   24.120374]  channel 0 bus <multibus>
+Oct 19 20:10:31 notebox kernel: [   24.120379]  channel 1 bus <multibus>
+Oct 19 20:10:31 notebox kernel: [   24.120429] KeyWest i2c @0x80018000 irq 26 /pci@f2000000/mac-io@17/i2c@18000
+Oct 19 20:10:31 notebox kernel: [   24.120437]  channel 0 bus <multibus>
+Oct 19 20:10:31 notebox kernel: [   24.120457] PMU i2c /pci@f2000000/mac-io@17/via-pmu@16000/pmu-i2c
+Oct 19 20:10:31 notebox kernel: [   24.120465]  channel 1 bus <multibus>
+Oct 19 20:10:31 notebox kernel: [   24.120470]  channel 2 bus <multibus>
+Oct 19 20:10:31 notebox kernel: [   24.120618] PCI: Probing PCI hardware
+Oct 19 20:10:31 notebox kernel: [   24.123653] Can't get bus-range for /pci@f2000000/cardbus@13, assuming it starts at 0
+Oct 19 20:10:31 notebox kernel: [   24.123777] Apple USB OHCI 0001:10:18.0 disabled by firmware
+Oct 19 20:10:31 notebox kernel: [   24.123787] Apple USB OHCI 0001:10:19.0 disabled by firmware
+Oct 19 20:10:31 notebox kernel: [   24.128822] NET: Registered protocol family 8
+Oct 19 20:10:31 notebox kernel: [   24.128831] NET: Registered protocol family 20
+Oct 19 20:10:31 notebox kernel: [   24.129500] NET: Registered protocol family 2
+Oct 19 20:10:31 notebox kernel: [   24.160698] IP route cache hash table entries: 16384 (order: 4, 65536 bytes)
+Oct 19 20:10:31 notebox kernel: [   24.160989] TCP established hash table entries: 65536 (order: 6, 262144 bytes)
+Oct 19 20:10:31 notebox kernel: [   24.161487] TCP bind hash table entries: 32768 (order: 5, 131072 bytes)
+Oct 19 20:10:31 notebox kernel: [   24.161742] TCP: Hash tables configured (established 65536 bind 32768)
+Oct 19 20:10:31 notebox kernel: [   24.161750] TCP reno registered
+Oct 19 20:10:31 notebox kernel: [   24.172911] checking if image is initramfs... it is
+Oct 19 20:10:31 notebox kernel: [   25.608333] Freeing initrd memory: 7512k freed
+Oct 19 20:10:31 notebox kernel: [   25.609123] Thermal assist unit not available
+Oct 19 20:10:31 notebox kernel: [   25.609361] Registering PowerMac CPU frequency driver
+Oct 19 20:10:31 notebox kernel: [   25.609368] Low: 765 Mhz, High: 1249 Mhz, Boot: 765 Mhz
+Oct 19 20:10:31 notebox kernel: [   25.640806] audit: initializing netlink socket (disabled)
+Oct 19 20:10:31 notebox kernel: [   25.640828] audit(1192817397.628:1): initialized
+Oct 19 20:10:31 notebox kernel: [   25.640971] VFS: Disk quotas dquot_6.5.1
+Oct 19 20:10:31 notebox kernel: [   25.640997] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
+Oct 19 20:10:31 notebox kernel: [   25.641076] io scheduler noop registered
+Oct 19 20:10:31 notebox kernel: [   25.641082] io scheduler anticipatory registered
+Oct 19 20:10:31 notebox kernel: [   25.641086] io scheduler deadline registered
+Oct 19 20:10:31 notebox kernel: [   25.641098] io scheduler cfq registered (default)
+Oct 19 20:10:31 notebox kernel: [   25.641615] PCI: Enabling device 0000:00:10.0 (0006 -> 0007)
+Oct 19 20:10:31 notebox kernel: [   25.837344] radeonfb: Retrieved PLL infos from Open Firmware
+Oct 19 20:10:31 notebox kernel: [   25.837349] radeonfb: Reference=27.00 MHz (RefDiv=12) Memory=200.00 Mhz, System=300.00 MHz
+Oct 19 20:10:31 notebox kernel: [   25.837354] radeonfb: PLL min 12000 max 35000
+Oct 19 20:10:31 notebox kernel: [   25.937907] i2c_adapter i2c-2: unable to read EDID block.
+Oct 19 20:10:31 notebox kernel: [   26.093902] i2c_adapter i2c-2: unable to read EDID block.
+Oct 19 20:10:31 notebox kernel: [   26.249902] i2c_adapter i2c-2: unable to read EDID block.
+Oct 19 20:10:31 notebox kernel: [   26.605558] radeonfb: Monitor 1 type LCD found
+Oct 19 20:10:31 notebox kernel: [   26.605562] radeonfb: EDID probed
+Oct 19 20:10:31 notebox kernel: [   26.605564] radeonfb: Monitor 2 type no found
+Oct 19 20:10:31 notebox kernel: [   26.605636] radeonfb: Dynamic Clock Power Management enabled
+Oct 19 20:10:31 notebox kernel: [   26.638841] Console: switching to colour frame buffer device 160x53
+Oct 19 20:10:31 notebox kernel: [   26.661136] radeonfb: Backlight initialized (radeonbl0)
+Oct 19 20:10:31 notebox kernel: [   26.661141] radeonfb (0000:00:10.0): ATI Radeon NP 
+Oct 19 20:10:31 notebox kernel: [   26.695512] Generic RTC Driver v1.07
+Oct 19 20:10:31 notebox kernel: [   26.695575] Macintosh non-volatile memory driver v1.1
+Oct 19 20:10:31 notebox kernel: [   26.695694] mice: PS/2 mouse device common for all mice
+Oct 19 20:10:31 notebox kernel: [   26.696475] RAMDISK driver initialized: 16 RAM disks of 65536K size 1024 blocksize
+Oct 19 20:10:31 notebox kernel: [   26.696940] MacIO PCI driver attached to Intrepid chipset
+Oct 19 20:10:31 notebox kernel: [   26.698091] input: Macintosh mouse button emulation as /class/input/input0
+Oct 19 20:10:31 notebox kernel: [   26.698297] Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
+Oct 19 20:10:31 notebox kernel: [   26.698306] ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
+Oct 19 20:10:31 notebox kernel: [   26.698386] adb: starting probe task...
+Oct 19 20:10:31 notebox kernel: [   26.699663] PCI: Enabling device 0002:24:0d.0 (0000 -> 0002)
+Oct 19 20:10:31 notebox kernel: [   26.960489] ADB keyboard at 2, handler 1
+Oct 19 20:10:31 notebox kernel: [   26.960500] Detected ADB keyboard, type ISO, swapping keys.
+Oct 19 20:10:31 notebox kernel: [   26.960642] input: ADB keyboard as /class/input/input1
+Oct 19 20:10:31 notebox kernel: [   26.960739] input: ADB Powerbook buttons as /class/input/input2
+Oct 19 20:10:31 notebox kernel: [   26.975735] ADB mouse at 3, handler set to 4 (trackpad)
+Oct 19 20:10:31 notebox kernel: [   27.035532] input: ADB mouse as /class/input/input3
+Oct 19 20:10:31 notebox kernel: [   27.035573] adb: finished probe task...
+Oct 19 20:10:31 notebox kernel: [   27.716576] ide0: Found Apple UniNorth ATA-6 controller, bus ID 3, irq 39
+Oct 19 20:10:31 notebox kernel: [   28.004770] hda: TOSHIBA MK8025GAS, ATA DISK drive
+Oct 19 20:10:31 notebox kernel: [   28.676580] hda: Enabling Ultra DMA 5
+Oct 19 20:10:31 notebox kernel: [   28.677617] ide0 at 0xe1022000-0xe1022007,0xe1022160 on irq 39
+Oct 19 20:10:31 notebox kernel: [   29.696574] ide1: Found Apple KeyLargo ATA-3 controller, bus ID 0, irq 24
+Oct 19 20:10:31 notebox kernel: [   30.096750] hdc: MATSHITADVD-R UJ-816, ATAPI CD/DVD-ROM drive
+Oct 19 20:10:31 notebox kernel: [   30.432576] hdc: Enabling MultiWord DMA 2
+Oct 19 20:10:31 notebox kernel: [   30.433599] ide1 at 0xe1012000-0xe1012007,0xe1012160 on irq 24
+Oct 19 20:10:31 notebox kernel: [   30.433803] PowerMac i2c bus pmu 2 registered
+Oct 19 20:10:31 notebox kernel: [   30.433857] PowerMac i2c bus pmu 1 registered
+Oct 19 20:10:31 notebox kernel: [   30.433912] PowerMac i2c bus mac-io 0 registered
+Oct 19 20:10:31 notebox kernel: [   30.433976] PowerMac i2c bus uni-n 1 registered
+Oct 19 20:10:31 notebox kernel: [   30.434029] PowerMac i2c bus uni-n 0 registered
+Oct 19 20:10:31 notebox kernel: [   30.434154] TCP cubic registered
+Oct 19 20:10:31 notebox kernel: [   30.434163] NET: Registered protocol family 1
+Oct 19 20:10:31 notebox kernel: [   30.434296] input: PMU as /class/input/input4
+Oct 19 20:10:31 notebox kernel: [   30.434346] Registered led device: pmu-front-led
+Oct 19 20:10:31 notebox kernel: [   30.434357] Freeing unused kernel memory: 188k init
+Oct 19 20:10:31 notebox kernel: [   31.926664] Capability LSM initialized
+Oct 19 20:10:31 notebox kernel: [   33.398600] usbcore: registered new interface driver usbfs
+Oct 19 20:10:31 notebox kernel: [   33.398639] usbcore: registered new interface driver hub
+Oct 19 20:10:31 notebox kernel: [   33.398674] usbcore: registered new device driver usb
+Oct 19 20:10:31 notebox kernel: [   33.400676] Apple USB OHCI 0001:10:18.0 disabled by firmware
+Oct 19 20:10:31 notebox kernel: [   33.400692] Apple USB OHCI 0001:10:19.0 disabled by firmware
+Oct 19 20:10:31 notebox kernel: [   33.400709] PCI: Enabling device 0001:10:1a.0 (0000 -> 0002)
+Oct 19 20:10:31 notebox kernel: [   33.400726] ohci_hcd 0001:10:1a.0: OHCI Host Controller
+Oct 19 20:10:31 notebox kernel: [   33.400920] ohci_hcd 0001:10:1a.0: new USB bus registered, assigned bus number 1
+Oct 19 20:10:31 notebox kernel: [   33.400949] ohci_hcd 0001:10:1a.0: irq 29, io mem 0xa0003000
+Oct 19 20:10:31 notebox kernel: [   33.540906] usb usb1: configuration #1 chosen from 1 choice
+Oct 19 20:10:31 notebox kernel: [   33.540955] hub 1-0:1.0: USB hub found
+Oct 19 20:10:31 notebox kernel: [   33.540973] hub 1-0:1.0: 2 ports detected
+Oct 19 20:10:31 notebox kernel: [   33.644795] PCI: Enabling device 0001:10:1b.0 (0000 -> 0002)
+Oct 19 20:10:31 notebox kernel: [   33.644819] ohci_hcd 0001:10:1b.0: OHCI Host Controller
+Oct 19 20:10:31 notebox kernel: [   33.644854] ohci_hcd 0001:10:1b.0: new USB bus registered, assigned bus number 2
+Oct 19 20:10:31 notebox kernel: [   33.644885] ohci_hcd 0001:10:1b.0: irq 63, io mem 0xa0002000
+Oct 19 20:10:31 notebox kernel: [   33.855680] usb usb2: configuration #1 chosen from 1 choice
+Oct 19 20:10:31 notebox kernel: [   33.855743] hub 2-0:1.0: USB hub found
+Oct 19 20:10:31 notebox kernel: [   33.855760] hub 2-0:1.0: 3 ports detected
+Oct 19 20:10:31 notebox kernel: [   33.980030] PCI: Enabling device 0001:10:1b.1 (0000 -> 0002)
+Oct 19 20:10:31 notebox kernel: [   33.980057] ohci_hcd 0001:10:1b.1: OHCI Host Controller
+Oct 19 20:10:31 notebox kernel: [   33.980094] ohci_hcd 0001:10:1b.1: new USB bus registered, assigned bus number 3
+Oct 19 20:10:31 notebox kernel: [   33.980119] ohci_hcd 0001:10:1b.1: irq 63, io mem 0xa0001000
+Oct 19 20:10:31 notebox kernel: [   34.052335] usb usb3: configuration #1 chosen from 1 choice
+Oct 19 20:10:31 notebox kernel: [   34.052383] hub 3-0:1.0: USB hub found
+Oct 19 20:10:31 notebox kernel: [   34.052400] hub 3-0:1.0: 2 ports detected
+Oct 19 20:10:31 notebox kernel: [   34.104609] usb 1-1: new full speed USB device using ohci_hcd and address 2
+Oct 19 20:10:31 notebox kernel: [   34.165932] PCI: Enabling device 0001:10:1b.2 (0004 -> 0006)
+Oct 19 20:10:31 notebox kernel: [   34.165955] ehci_hcd 0001:10:1b.2: EHCI Host Controller
+Oct 19 20:10:31 notebox kernel: [   34.166018] ehci_hcd 0001:10:1b.2: new USB bus registered, assigned bus number 4
+Oct 19 20:10:31 notebox kernel: [   34.188599] ehci_hcd 0001:10:1b.2: irq 63, io mem 0xa0000000
+Oct 19 20:10:31 notebox kernel: [   34.188612] ehci_hcd 0001:10:1b.2: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
+Oct 19 20:10:31 notebox kernel: [   34.188766] usb usb4: configuration #1 chosen from 1 choice
+Oct 19 20:10:31 notebox kernel: [   34.188812] hub 4-0:1.0: USB hub found
+Oct 19 20:10:31 notebox kernel: [   34.188833] hub 4-0:1.0: 5 ports detected
+Oct 19 20:10:31 notebox kernel: [   34.293299] PCI: Enabling device 0002:24:0e.0 (0000 -> 0002)
+Oct 19 20:10:31 notebox kernel: [   34.344502] ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[40]  MMIO=[f5000000-f50007ff]  Max Packet=[4096]  IR/IT contexts=[8/8]
+Oct 19 20:10:31 notebox kernel: [   34.354921] sungem.c:v0.98 8/24/03 David S. Miller (davem@redhat.com)
+Oct 19 20:10:31 notebox kernel: [   34.379076] hda: max request size: 512KiB
+Oct 19 20:10:31 notebox kernel: [   34.391313] usb 1-1: configuration #1 chosen from 1 choice
+Oct 19 20:10:31 notebox kernel: [   34.421399] eth0: Sun GEM (PCI) 10/100/1000BaseT Ethernet 00:0a:95:d0:6b:40 
+Oct 19 20:10:31 notebox kernel: [   34.421407] eth0: Found Marvell 88E1111 PHY
+Oct 19 20:10:31 notebox kernel: [   34.462336] hda: 156301488 sectors (80026 MB), CHS=16383/255/63, UDMA(100)
+Oct 19 20:10:31 notebox kernel: [   34.491730] hda: cache flushes supported
+Oct 19 20:10:31 notebox kernel: [   34.491811]  hda: [mac] hda1 hda2 hda3 hda4 hda5 hda6
+Oct 19 20:10:31 notebox kernel: [   34.565477] hdc: ATAPI 24X DVD-ROM DVD-R CD-R/RW drive, 2048kB Cache, (U)DMA
+Oct 19 20:10:31 notebox kernel: [   34.565495] Uniform CD-ROM driver Revision: 3.20
+Oct 19 20:10:31 notebox kernel: [   34.806464] usbcore: registered new interface driver hiddev
+Oct 19 20:10:31 notebox kernel: [   34.844076] input: HID 05ac:1000 as /class/input/input5
+Oct 19 20:10:31 notebox kernel: [   34.844116] input: USB HID v1.11 Keyboard [HID 05ac:1000] on usb-0001:10:1a.0-1
+Oct 19 20:10:31 notebox kernel: [   34.864547] input: HID 05ac:1000 as /class/input/input6
+Oct 19 20:10:31 notebox kernel: [   34.864829] input: USB HID v1.11 Mouse [HID 05ac:1000] on usb-0001:10:1a.0-1
+Oct 19 20:10:31 notebox kernel: [   34.864853] usbcore: registered new interface driver usbhid
+Oct 19 20:10:31 notebox kernel: [   34.864860] drivers/usb/input/hid-core.c: v2.6:USB HID core driver
+Oct 19 20:10:31 notebox kernel: [   35.306904] Attempting manual resume
+Oct 19 20:10:31 notebox kernel: [   35.400756] kjournald starting.  Commit interval 5 seconds
+Oct 19 20:10:31 notebox kernel: [   35.400779] EXT3-fs: mounted filesystem with ordered data mode.
+Oct 19 20:10:31 notebox kernel: [   48.118937] Linux agpgart interface v0.102 (c) Dave Jones
+Oct 19 20:10:31 notebox kernel: [   48.142272] agpgart: Detected Apple UniNorth 2 chipset
+Oct 19 20:10:31 notebox kernel: [   48.142380] agpgart: configuring for size idx: 8
+Oct 19 20:10:31 notebox kernel: [   48.142444] agpgart: AGP aperture is 32M @ 0x0
+Oct 19 20:10:31 notebox kernel: [   49.433066] ieee80211: 802.11 data/management/control stack, git-1.1.13
+Oct 19 20:10:31 notebox kernel: [   49.433073] ieee80211: Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>
+Oct 19 20:10:31 notebox kernel: [   49.482642] bcm43xx driver
+Oct 19 20:10:31 notebox kernel: [   49.482831] PCI: Enabling device 0001:10:12.0 (0004 -> 0006)
+Oct 19 20:10:31 notebox kernel: [   50.165174] Yenta: CardBus bridge found at 0001:10:13.0 [0000:0000]
+Oct 19 20:10:31 notebox kernel: [   50.165208] PCI: Bus 17, cardbus bridge: 0001:10:13.0
+Oct 19 20:10:31 notebox kernel: [   50.165212]   IO window: 00001000-000011ff
+Oct 19 20:10:31 notebox kernel: [   50.165218]   IO window: 00001400-000015ff
+Oct 19 20:10:31 notebox kernel: [   50.165224]   PREFETCH window: 90000000-9fffffff
+Oct 19 20:10:31 notebox kernel: [   50.165230]   MEM window: f3000000-f33fffff
+Oct 19 20:10:31 notebox kernel: [   50.165238] Yenta: Enabling burst memory read transactions
+Oct 19 20:10:31 notebox kernel: [   50.165244] Yenta: Using CSCINT to route CSC interrupts to PCI
+Oct 19 20:10:31 notebox kernel: [   50.165247] Yenta: Routing CardBus interrupts to PCI
+Oct 19 20:10:31 notebox kernel: [   50.165253] Yenta TI: socket 0001:10:13.0, mfunc 0x00001002, devctl 0x60
+Oct 19 20:10:31 notebox kernel: [   50.268616] Yenta: ISA IRQ mask 0x0000, PCI irq 53
+Oct 19 20:10:31 notebox kernel: [   50.268624] Socket status: 30000007
+Oct 19 20:10:31 notebox kernel: [   50.268631] pcmcia: parent PCI bridge I/O window: 0x0 - 0x7fffff
+Oct 19 20:10:31 notebox kernel: [   50.268637] pcmcia: parent PCI bridge Memory window: 0xf3000000 - 0xf3ffffff
+Oct 19 20:10:31 notebox kernel: [   50.268642] pcmcia: parent PCI bridge Memory window: 0x80000000 - 0xafffffff
+Oct 19 20:10:31 notebox kernel: [   51.317258] pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)
+Oct 19 20:10:31 notebox kernel: [   51.317356] ttyS0 at MMIO 0x80013020 (irq = 22) is a Z85c30 ESCC - Serial port
+Oct 19 20:10:31 notebox kernel: [   51.317718] ttyS1 at MMIO 0x80013000 (irq = 23) is a Z85c30 ESCC - Serial port
+Oct 19 20:10:31 notebox kernel: [   53.709622] SoftMAC: Open Authentication completed with 00:13:49:a1:23:74
+Oct 19 20:10:31 notebox kernel: [   53.834865] NET: Registered protocol family 10
+Oct 19 20:10:31 notebox kernel: [   53.834992] lo: Disabled Privacy Extensions
+Oct 19 20:10:31 notebox kernel: [   53.988707] fuse init (API version 7.8)
+Oct 19 20:10:31 notebox kernel: [   54.736645] input: PowerMac Beep as /class/input/input7
+Oct 19 20:10:31 notebox kernel: [   54.841413] apm_emu: APM Emulation 0.5 initialized.
+Oct 19 20:10:31 notebox kernel: [   54.924866] SCSI subsystem initialized
+Oct 19 20:10:31 notebox kernel: [   55.087530] adt746x: version 1 (supported)
+Oct 19 20:10:31 notebox kernel: [   55.087539] adt746x: Thermostat bus: 1, address: 0x2e, limit_adjust: 0, fan_speed: -1
+Oct 19 20:10:31 notebox kernel: [   55.087545] sensor 0: CPU/INTREPID BOTTOMSIDE
+Oct 19 20:10:31 notebox kernel: [   55.087549] sensor 1: CPU BOTTOMSIDE
+Oct 19 20:10:31 notebox kernel: [   55.087552] sensor 2: PWR SUPPLY BOTTOMSIDE
+Oct 19 20:10:31 notebox kernel: [   55.088002] adt746x: ADT7460 initializing
+Oct 19 20:10:31 notebox kernel: [   55.090126] adt746x: Lowering max temperatures from 81, 80, 87 to 70, 50, 70
+Oct 19 20:10:31 notebox kernel: [   55.288646] Adding 1509100k swap on /dev/disk/by-uuid/ecca67d1-6dba-4f84-ade6-4308e8b416eb.  Priority:-1 extents:1 across:1509100k
+Oct 19 20:10:31 notebox kernel: [   55.298771] EXT3 FS on hda3, internal journal
+Oct 19 20:10:31 notebox kernel: [   55.634455] kjournald starting.  Commit interval 5 seconds
+Oct 19 20:10:31 notebox kernel: [   55.634586] EXT3 FS on hda5, internal journal
+Oct 19 20:10:31 notebox kernel: [   55.634594] EXT3-fs: mounted filesystem with ordered data mode.
+Oct 19 20:10:31 notebox kernel: [   55.677032] kjournald starting.  Commit interval 5 seconds
+Oct 19 20:10:31 notebox kernel: [   55.677148] EXT3 FS on hda6, internal journal
+Oct 19 20:10:31 notebox kernel: [   55.677156] EXT3-fs: mounted filesystem with ordered data mode.
+Oct 19 20:10:35 notebox dhcdbd: Started up.
+Oct 19 20:10:35 notebox kernel: [   63.058818] ADDRCONF(NETDEV_UP): eth0: link is not ready
+Oct 19 20:10:39 notebox kernel: [   66.422605] [drm] Initialized drm 1.1.0 20060810
+Oct 19 20:10:39 notebox kernel: [   66.445959] [drm] Initialized radeon 1.25.0 20060524 on minor 0
+Oct 19 20:10:39 notebox kernel: [   66.894325] lp: driver loaded but no devices found
+Oct 19 20:10:39 notebox kernel: [   67.047198] ppdev: user-space parallel port driver
+Oct 19 20:10:40 notebox kernel: [   67.658349] agpgart: Putting AGP V2 device at 0000:00:0b.0 into 1x mode
+Oct 19 20:10:40 notebox kernel: [   67.658505] agpgart: Putting AGP V2 device at 0000:00:10.0 into 1x mode
+Oct 19 20:10:40 notebox kernel: [   67.713230] [drm] Setting GART location based on new memory map
+Oct 19 20:10:40 notebox kernel: [   67.713244] [drm] Can't use AGP base @0x00000000, won't fit
+Oct 19 20:10:40 notebox kernel: [   67.713254] [drm] Loading R300 Microcode
+Oct 19 20:10:40 notebox kernel: [   67.713310] [drm] writeback test succeeded in 1 usecs
+Oct 19 20:10:41 notebox hpiod: 1.7.3 accepting connections at 2208... 
+Oct 19 20:10:52 notebox kernel: [   79.408899] ondemand governor failed to load due to too long transition latency
+Oct 19 20:10:52 notebox kernel: [   80.020333] Bluetooth: Core ver 2.11
+Oct 19 20:10:52 notebox kernel: [   80.020428] NET: Registered protocol family 31
+Oct 19 20:10:52 notebox kernel: [   80.020432] Bluetooth: HCI device and connection manager initialized
+Oct 19 20:10:52 notebox kernel: [   80.020438] Bluetooth: HCI socket layer initialized
+Oct 19 20:10:52 notebox kernel: [   80.264344] Bluetooth: L2CAP ver 2.8
+Oct 19 20:10:52 notebox kernel: [   80.264354] Bluetooth: L2CAP socket layer initialized
+Oct 19 20:10:52 notebox kernel: [   80.286122] usb 1-1: USB disconnect, address 2
+Oct 19 20:10:53 notebox kernel: [   80.521922] Bluetooth: RFCOMM socket layer initialized
+Oct 19 20:10:53 notebox kernel: [   80.521949] Bluetooth: RFCOMM TTY layer initialized
+Oct 19 20:10:53 notebox kernel: [   80.521952] Bluetooth: RFCOMM ver 1.8
+Oct 19 20:10:53 notebox kernel: [   80.628600] usb 1-1: new full speed USB device using ohci_hcd and address 3
+Oct 19 20:10:53 notebox kernel: [   80.885292] usb 1-1: configuration #1 chosen from 1 choice
+Oct 19 20:10:54 notebox kernel: [   81.588825] Bluetooth: HCI USB driver ver 2.9
+Oct 19 20:10:54 notebox kernel: [   81.598342] usbcore: registered new interface driver hci_usb
+Oct 19 20:16:54 notebox syslogd 1.4.1#20ubuntu4: restart.
+Oct 19 20:30:31 notebox -- MARK --
+Oct 19 20:50:24 notebox gconfd (closure-5712): starting (version 2.18.0.1), pid 5712 user 'closure'
+Oct 19 20:50:24 notebox gconfd (closure-5712): Resolved address "xml:readonly:/etc/gconf/gconf.xml.mandatory" to a read-only configuration source at position 0
+Oct 19 20:50:24 notebox gconfd (closure-5712): Resolved address "xml:readwrite:/home/closure/.gconf" to a writable configuration source at position 1
+Oct 19 20:50:24 notebox gconfd (closure-5712): Resolved address "xml:readonly:/etc/gconf/gconf.xml.defaults" to a read-only configuration source at position 2
+Oct 19 20:50:24 notebox gconfd (closure-5712): Resolved address "xml:readonly:/var/lib/gconf/debian.defaults" to a read-only configuration source at position 3
+Oct 19 20:50:24 notebox gconfd (closure-5712): Resolved address "xml:readonly:/var/lib/gconf/defaults" to a read-only configuration source at position 4
+Oct 19 20:50:54 notebox gconfd (closure-5712): GConf server is not in use, shutting down.
+Oct 19 20:50:54 notebox gconfd (closure-5712): Exiting

File sendfile/tags/1.6.0/tests/sicp.pdf

+testfile.jpg

File sendfile/tags/1.6.0/tests/test-run.scm

+(use test tcp posix (srfi 4))
+(load "test-utils")
+(load "../sendfile.so")
+(import sendfile)
+
+(newline)
+(display "starting server on port 5555")
+(define server-pid (process-fork server))
+
+(unless (wait-for-server 3)
+  (display "could not start server!!!!")
+  (exit 0))
+
+;;wait 5 seconds to prevent from weird bug on some machines
+(newline)
+(display "stand by ....")
+(flush-output)
+(sleep 4)
+
+
+(test-group "read-write-loop"
+      (test "send"
+       test-file-size
+       (with-prepared-environment test-file
+        (lambda (in out)
+          (impl:read-write-loop/fd in out test-file-size))))
+      (sleep 1)
+      (test "verify"
+       test-file-checksum
+       (compute-file-checksum test-file-out)))
+
+(test-group "read-write-loop (ports-only)"
+      (test "send"
+        test-file-size
+        (with-prepared-environment test-file
+         (lambda (in out)
+             (impl:read-write-loop/port in out test-file-size)) #t))
+      (sleep 1)
+      (test "verify"
+       test-file-checksum
+       (compute-file-checksum test-file-out)))
+
+
+(if os-dep:sendfile-available?
+    (test-group "sendfile-impl"
+                (test "send"
+                      test-file-size 
+                      (with-prepared-environment test-file
+                       (lambda (in out)
+                         (impl:sendfile in out test-file-size))))
+                 (sleep 1)
+                 (test "verify"
+                       test-file-checksum
+                       (compute-file-checksum test-file-out))))
+
+(if os-dep:mmap-available?
+    (test-group "mmapped io"
+