mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
server: Reimplement mailslots using server-side I/O.
This commit is contained in:
parent
c984ec084b
commit
3ccb87e3f8
Notes:
Alexandre Julliard
2024-07-22 23:02:37 +02:00
Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/-/merge_requests/6045
6 changed files with 156 additions and 138 deletions
|
@ -3305,7 +3305,6 @@ static void test_GetFileType(void)
|
|||
ok( h != INVALID_HANDLE_VALUE, "CreateMailslot failed\n" );
|
||||
SetLastError( 12345678 );
|
||||
type = GetFileType( h );
|
||||
todo_wine
|
||||
ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
|
||||
todo_wine
|
||||
ok( GetLastError() == NO_ERROR, "expected ERROR_NO_ERROR got %lx\n", GetLastError() );
|
||||
|
|
|
@ -94,7 +94,6 @@ static int mailslot_test(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = ReadFile(hSlot, buffer, 0, &count, NULL);
|
||||
ok(!ret, "ReadFile should fail\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError());
|
||||
ok(count == 0, "expected 0, got %lu\n", count);
|
||||
|
||||
|
@ -264,9 +263,7 @@ static int mailslot_test(void)
|
|||
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
|
||||
"getmailslotinfo failed\n");
|
||||
ok( dwNext == 1, "dwNext incorrect\n");
|
||||
todo_wine {
|
||||
ok( dwMsgCount == 2, "dwMsgCount incorrect\n");
|
||||
}
|
||||
|
||||
/* write a 3rd message with zero size */
|
||||
ok( WriteFile( hWriter2, buffer, 0, &count, NULL), "3rd write failed\n");
|
||||
|
@ -276,8 +273,7 @@ static int mailslot_test(void)
|
|||
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
|
||||
"getmailslotinfo failed\n");
|
||||
ok( dwNext == 1, "dwNext incorrect\n");
|
||||
todo_wine
|
||||
ok( dwMsgCount == 3, "dwMsgCount incorrect %lu\n", dwMsgCount);
|
||||
ok( dwMsgCount == 3, "dwMsgCount incorrect %lu\n", dwMsgCount);
|
||||
|
||||
buffer[0]=buffer[1]=0;
|
||||
|
||||
|
@ -295,9 +291,7 @@ static int mailslot_test(void)
|
|||
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
|
||||
"getmailslotinfo failed\n");
|
||||
ok( dwNext == 2, "dwNext incorrect\n");
|
||||
todo_wine {
|
||||
ok( dwMsgCount == 2, "dwMsgCount incorrect %lu\n", dwMsgCount);
|
||||
}
|
||||
ok( dwMsgCount == 2, "dwMsgCount incorrect %lu\n", dwMsgCount);
|
||||
|
||||
/* read the second message */
|
||||
ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
|
||||
|
@ -310,15 +304,11 @@ static int mailslot_test(void)
|
|||
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
|
||||
"getmailslotinfo failed\n");
|
||||
ok( dwNext == 0, "dwNext incorrect %lu\n", dwNext);
|
||||
todo_wine {
|
||||
ok( dwMsgCount == 1, "dwMsgCount incorrect %lu\n", dwMsgCount);
|
||||
}
|
||||
ok( dwMsgCount == 1, "dwMsgCount incorrect %lu\n", dwMsgCount);
|
||||
|
||||
/* read the 3rd (zero length) message */
|
||||
todo_wine {
|
||||
ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
|
||||
"3rd slot read failed\n");
|
||||
}
|
||||
ok( count == 0, "failed to get 3rd message\n");
|
||||
|
||||
/*
|
||||
|
@ -346,9 +336,9 @@ static int mailslot_test(void)
|
|||
io.Status = 0xdeadbeef;
|
||||
io.Information = 0xdeadbeef;
|
||||
ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, 1, NULL, NULL );
|
||||
todo_wine ok( ret == STATUS_BUFFER_TOO_SMALL, "got %#x\n", ret );
|
||||
todo_wine ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
|
||||
todo_wine ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
|
||||
ok( ret == STATUS_BUFFER_TOO_SMALL, "got %#x\n", ret );
|
||||
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
|
||||
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
|
||||
|
||||
io.Status = 0xdeadbeef;
|
||||
io.Information = 0xdeadbeef;
|
||||
|
@ -359,8 +349,8 @@ static int mailslot_test(void)
|
|||
ok( io.Information == sizeof(info), "got size %Iu\n", io.Information );
|
||||
ok( !info.MaximumMessageSize, "got maximum size %lu\n", info.MaximumMessageSize );
|
||||
ok( !info.MailslotQuota, "got quota %lu\n", info.MailslotQuota );
|
||||
todo_wine ok( info.NextMessageSize == 2, "got next size %lu\n", info.NextMessageSize );
|
||||
todo_wine ok( info.MessagesAvailable == 1, "got message count %lu\n", info.MessagesAvailable );
|
||||
ok( info.NextMessageSize == 2, "got next size %lu\n", info.NextMessageSize );
|
||||
ok( info.MessagesAvailable == 1, "got message count %lu\n", info.MessagesAvailable );
|
||||
ok( !info.ReadTimeout.QuadPart, "got timeout %I64u\n", info.ReadTimeout.QuadPart );
|
||||
|
||||
io.Status = 0xdeadbeef;
|
||||
|
@ -425,8 +415,8 @@ static int mailslot_test(void)
|
|||
|
||||
ret = WaitForSingleObject( hSlot, 1000 );
|
||||
ok( !ret, "got %d\n", ret );
|
||||
todo_wine ok( !io.Status, "got status %#lx\n", io.Status );
|
||||
todo_wine ok( io.Information == 4, "got size %Iu\n", io.Information );
|
||||
ok( !io.Status, "got status %#lx\n", io.Status );
|
||||
ok( io.Information == 4, "got size %Iu\n", io.Information );
|
||||
|
||||
CloseHandle( hWriter );
|
||||
CloseHandle( hSlot );
|
||||
|
|
|
@ -4522,44 +4522,6 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case FileMailslotQueryInformation:
|
||||
{
|
||||
FILE_MAILSLOT_QUERY_INFORMATION *info = ptr;
|
||||
|
||||
SERVER_START_REQ( set_mailslot_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->flags = 0;
|
||||
status = wine_server_call( req );
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
info->MaximumMessageSize = reply->max_msgsize;
|
||||
info->MailslotQuota = 0;
|
||||
info->NextMessageSize = 0;
|
||||
info->MessagesAvailable = 0;
|
||||
info->ReadTimeout.QuadPart = reply->read_timeout;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!status)
|
||||
{
|
||||
char *tmpbuf;
|
||||
ULONG size = info->MaximumMessageSize ? info->MaximumMessageSize : 0x10000;
|
||||
if (size > 0x10000) size = 0x10000;
|
||||
if ((tmpbuf = malloc( size )))
|
||||
{
|
||||
if (needs_close) close( fd );
|
||||
if (!server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ))
|
||||
{
|
||||
int res = recv( fd, tmpbuf, size, MSG_PEEK );
|
||||
info->MessagesAvailable = (res > 0);
|
||||
info->NextMessageSize = (res >= 0) ? res : MAILSLOT_NO_MESSAGE;
|
||||
}
|
||||
free( tmpbuf );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileNameInformation:
|
||||
{
|
||||
FILE_NAME_INFORMATION *info = ptr;
|
||||
|
@ -5156,10 +5118,7 @@ static BOOL async_write_proc( void *user, ULONG_PTR *info, unsigned int *status
|
|||
&needs_close, &type, NULL )))
|
||||
break;
|
||||
|
||||
if (!fileio->count && type == FD_TYPE_MAILSLOT)
|
||||
result = send( fd, fileio->buffer, 0, 0 );
|
||||
else
|
||||
result = write( fd, &fileio->buffer[fileio->already], fileio->count - fileio->already );
|
||||
result = write( fd, &fileio->buffer[fileio->already], fileio->count - fileio->already );
|
||||
|
||||
if (needs_close) close( fd );
|
||||
|
||||
|
@ -5364,20 +5323,6 @@ static unsigned int get_io_timeouts( HANDLE handle, enum server_fd_type type, UL
|
|||
}
|
||||
break;
|
||||
}
|
||||
case FD_TYPE_MAILSLOT:
|
||||
if (is_read)
|
||||
{
|
||||
timeouts->interval = 0; /* return as soon as we got something */
|
||||
SERVER_START_REQ( set_mailslot_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->flags = 0;
|
||||
if (!wine_server_call( req ) && reply->read_timeout != TIMEOUT_INFINITE)
|
||||
timeouts->total = reply->read_timeout / -10000;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
break;
|
||||
case FD_TYPE_SOCKET:
|
||||
case FD_TYPE_CHAR:
|
||||
if (is_read) timeouts->interval = 0; /* return as soon as we got something */
|
||||
|
@ -5428,7 +5373,6 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL
|
|||
}
|
||||
break;
|
||||
}
|
||||
case FD_TYPE_MAILSLOT:
|
||||
case FD_TYPE_SOCKET:
|
||||
case FD_TYPE_CHAR:
|
||||
*avail_mode = TRUE;
|
||||
|
@ -5703,7 +5647,7 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
|
|||
if (total) /* return with what we got so far */
|
||||
status = STATUS_SUCCESS;
|
||||
else
|
||||
status = (type == FD_TYPE_MAILSLOT) ? STATUS_IO_TIMEOUT : STATUS_TIMEOUT;
|
||||
status = STATUS_TIMEOUT;
|
||||
goto done;
|
||||
}
|
||||
if (ret == -1 && errno != EINTR)
|
||||
|
@ -5934,11 +5878,7 @@ NTSTATUS WINAPI NtWriteFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, v
|
|||
|
||||
for (;;)
|
||||
{
|
||||
/* zero-length writes on sockets may not work with plain write(2) */
|
||||
if (!length && type == FD_TYPE_MAILSLOT)
|
||||
result = send( unix_handle, buffer, 0, 0 );
|
||||
else
|
||||
result = write( unix_handle, (const char *)buffer + total, length - total );
|
||||
result = write( unix_handle, (const char *)buffer + total, length - total );
|
||||
|
||||
if (result >= 0)
|
||||
{
|
||||
|
|
|
@ -1777,7 +1777,6 @@ enum server_fd_type
|
|||
FD_TYPE_DIR,
|
||||
FD_TYPE_SOCKET,
|
||||
FD_TYPE_SERIAL,
|
||||
FD_TYPE_MAILSLOT,
|
||||
FD_TYPE_CHAR,
|
||||
FD_TYPE_DEVICE,
|
||||
FD_TYPE_NB_TYPES
|
||||
|
@ -6599,7 +6598,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 835
|
||||
#define SERVER_PROTOCOL_VERSION 836
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -47,14 +47,21 @@
|
|||
#include "thread.h"
|
||||
#include "request.h"
|
||||
|
||||
struct mailslot_message
|
||||
{
|
||||
struct list entry;
|
||||
struct iosb *iosb;
|
||||
};
|
||||
|
||||
struct mailslot
|
||||
{
|
||||
struct object obj;
|
||||
struct fd *fd;
|
||||
int write_fd;
|
||||
unsigned int max_msgsize;
|
||||
timeout_t read_timeout;
|
||||
struct list writers;
|
||||
struct list messages;
|
||||
struct async_queue read_q;
|
||||
};
|
||||
|
||||
/* mailslot functions */
|
||||
|
@ -91,21 +98,23 @@ static const struct object_ops mailslot_ops =
|
|||
};
|
||||
|
||||
static enum server_fd_type mailslot_get_fd_type( struct fd *fd );
|
||||
static void mailslot_queue_async( struct fd *fd, struct async *async, int type, int count );
|
||||
static void mailslot_read( struct fd *fd, struct async *async, file_pos_t pos );
|
||||
static void mailslot_write( struct fd *fd, struct async *async, file_pos_t pos );
|
||||
static void mailslot_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class );
|
||||
|
||||
static const struct fd_ops mailslot_fd_ops =
|
||||
{
|
||||
default_fd_get_poll_events, /* get_poll_events */
|
||||
default_poll_event, /* poll_event */
|
||||
mailslot_get_fd_type, /* get_fd_type */
|
||||
no_fd_read, /* read */
|
||||
no_fd_write, /* write */
|
||||
mailslot_read, /* read */
|
||||
mailslot_write, /* write */
|
||||
no_fd_flush, /* flush */
|
||||
default_fd_get_file_info, /* get_file_info */
|
||||
mailslot_get_file_info, /* get_file_info */
|
||||
no_fd_get_volume_info, /* get_volume_info */
|
||||
default_fd_ioctl, /* ioctl */
|
||||
default_fd_cancel_async, /* cancel_async */
|
||||
mailslot_queue_async, /* queue_async */
|
||||
no_fd_queue_async, /* queue_async */
|
||||
default_fd_reselect_async /* reselect_async */
|
||||
};
|
||||
|
||||
|
@ -150,14 +159,16 @@ static const struct object_ops mail_writer_ops =
|
|||
};
|
||||
|
||||
static enum server_fd_type mail_writer_get_fd_type( struct fd *fd );
|
||||
static void mail_writer_read( struct fd *fd, struct async *async, file_pos_t pos );
|
||||
static void mail_writer_write( struct fd *fd, struct async *async, file_pos_t pos );
|
||||
|
||||
static const struct fd_ops mail_writer_fd_ops =
|
||||
{
|
||||
default_fd_get_poll_events, /* get_poll_events */
|
||||
default_poll_event, /* poll_event */
|
||||
mail_writer_get_fd_type, /* get_fd_type */
|
||||
no_fd_read, /* read */
|
||||
no_fd_write, /* write */
|
||||
mail_writer_read, /* read */
|
||||
mail_writer_write, /* write */
|
||||
no_fd_flush, /* flush */
|
||||
default_fd_get_file_info, /* get_file_info */
|
||||
no_fd_get_volume_info, /* get_volume_info */
|
||||
|
@ -258,17 +269,29 @@ static const struct fd_ops mailslot_device_fd_ops =
|
|||
default_fd_reselect_async /* reselect_async */
|
||||
};
|
||||
|
||||
static struct mailslot_message *get_first_message( struct mailslot *mailslot )
|
||||
{
|
||||
if (list_empty( &mailslot->messages ))
|
||||
return NULL;
|
||||
|
||||
return LIST_ENTRY( list_head( &mailslot->messages ), struct mailslot_message, entry );
|
||||
}
|
||||
|
||||
static void mailslot_destroy( struct object *obj)
|
||||
{
|
||||
struct mailslot *mailslot = (struct mailslot *) obj;
|
||||
struct mailslot_message *message;
|
||||
|
||||
while ((message = get_first_message( mailslot )))
|
||||
{
|
||||
list_remove( &message->entry );
|
||||
release_object( message->iosb );
|
||||
free( message );
|
||||
}
|
||||
|
||||
free_async_queue( &mailslot->read_q );
|
||||
|
||||
assert( mailslot->fd );
|
||||
|
||||
if (mailslot->write_fd != -1)
|
||||
{
|
||||
shutdown( mailslot->write_fd, SHUT_RDWR );
|
||||
close( mailslot->write_fd );
|
||||
}
|
||||
release_object( mailslot->fd );
|
||||
}
|
||||
|
||||
|
@ -283,7 +306,85 @@ static void mailslot_dump( struct object *obj, int verbose )
|
|||
|
||||
static enum server_fd_type mailslot_get_fd_type( struct fd *fd )
|
||||
{
|
||||
return FD_TYPE_MAILSLOT;
|
||||
return FD_TYPE_DEVICE;
|
||||
}
|
||||
|
||||
static void reselect_mailslot( struct mailslot *mailslot )
|
||||
{
|
||||
struct mailslot_message *message;
|
||||
struct async *async;
|
||||
|
||||
while ((message = get_first_message( mailslot )) && (async = find_pending_async( &mailslot->read_q )))
|
||||
{
|
||||
struct iosb *read_iosb = async_get_iosb( async );
|
||||
|
||||
if (read_iosb->out_size < message->iosb->in_size)
|
||||
{
|
||||
async_request_complete( async, STATUS_BUFFER_TOO_SMALL, 0, 0, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
async_request_complete( async, STATUS_SUCCESS, message->iosb->in_size,
|
||||
message->iosb->in_size, message->iosb->in_data );
|
||||
message->iosb->in_data = NULL;
|
||||
list_remove( &message->entry );
|
||||
release_object( message->iosb );
|
||||
free( message );
|
||||
}
|
||||
|
||||
release_object( async );
|
||||
release_object( read_iosb );
|
||||
}
|
||||
}
|
||||
|
||||
static void mailslot_read( struct fd *fd, struct async *async, file_pos_t pos )
|
||||
{
|
||||
struct mailslot *mailslot = get_fd_user( fd );
|
||||
|
||||
if (mailslot->read_timeout != (timeout_t)-1)
|
||||
async_set_timeout( async, mailslot->read_timeout ? mailslot->read_timeout : -1, STATUS_IO_TIMEOUT );
|
||||
queue_async( &mailslot->read_q, async );
|
||||
reselect_mailslot( mailslot );
|
||||
set_error( STATUS_PENDING );
|
||||
}
|
||||
|
||||
static void mailslot_write( struct fd *fd, struct async *async, file_pos_t pos )
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
|
||||
static void mailslot_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class )
|
||||
{
|
||||
struct mailslot *mailslot = get_fd_user( fd );
|
||||
|
||||
switch (info_class)
|
||||
{
|
||||
case FileMailslotQueryInformation:
|
||||
{
|
||||
FILE_MAILSLOT_QUERY_INFORMATION *info;
|
||||
struct mailslot_message *message;
|
||||
|
||||
if (get_reply_max_size() < sizeof(*info))
|
||||
{
|
||||
set_error( STATUS_INFO_LENGTH_MISMATCH );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(info = set_reply_data_size( sizeof(*info) ))) return;
|
||||
info->MaximumMessageSize = mailslot->max_msgsize;
|
||||
info->MailslotQuota = 0;
|
||||
info->MessagesAvailable = list_count( &mailslot->messages );
|
||||
if ((message = get_first_message( mailslot )))
|
||||
info->NextMessageSize = message->iosb->in_size;
|
||||
else
|
||||
info->NextMessageSize = MAILSLOT_NO_MESSAGE;
|
||||
info->ReadTimeout.QuadPart = mailslot->read_timeout;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
default_fd_get_file_info( fd, handle, info_class );
|
||||
}
|
||||
}
|
||||
|
||||
static struct fd *mailslot_get_fd( struct object *obj )
|
||||
|
@ -318,7 +419,6 @@ static struct object *mailslot_open_file( struct object *obj, unsigned int acces
|
|||
{
|
||||
struct mailslot *mailslot = (struct mailslot *)obj;
|
||||
struct mail_writer *writer;
|
||||
int unix_fd;
|
||||
|
||||
if (!(sharing & FILE_SHARE_READ))
|
||||
{
|
||||
|
@ -341,23 +441,15 @@ static struct object *mailslot_open_file( struct object *obj, unsigned int acces
|
|||
}
|
||||
}
|
||||
|
||||
if ((unix_fd = dup( mailslot->write_fd )) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
return NULL;
|
||||
}
|
||||
if (!(writer = alloc_object( &mail_writer_ops )))
|
||||
{
|
||||
close( unix_fd );
|
||||
return NULL;
|
||||
}
|
||||
grab_object( mailslot );
|
||||
writer->mailslot = mailslot;
|
||||
writer->access = mail_writer_map_access( &writer->obj, access );
|
||||
writer->sharing = sharing;
|
||||
list_add_head( &mailslot->writers, &writer->entry );
|
||||
|
||||
if (!(writer->fd = create_anonymous_fd( &mail_writer_fd_ops, unix_fd, &writer->obj, options )))
|
||||
if (!(writer->fd = alloc_pseudo_fd( &mail_writer_fd_ops, &writer->obj, options )))
|
||||
{
|
||||
release_object( writer );
|
||||
return NULL;
|
||||
|
@ -366,18 +458,6 @@ static struct object *mailslot_open_file( struct object *obj, unsigned int acces
|
|||
return &writer->obj;
|
||||
}
|
||||
|
||||
static void mailslot_queue_async( struct fd *fd, struct async *async, int type, int count )
|
||||
{
|
||||
struct mailslot *mailslot = get_fd_user( fd );
|
||||
|
||||
assert(mailslot->obj.ops == &mailslot_ops);
|
||||
|
||||
fd_queue_async( fd, async, type );
|
||||
async_set_timeout( async, mailslot->read_timeout ? mailslot->read_timeout : -1,
|
||||
STATUS_IO_TIMEOUT );
|
||||
set_error( STATUS_PENDING );
|
||||
}
|
||||
|
||||
static void mailslot_device_dump( struct object *obj, int verbose )
|
||||
{
|
||||
fputs( "Mailslot device\n", stderr );
|
||||
|
@ -478,29 +558,21 @@ static struct mailslot *create_mailslot( struct object *root,
|
|||
const struct security_descriptor *sd )
|
||||
{
|
||||
struct mailslot *mailslot;
|
||||
int fds[2];
|
||||
|
||||
if (!(mailslot = create_named_object( root, &mailslot_ops, name, attr, sd ))) return NULL;
|
||||
|
||||
mailslot->fd = NULL;
|
||||
mailslot->write_fd = -1;
|
||||
mailslot->max_msgsize = max_msgsize;
|
||||
mailslot->read_timeout = read_timeout;
|
||||
list_init( &mailslot->writers );
|
||||
list_init( &mailslot->messages );
|
||||
init_async_queue( &mailslot->read_q );
|
||||
|
||||
if (!socketpair( PF_UNIX, SOCK_DGRAM, 0, fds ))
|
||||
if ((mailslot->fd = alloc_pseudo_fd( &mailslot_fd_ops, &mailslot->obj, options )))
|
||||
{
|
||||
fcntl( fds[0], F_SETFL, O_NONBLOCK );
|
||||
fcntl( fds[1], F_SETFL, O_NONBLOCK );
|
||||
shutdown( fds[0], SHUT_RD );
|
||||
mailslot->write_fd = fds[0];
|
||||
if ((mailslot->fd = create_anonymous_fd( &mailslot_fd_ops, fds[1], &mailslot->obj, options )))
|
||||
{
|
||||
allow_fd_caching( mailslot->fd );
|
||||
return mailslot;
|
||||
}
|
||||
allow_fd_caching( mailslot->fd );
|
||||
return mailslot;
|
||||
}
|
||||
else file_set_error();
|
||||
|
||||
release_object( mailslot );
|
||||
return NULL;
|
||||
|
@ -522,7 +594,26 @@ static void mail_writer_destroy( struct object *obj)
|
|||
|
||||
static enum server_fd_type mail_writer_get_fd_type( struct fd *fd )
|
||||
{
|
||||
return FD_TYPE_MAILSLOT;
|
||||
return FD_TYPE_DEVICE;
|
||||
}
|
||||
|
||||
static void mail_writer_read( struct fd *fd, struct async *async, file_pos_t pos )
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
|
||||
static void mail_writer_write( struct fd *fd, struct async *async, file_pos_t pos )
|
||||
{
|
||||
struct mail_writer *writer = get_fd_user( fd );
|
||||
struct mailslot_message *message;
|
||||
data_size_t size;
|
||||
|
||||
if (!(message = mem_alloc( sizeof(*message) ))) return;
|
||||
message->iosb = async_get_iosb( async );
|
||||
size = message->iosb->in_size;
|
||||
list_add_tail( &writer->mailslot->messages, &message->entry );
|
||||
reselect_mailslot( writer->mailslot );
|
||||
async_request_complete( async, STATUS_SUCCESS, size, 0, NULL );
|
||||
}
|
||||
|
||||
static struct fd *mail_writer_get_fd( struct object *obj )
|
||||
|
|
|
@ -1502,7 +1502,6 @@ enum server_fd_type
|
|||
FD_TYPE_DIR, /* directory */
|
||||
FD_TYPE_SOCKET, /* socket */
|
||||
FD_TYPE_SERIAL, /* serial port */
|
||||
FD_TYPE_MAILSLOT, /* mailslot */
|
||||
FD_TYPE_CHAR, /* unspecified char device */
|
||||
FD_TYPE_DEVICE, /* Windows device file */
|
||||
FD_TYPE_NB_TYPES
|
||||
|
|
Loading…
Reference in a new issue