server: Return a more correct fd type for anonymous files.
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 @@
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 @@
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 @@
FD_TYPE_SERIAL,
FD_TYPE_PIPE,
FD_TYPE_MAILSLOT,
+ FD_TYPE_CHAR,
FD_TYPE_DEVICE,
FD_TYPE_NB_TYPES
};
@@ -4625,6 +4626,6 @@
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 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 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 @@
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 @@
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 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 @@
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
};