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