Patch 2 in the series, a repost of my patch to wine-devel of 2002-01-03,
Now incremental to the previous patch (i.e., also relies on Mike's
patches being applied).

Patch file:     002-fd_type.diff
Purpose:        More general approach to file descriptor types and flags.
Created:        2002-01-07
Applies:        CVS 2002-01-07
                (with 001-file_overlapped.diff applied)

If overlapped IO is to be allowed / implemented for several different types
of file descriptors (regular files, serial ports, pipes, sockets, ...), a
more general scheme must be found to obtain file descriptor types and flags
or capabilities. The current scheme treats FD_TYPE_OVERLAPPED as a special
type, making it impossible to distinguish between e.g. overlapped files and
overlapped sockets.

This patch fixes this behaviour by modifying the meaning of return value
of the get_file_info() function.

** NOTE ON BUILDING:    tools/make_requests must be run **
**                      after applying this patch       **

server/protocol.def:
        The lowest byte of the type value is reserved for the type itself
        (macro FD_TYPE (type)the rest is available for miscellaneous flags.

        New FD types: FD_TYPE_DEVICE, FD_TYPE_NAMED_PIPE, FD_TYPE_PIPE,
                FD_TYPE_SERIAL, FD_TYPE_SOCKET.
        New FD flags (were formerly FD types):
                FD_TYPE_FLAG_OVERLAPPED: The fd uses overlapped I/O.
                FD_TYPE_FLAG_TIMEOUT: The fd applies a timeout on
                        its I/O operations
        New test macros: FD_TYPE_IS_OVERLAPPED (type),
                FD_TYPE_HAS_TIMEOUT (type)

server/device.c:
        device_get_info():
                return FD_TYPE_DEVICE.
server/file.c:
        file_get_info():
                set FD_TYPE_FLAG_OVERLAPPED on overlapped files.
server/named_pipe.c:
        named_pipe_get_info():
                return FD_TYPE_NAMED_PIPE.
server/pipe.c:
        named_pipe_get_info():
                return FD_TYPE_PIPE.
server/serial.c:
        serial_get_info():
                return FD_TYPE_SERIAL, account for OVERLAPPED and
                TIMEOUT flags.
server/serial.c:
        sock_get_info():
                return FD_TYPE_SOCKET.

files/file.c:
        ReadFile():
                Replace FD_TYPE_XYZ dependent switch statement
                with an equivalent if/elseif construct which
                will allow a morte fine-grained destinction
                of fd types and flags in the future.
        WriteFile():
                dito.

Martin Wilck <[EMAIL PROTECTED]>

diff -ruX diffignore CVS/wine/files/file.c MW/wine/files/file.c
--- CVS/wine/files/file.c       Mon Jan  7 16:04:31 2002
+++ MW/wine/files/file.c        Mon Jan  7 16:00:33 2002
@@ -1467,9 +1467,8 @@

     unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type );

-    switch (type)
+    if ( FD_TYPE_IS_OVERLAPPED (type) )
     {
-    case FD_TYPE_OVERLAPPED:
        if (unix_handle == -1) return FALSE;
         if ( (overlapped==NULL) || NtResetEvent( overlapped->hEvent, NULL ) )
         {
@@ -1512,15 +1511,21 @@
         /* fail on return, with ERROR_IO_PENDING */
         SetLastError(ERROR_IO_PENDING);
         return FALSE;
+    }

-    case FD_TYPE_CONSOLE:
+    else if ( FD_TYPE (type) == FD_TYPE_CONSOLE )
+    {
        return ReadConsoleA(hFile, buffer, bytesToRead, bytesRead, NULL);
+    }

-    case FD_TYPE_TIMEOUT:
+    else if ( FD_TYPE_HAS_TIMEOUT (type) )
+    {
         close(unix_handle);
         return FILE_TimeoutRead(hFile, buffer, bytesToRead, bytesRead);
+    }

-    default:
+    else
+    {
        /* normal unix files */
        if (unix_handle == -1)
            return FALSE;
@@ -1530,7 +1535,6 @@
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
-       break;
     }

     /* code for synchronous reads */
@@ -1689,9 +1693,8 @@

     unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type );

-    switch (type)
+    if ( FD_TYPE_IS_OVERLAPPED (type) )
     {
-    case FD_TYPE_OVERLAPPED:
        if (unix_handle == -1) return FALSE;
         if ( (overlapped==NULL) || NtResetEvent( overlapped->hEvent, NULL ) )
         {
@@ -1741,11 +1744,17 @@
         SetLastError(ERROR_IO_PENDING);
         return FALSE;

-    case FD_TYPE_CONSOLE:
+    }
+
+    else if ( FD_TYPE (type) == FD_TYPE_CONSOLE )
+    {
         TRACE("%d %s %ld %p %p\n", hFile, debugstr_an(buffer, bytesToWrite), 
bytesToWrite,
              bytesWritten, overlapped );
        return WriteConsoleA(hFile, buffer, bytesToWrite, bytesWritten, NULL);
-    default:
+    }
+
+    else
+    {
        if (unix_handle == -1)
            return FALSE;
     }
diff -ruX diffignore CVS/wine/server/device.c MW/wine/server/device.c
--- CVS/wine/server/device.c    Mon Jan  7 15:45:26 2002
+++ MW/wine/server/device.c     Mon Jan  7 16:00:33 2002
@@ -83,7 +83,7 @@
         reply->index_low   = 0;
         reply->serial      = 0;
     }
-    return FD_TYPE_DEFAULT;
+    return FD_TYPE_DEVICE;
 }

 /* create a device */
diff -ruX diffignore CVS/wine/server/file.c MW/wine/server/file.c
--- CVS/wine/server/file.c      Mon Jan  7 15:58:22 2002
+++ MW/wine/server/file.c       Mon Jan  7 16:00:33 2002
@@ -308,6 +308,7 @@
 {
     struct stat st;
     struct file *file = (struct file *)obj;
+    int fd_type = FD_TYPE_DEFAULT;
     assert( obj->ops == &file_ops );

     if (reply)
@@ -342,9 +343,10 @@
     }

     if (file->flags & FILE_FLAG_OVERLAPPED)
-       return FD_TYPE_OVERLAPPED;
+       fd_type |= FD_TYPE_FLAG_OVERLAPPED;
+
+    return fd_type;

-    return FD_TYPE_DEFAULT;
 }

 static struct async_queue *file_queue_async(struct object *obj, struct async *async, 
int type, int count)
diff -ruX diffignore CVS/wine/server/named_pipe.c MW/wine/server/named_pipe.c
--- CVS/wine/server/named_pipe.c        Mon Jan  7 15:45:26 2002
+++ MW/wine/server/named_pipe.c Mon Jan  7 16:00:33 2002
@@ -197,7 +197,7 @@
         reply->index_low   = 0;
         reply->serial      = 0;
     }
-    return FD_TYPE_DEFAULT;
+    return FD_TYPE_NAMED_PIPE;
 }

 static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
diff -ruX diffignore CVS/wine/server/pipe.c MW/wine/server/pipe.c
--- CVS/wine/server/pipe.c      Mon Jan  7 15:45:26 2002
+++ MW/wine/server/pipe.c       Mon Jan  7 16:00:33 2002
@@ -140,7 +140,7 @@
         reply->index_low   = 0;
         reply->serial      = 0;
     }
-    return FD_TYPE_DEFAULT;
+    return FD_TYPE_PIPE;
 }

 static void pipe_destroy( struct object *obj )
diff -ruX diffignore CVS/wine/server/protocol.def MW/wine/server/protocol.def
--- CVS/wine/server/protocol.def        Mon Jan  7 15:45:26 2002
+++ MW/wine/server/protocol.def Mon Jan  7 16:00:33 2002
@@ -544,12 +544,22 @@
     int          fd;            /* file descriptor */
     int          type;          /* the type of file */
 @END
+#define FD_TYPE(x) ((x) & 0xff)
+
 #define FD_TYPE_INVALID    0
 #define FD_TYPE_DEFAULT    1
 #define FD_TYPE_CONSOLE    2
-#define FD_TYPE_OVERLAPPED 3
-#define FD_TYPE_TIMEOUT    4
+#define FD_TYPE_DEVICE     3
+#define FD_TYPE_NAMED_PIPE 4
+#define FD_TYPE_PIPE       5
+#define FD_TYPE_SERIAL     6
+#define FD_TYPE_SOCKET     7
+
+#define FD_TYPE_FLAG_OVERLAPPED 0x100
+#define FD_TYPE_FLAG_TIMEOUT    0x200

+#define FD_TYPE_IS_OVERLAPPED(x) ((x) & FD_TYPE_FLAG_OVERLAPPED)
+#define FD_TYPE_HAS_TIMEOUT(x)   ((x) & FD_TYPE_FLAG_TIMEOUT)

 /* Set a file current position */
 @REQ(set_file_pointer)
diff -ruX diffignore CVS/wine/server/serial.c MW/wine/server/serial.c
--- CVS/wine/server/serial.c    Mon Jan  7 15:45:26 2002
+++ MW/wine/server/serial.c     Mon Jan  7 16:00:33 2002
@@ -192,6 +192,7 @@
 static int serial_get_info( struct object *obj, struct get_file_info_reply *reply )
 {
     struct serial *serial = (struct serial *) obj;
+    int fd_type = FD_TYPE_SERIAL;
     assert( obj->ops == &serial_ops );

     if (reply)
@@ -209,13 +210,13 @@
     }

     if(serial->attrib & FILE_FLAG_OVERLAPPED)
-        return FD_TYPE_OVERLAPPED;
+        fd_type |= FD_TYPE_FLAG_OVERLAPPED;

-    if( (serial->readinterval == MAXDWORD) &&
-        (serial->readmult == 0) && (serial->readconst == 0) )
-        return FD_TYPE_DEFAULT;
+    else if( !((serial->readinterval == MAXDWORD) &&
+              (serial->readmult == 0) && (serial->readconst == 0)) )
+       fd_type |= FD_TYPE_FLAG_TIMEOUT;

-    return FD_TYPE_TIMEOUT;
+    return fd_type;
 }

 static void serial_poll_event(struct object *obj, int event)
diff -ruX diffignore CVS/wine/server/sock.c MW/wine/server/sock.c
--- CVS/wine/server/sock.c      Mon Jan  7 15:45:26 2002
+++ MW/wine/server/sock.c       Mon Jan  7 16:00:33 2002
@@ -288,7 +288,7 @@
         reply->index_low   = 0;
         reply->serial      = 0;
     }
-    return FD_TYPE_DEFAULT;
+    return FD_TYPE_SOCKET;
 }

 static void sock_destroy( struct object *obj )



Reply via email to