Oct 14, 2008, 2:00:40 AM (11 years ago)

Stop wrapping (pseudo) file-descriptors around Windows file handlers;
there seem to be cases where this definitely loses, because the MSVCRT
runtime tries to flush buffers associated with (e.g.) a listening socket
when it's closed, and we often have to do I/O in Windows-specific ways
and can't always use the C runtime, anyway.

Handles are (depending on which function you're dealing with) either
pointers or pointer-sized integers; they can be used interchangably
with ints on Win32, but porting this change to Win64 may require some
changes (in l1-io.lisp, in the PIPE function, perhaps elsewhere.)

Supporting this requires some changss in the kernel (mostly in
windows-calls.c) To bootstrap it, most of the I/O functions in
that file assume that very small integers [0 .. 31] are fds wrapped
around a handle and that anything larger is the handle itself. All
of the actual work done by those functions is done on the handle,
without involving the C runtime.

I'll check in a win32 kernel and image in a few minutes. Mixing
older kernels/images won't work, but I don't want to change the
kernel/image compatibility stuff until this is further along.

SLIME sort of works, but not very reliably yet.

1 edited


  • trunk/source/level-1/linux-files.lisp

    r10897 r11081  
    408 (defun %file-kind (mode)
     408(defun %file-kind (mode &optional fd)
     409  (declare (ignorable fd))
    409410  (when mode
    410411    (let* ((kind (logand mode #$S_IFMT)))
    413414            #-windows-target
    414415            ((eql kind #$S_IFLNK) :link)
    415             ((eql kind #$S_IFIFO) :pipe)
     416            ((eql kind #$S_IFIFO)
     417             #-windows-target :pipe
     418             ;; Windows doesn't seem to be able to distinguish between
     419             ;; sockets and pipes.  Since this function is currently
     420             ;; (mostly) used for printing streams and since we've
     421             ;; already done something fairly expensive (stat, fstat)
     422             ;; to get here.  try to distinguish between pipes and
     423             ;; sockets by calling #_getsockopt.  If that succeeds,
     424             ;; we've got a socket; otherwise, we're probably got a pipe.
     425             #+windows-target (rlet ((ptype :int)
     426                                     (plen :int 4))
     427                                (if (and fd (eql 0 (#_getsockopt fd #$SOL_SOCKET #$SO_TYPE  ptype plen)))
     428                                    :socket
     429                                    :pipe)))
    416430            #-windows-target
    417431            ((eql kind #$S_IFSOCK) :socket)
    425439  (if (isatty fd)
    426440    :tty
    427     (%file-kind (nth-value 1 (%fstat fd)))))
     441    (%file-kind (nth-value 1 (%fstat fd)) fd)))
    499513(defun fd-dup (fd &key direction inheritable)
     514  (declare (ignore direction))
    500515  (rlet ((handle #>HANDLE))
    501516    (#_DuplicateHandle (#_GetCurrentProcess)
    502                        (#__get_osfhandle fd)
     517                       fd
    503518                       (#_GetCurrentProcess)
    504519                       handle
    505520                       0
    506521                       (if inheritable #$TRUE #$FALSE)
    507                        #$DUPLICATE_SAME_ACCESS)
    508     (#__open_osfhandle (pref handle #>HANDLE) (case direction
    509                                                 (:input #$O_RDONLY)
    510                                                 (:output #$O_WRONLY)
    511                                                 (t #$O_RDWR)))))
     522                       #$DUPLICATE_SAME_ACCESS)))
    514525(defun fd-fsync (fd)
    515   #+windows-target (progn fd 0)
     526  #+windows-target (#_FlushFileBuffers fd)
    516527  #-windows-target
    517528  (int-errno-call (#_fsync fd)))
    16081619      (setf (pref si #>STARTUPINFO.wShowWindow) #$SW_HIDE)
    16091620      (setf (pref si #>STARTUPINFO.hStdInput)
    1610             (%int-to-ptr (#__get_osfhandle (or new-in 0))))
     1621            (if new-in
     1622              (%int-to-ptr new-in)
     1623              (#_GetStdHandle #$STD_INPUT_HANDLE)))
    16111624      (setf (pref si #>STARTUPINFO.hStdOutput)
    1612             (%int-to-ptr (#__get_osfhandle (or new-out 1))))
     1625            (if new-out
     1626              (%int-to-ptr new-out)
     1627              (#_GetStdHandle #$STD_OUTPUT_HANDLE)))
    16131628      (setf (pref si #>STARTUPINFO.hStdError)
    1614             (%int-to-ptr (#__get_osfhandle (or new-err 2))))
     1629            (if new-err
     1630              (%int-to-ptr new-err)
     1631              (#_GetStdHandle #$STD_ERROR_HANDLE)))
    16151632      (if (zerop (#_CreateProcessW (%null-ptr)
    16161633                                   command
Note: See TracChangeset for help on using the changeset viewer.