Subject: [clisp-list] one must not use FFI to read() into Lisp arrays (was: read-line)

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Tue Jan 21 08:43:07 2003

Michael Koehne wrote:
>   So I think I need  some low level
> (system-read stream array) and (system-write stream array)
>  both returning an integer. I'll next read into ffi.

I should have mentioned this earlier, when we discussed READ-SOME/PARTIAL a while ago.
The FFI is not a reliable solution for writing into Lisp arrays.

Witness the code in unixaux.d *and* in win32aux.d:
  local int lowlevel_sock_read (SOCKET fd, void* buf, int nbyte)
      #if (defined(GENERATIONAL_GC) && defined(SPVW_MIXED)) || defined(SELFMADE_MMAP)
      # Must adjust the memory permissions before calling read().
      # - On SunOS4 a missing write permission causes the read() call to hang
      #   in an endless loop.
      # - With Linux 2.2 the read call returns with errno=EFAULT, but with
      #   unpredictable side side effects: If fd refers to a socket, some of
      #   the socket data gets lost.
      # The SunOS4 behaviour is clearly a bug, but the Linux 2.2 behaviour is
      # not. The POSIX spec says that read() returns with errno=EFAULT, but
      # does not specify anything about possible side effects.
      handle_fault_range(PROT_READ_WRITE,(aint)buf,(aint)buf+nbyte);
      #endif
      ... now recv() can be called on that buf[fer]

One's own FFI code obviously would not invoke handle_fault_range() to prepare the call to read() or write(). As a result, the code may fail on some systems.

Maybe you wouldn't bother because it may seem to work for you durign testing, but IMHO CLISP should provide portable ways of doing the reading reliably.

Of course, you could roll your own i/o *and* buffers with the FFI and not care about generational GC.

Hmm, this may also affect authors of hand-written modules.

Regards,
	Jorg Hohle.