Wolfgang Walter : ntdll: Call tcdrain for serial handles from NtFlushBuffersFile.

Alexandre Julliard julliard at winehq.org
Thu Aug 29 13:18:14 CDT 2013


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

Author: Wolfgang Walter <wine at stwm.de>
Date:   Tue Jan 20 17:52:38 2009 +0100

ntdll: Call tcdrain for serial handles from NtFlushBuffersFile.

---

 dlls/ntdll/file.c |   39 +++++++++++++++++++++++++++++++--------
 server/serial.c   |   11 +----------
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 5147ef5..3ffc632 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -66,6 +66,9 @@
 #ifdef HAVE_SYS_STATFS_H
 # include <sys/statfs.h>
 #endif
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
 #ifdef HAVE_VALGRIND_MEMCHECK_H
 # include <valgrind/memcheck.h>
 #endif
@@ -2749,19 +2752,39 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock
 {
     NTSTATUS ret;
     HANDLE hEvent = NULL;
+    enum server_fd_type type;
+    int fd, needs_close;
 
-    SERVER_START_REQ( flush_file )
+    ret = server_get_unix_fd( hFile, FILE_WRITE_DATA, &fd, &needs_close, &type, NULL );
+
+    if (!ret && type == FD_TYPE_SERIAL)
     {
-        req->handle = wine_server_obj_handle( hFile );
-        ret = wine_server_call( req );
-        hEvent = wine_server_ptr_handle( reply->event );
+        while (tcdrain( fd ) == -1)
+        {
+            if (errno != EINTR)
+            {
+                ret = FILE_GetNtStatus();
+                break;
+            }
+        }
     }
-    SERVER_END_REQ;
-    if (!ret && hEvent)
+    else
     {
-        ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
-        NtClose( hEvent );
+        SERVER_START_REQ( flush_file )
+        {
+            req->handle = wine_server_obj_handle( hFile );
+            ret = wine_server_call( req );
+            hEvent = wine_server_ptr_handle( reply->event );
+        }
+        SERVER_END_REQ;
+        if (!ret && hEvent)
+        {
+            ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
+            NtClose( hEvent );
+        }
     }
+
+    if (needs_close) close( fd );
     return ret;
 }
 
diff --git a/server/serial.c b/server/serial.c
index 587fee1..aac20fa 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -61,7 +61,6 @@ static struct fd *serial_get_fd( struct object *obj );
 static void serial_destroy(struct object *obj);
 
 static enum server_fd_type serial_get_fd_type( struct fd *fd );
-static void serial_flush( struct fd *fd, struct event **event );
 static void serial_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
 
 struct serial
@@ -107,7 +106,7 @@ static const struct fd_ops serial_fd_ops =
 {
     default_fd_get_poll_events,   /* get_poll_events */
     default_poll_event,           /* poll_event */
-    serial_flush,                 /* flush */
+    no_flush,                     /* flush */
     serial_get_fd_type,           /* get_fd_type */
     default_fd_ioctl,             /* ioctl */
     serial_queue_async,           /* queue_async */
@@ -196,14 +195,6 @@ static void serial_queue_async( struct fd *fd, const async_data_t *data, int typ
     }
 }
 
-static void serial_flush( struct fd *fd, struct event **event )
-{
-    /* MSDN says: If hFile is a handle to a communications device,
-     * the function only flushes the transmit buffer.
-     */
-    if (tcflush( get_unix_fd(fd), TCOFLUSH ) == -1) file_set_error();
-}
-
 DECL_HANDLER(get_serial_info)
 {
     struct serial *serial;




More information about the wine-cvs mailing list