Patch: fd_type_socket.diff (5 in series)

Martin Wilck Martin.Wilck at fujitsu-siemens.com
Tue Apr 23 13:37:20 CDT 2002


Patch: fd_type_socket.diff (5 in series)

Fix ReadFile() semantics when reading asynchronously on sockets.

Overlapped ReadFile() on sockets must signal success if a positive number of
bytes has been read. The current implementation pends until its buffer is full,
which is not the behaviour applications expect (Example: Hamster local news/pop3 server).

To change the semantics for sockets requires that ReadFile() knows it is
working on a socket.

Patch against: CVS 2002/04/23, with previous patches in series applied.

Modified files:
        files:          file.c (add fd_type field to async_fileio struct and use it to
                                figure out whether reading from a socket)
        include:        server_protocol.h (define FD_TYPE_SOCKET)
        server:         protocol.def (dito)
                        sock.c (set type to FD_TYPE_SOCKET)

diff -ruNX ignore CVS/wine/files/file.c TMP/wine/files/file.c
--- CVS/wine/files/file.c	Tue Apr 23 18:14:21 2002
+++ TMP/wine/files/file.c	Tue Apr 23 18:14:09 2002
@@ -115,6 +115,7 @@
     LPOVERLAPPED_COMPLETION_ROUTINE  completion_func;
     char                             *buffer;
     int                              count;
+    enum fd_type                     fd_type;
 } async_fileio;

 static DWORD fileio_get_async_status (const struct async_private *ovp)
@@ -1459,10 +1460,15 @@

     /* check to see if the data is ready (non-blocking) */

-    result = pread (ovp->fd, &fileio->buffer[already], fileio->count - already,
-                    OVERLAPPED_OFFSET (lpOverlapped) + already);
-    if ((result < 0) && (errno == ESPIPE))
+    if ( fileio->fd_type == FD_TYPE_SOCKET )
         result = read (ovp->fd, &fileio->buffer[already], fileio->count - already);
+    else
+    {
+        result = pread (ovp->fd, &fileio->buffer[already], fileio->count - already,
+                        OVERLAPPED_OFFSET (lpOverlapped) + already);
+        if ((result < 0) && (errno == ESPIPE))
+            result = read (ovp->fd, &fileio->buffer[already], fileio->count - already);
+    }

     if ( (result<0) && ((errno == EAGAIN) || (errno == EINTR)))
     {
@@ -1482,10 +1488,10 @@
     lpOverlapped->InternalHigh += result;
     TRACE("read %d more bytes %ld/%d so far\n",result,lpOverlapped->InternalHigh,fileio->count);

-    if(lpOverlapped->InternalHigh < fileio->count)
-        r = STATUS_PENDING;
-    else
+    if(lpOverlapped->InternalHigh >= fileio->count || fileio->fd_type == FD_TYPE_SOCKET )
         r = STATUS_SUCCESS;
+    else
+        r = STATUS_PENDING;

 async_end:
     lpOverlapped->Internal = r;
@@ -1544,6 +1550,7 @@
     ovp->count = bytesToRead;
     ovp->completion_func = lpCompletionRoutine;
     ovp->buffer = buffer;
+    ovp->fd_type = type;

     return !register_new_async (&ovp->async);

@@ -1683,10 +1690,15 @@

     /* write some data (non-blocking) */

-    result = pwrite(ovp->fd, &fileio->buffer[already], fileio->count - already,
-                    OVERLAPPED_OFFSET (lpOverlapped) + already);
-    if ((result < 0) && (errno == ESPIPE))
+    if ( fileio->fd_type == FD_TYPE_SOCKET )
         result = write(ovp->fd, &fileio->buffer[already], fileio->count - already);
+    else
+    {
+        result = pwrite(ovp->fd, &fileio->buffer[already], fileio->count - already,
+                    OVERLAPPED_OFFSET (lpOverlapped) + already);
+        if ((result < 0) && (errno == ESPIPE))
+            result = write(ovp->fd, &fileio->buffer[already], fileio->count - already);
+    }

     if ( (result<0) && ((errno == EAGAIN) || (errno == EINTR)))
     {
@@ -1727,8 +1739,8 @@
     int flags;
     enum fd_type type;

-    TRACE("file %d to buf %p num %ld %p func %p stub\n",
-	  hFile, buffer, bytesToWrite, overlapped, lpCompletionRoutine);
+    TRACE("file %d to buf %p num %ld %p func %p handle %d\n",
+	  hFile, buffer, bytesToWrite, overlapped, lpCompletionRoutine, hEvent);

     if (overlapped == NULL)
     {
@@ -1766,6 +1778,7 @@
     ovp->buffer = (LPVOID) buffer;
     ovp->count = bytesToWrite;
     ovp->completion_func = lpCompletionRoutine;
+    ovp->fd_type = type;

     return !register_new_async (&ovp->async);

diff -ruNX ignore CVS/wine/include/wine/server_protocol.h TMP/wine/include/wine/server_protocol.h
--- CVS/wine/include/wine/server_protocol.h	Tue Apr 23 17:53:34 2002
+++ TMP/wine/include/wine/server_protocol.h	Tue Apr 23 18:14:09 2002
@@ -791,6 +791,7 @@
     FD_TYPE_INVALID,
     FD_TYPE_DEFAULT,
     FD_TYPE_CONSOLE,
+    FD_TYPE_SOCKET,
     FD_TYPE_SMB
 };
 #define FD_FLAG_OVERLAPPED 0x01
diff -ruNX ignore CVS/wine/server/protocol.def TMP/wine/server/protocol.def
--- CVS/wine/server/protocol.def	Tue Apr 23 17:53:34 2002
+++ TMP/wine/server/protocol.def	Tue Apr 23 18:14:09 2002
@@ -608,6 +608,7 @@
     FD_TYPE_INVALID,
     FD_TYPE_DEFAULT,
     FD_TYPE_CONSOLE,
+    FD_TYPE_SOCKET,
     FD_TYPE_SMB
 };
 #define FD_FLAG_OVERLAPPED 0x01
diff -ruNX ignore CVS/wine/server/sock.c TMP/wine/server/sock.c
--- CVS/wine/server/sock.c	Tue Apr 23 17:53:34 2002
+++ TMP/wine/server/sock.c	Tue Apr 23 18:14:09 2002
@@ -421,7 +421,7 @@
     if (sock->flags & WSA_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED;
     if ( !(sock->state & FD_READ ) )  *flags |= FD_FLAG_RECV_SHUTDOWN;
     if ( !(sock->state & FD_WRITE ) ) *flags |= FD_FLAG_SEND_SHUTDOWN;
-    return FD_TYPE_DEFAULT;
+    return FD_TYPE_SOCKET;
 }

 static void sock_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)







More information about the wine-patches mailing list