Alexandre Julliard : server: Return a more correct fd type for anonymous files.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Apr 23 08:39:20 CDT 2007


Module: wine
Branch: master
Commit: 133b8bc3edea8b0ddaaf812b2fdcbf20e244ec85
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=133b8bc3edea8b0ddaaf812b2fdcbf20e244ec85

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Apr 23 15:13:22 2007 +0200

server: Return a more correct fd type for anonymous files.

---

 dlls/ntdll/file.c              |    2 ++
 include/wine/server_protocol.h |    3 ++-
 server/file.c                  |   20 +++++++++++++++++---
 server/protocol.def            |    1 +
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index d0229af..b1e2209 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -439,6 +439,7 @@ static NTSTATUS get_io_timeouts( HANDLE handle, enum server_fd_type type, ULONG
         break;
     case FD_TYPE_SOCKET:
     case FD_TYPE_PIPE:
+    case FD_TYPE_CHAR:
         if (is_read) timeouts->interval = 0;  /* return as soon as we got something */
         break;
     default:
@@ -491,6 +492,7 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL
     case FD_TYPE_MAILSLOT:
     case FD_TYPE_SOCKET:
     case FD_TYPE_PIPE:
+    case FD_TYPE_CHAR:
         *avail_mode = TRUE;
         break;
     default:
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 1fde126..5a1c721 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1083,6 +1083,7 @@ enum server_fd_type
     FD_TYPE_SERIAL,
     FD_TYPE_PIPE,
     FD_TYPE_MAILSLOT,
+    FD_TYPE_CHAR,
     FD_TYPE_DEVICE,
     FD_TYPE_NB_TYPES
 };
@@ -4625,6 +4626,6 @@ union generic_reply
     struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 298
+#define SERVER_PROTOCOL_VERSION 299
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/file.c b/server/file.c
index a45c340..7fc36b0 100644
--- a/server/file.c
+++ b/server/file.c
@@ -58,6 +58,7 @@ struct file
     struct object       obj;        /* object header */
     struct fd          *fd;         /* file descriptor for this file */
     unsigned int        access;     /* file access (FILE_READ_DATA etc.) */
+    mode_t              mode;       /* file stat.st_mode */
 };
 
 static unsigned int generic_file_map_access( unsigned int access );
@@ -110,9 +111,17 @@ static inline int is_overlapped( const struct file *file )
 static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing )
 {
     struct file *file;
+    struct stat st;
+
+    if (fstat( fd, &st ) == -1)
+    {
+        file_set_error();
+        return NULL;
+    }
 
     if ((file = alloc_object( &file_ops )))
     {
+        file->mode = st.st_mode;
         file->access = file_map_access( &file->obj, access );
         if (!(file->fd = create_anonymous_fd( &file_fd_ops, fd, &file->obj,
                                               FILE_SYNCHRONOUS_IO_NONALERT )))
@@ -124,12 +133,13 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in
     return file;
 }
 
-static struct object *create_file_obj( struct fd *fd, unsigned int access )
+static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode )
 {
     struct file *file = alloc_object( &file_ops );
 
     if (!file) return NULL;
     file->access  = access;
+    file->mode    = mode;
     file->fd      = fd;
     grab_object( fd );
     set_fd_user( fd, &file_fd_ops, &file->obj );
@@ -178,7 +188,7 @@ static struct object *create_file( const char *nameptr, data_size_t len, unsigne
     else if (S_ISCHR(mode) && is_serial_fd( fd ))
         obj = create_serial( fd );
     else
-        obj = create_file_obj( fd, access );
+        obj = create_file_obj( fd, access, mode );
 
     release_object( fd );
 
@@ -235,7 +245,11 @@ static void file_flush( struct fd *fd, struct event **event )
 
 static enum server_fd_type file_get_fd_type( struct fd *fd )
 {
-    return FD_TYPE_FILE;
+    struct file *file = get_fd_user( fd );
+
+    if (S_ISREG(file->mode) || S_ISBLK(file->mode)) return FD_TYPE_FILE;
+    if (S_ISDIR(file->mode)) return FD_TYPE_DIR;
+    return FD_TYPE_CHAR;
 }
 
 static struct fd *file_get_fd( struct object *obj )
diff --git a/server/protocol.def b/server/protocol.def
index 02dee2d..8e50119 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -897,6 +897,7 @@ enum server_fd_type
     FD_TYPE_SERIAL,   /* serial port */
     FD_TYPE_PIPE,     /* named pipe */
     FD_TYPE_MAILSLOT, /* mailslot */
+    FD_TYPE_CHAR,     /* unspecified char device */
     FD_TYPE_DEVICE,   /* Windows device file */
     FD_TYPE_NB_TYPES
 };




More information about the wine-cvs mailing list