ntdll: Call tcdrain for serial handles from NtFlushBuffersFile.
This commit is contained in:
parent
d35c67becd
commit
f93a5d2560
|
@ -66,6 +66,9 @@
|
||||||
#ifdef HAVE_SYS_STATFS_H
|
#ifdef HAVE_SYS_STATFS_H
|
||||||
# include <sys/statfs.h>
|
# include <sys/statfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
#include <termios.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
# include <valgrind/memcheck.h>
|
# include <valgrind/memcheck.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -2749,19 +2752,39 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock
|
||||||
{
|
{
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
HANDLE hEvent = NULL;
|
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 );
|
while (tcdrain( fd ) == -1)
|
||||||
ret = wine_server_call( req );
|
{
|
||||||
hEvent = wine_server_ptr_handle( reply->event );
|
if (errno != EINTR)
|
||||||
|
{
|
||||||
|
ret = FILE_GetNtStatus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
else
|
||||||
if (!ret && hEvent)
|
|
||||||
{
|
{
|
||||||
ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
|
SERVER_START_REQ( flush_file )
|
||||||
NtClose( hEvent );
|
{
|
||||||
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ static struct fd *serial_get_fd( struct object *obj );
|
||||||
static void serial_destroy(struct object *obj);
|
static void serial_destroy(struct object *obj);
|
||||||
|
|
||||||
static enum server_fd_type serial_get_fd_type( struct fd *fd );
|
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 );
|
static void serial_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
|
||||||
|
|
||||||
struct serial
|
struct serial
|
||||||
|
@ -107,7 +106,7 @@ static const struct fd_ops serial_fd_ops =
|
||||||
{
|
{
|
||||||
default_fd_get_poll_events, /* get_poll_events */
|
default_fd_get_poll_events, /* get_poll_events */
|
||||||
default_poll_event, /* poll_event */
|
default_poll_event, /* poll_event */
|
||||||
serial_flush, /* flush */
|
no_flush, /* flush */
|
||||||
serial_get_fd_type, /* get_fd_type */
|
serial_get_fd_type, /* get_fd_type */
|
||||||
default_fd_ioctl, /* ioctl */
|
default_fd_ioctl, /* ioctl */
|
||||||
serial_queue_async, /* queue_async */
|
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)
|
DECL_HANDLER(get_serial_info)
|
||||||
{
|
{
|
||||||
struct serial *serial;
|
struct serial *serial;
|
||||||
|
|
Loading…
Reference in New Issue