Cygwin: POSIX msg queues: move handling of memory map into fhandler

This encapsulated creation, duplication, and closing of all
Windows objects connected to the message queue in the fhandler.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2021-05-21 15:25:37 +02:00
parent 5b380b1ca6
commit 723f38b10a
3 changed files with 52 additions and 71 deletions

View File

@ -3107,6 +3107,8 @@ class fhandler_mqueue: public fhandler_base
{
struct mq_info mqi;
struct mq_info *_mqinfo (HANDLE, SIZE_T, mode_t, int, bool);
public:
fhandler_mqueue ();
fhandler_mqueue (void *) {}
@ -3116,7 +3118,14 @@ public:
char *get_proc_fd_name (char *);
struct mq_info *mqinfo (int8_t *, HANDLE, size_t, mode_t, int);
struct mq_info *mqinfo_create (HANDLE _h, SIZE_T _s, mode_t _m, int _f)
{
return _mqinfo (_h, _s, _m, _f, false);
}
struct mq_info *mqinfo_open (HANDLE _h, SIZE_T _s, mode_t _m, int _f)
{
return _mqinfo (_h, _s, _m, _f, true);
}
struct mq_info *mqinfo () { return &mqi; }
void fixup_after_fork (HANDLE);

View File

@ -20,17 +20,19 @@ fhandler_mqueue::fhandler_mqueue () :
}
struct mq_info *
fhandler_mqueue::mqinfo (int8_t *mptr, HANDLE sect, size_t size, mode_t mode,
int flags)
fhandler_mqueue::_mqinfo (HANDLE fh, SIZE_T filesize, mode_t mode, int flags,
bool just_open)
{
WCHAR buf[MAX_PATH];
WCHAR buf[NAME_MAX + sizeof ("mqueue/XXX")];
UNICODE_STRING uname;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
LARGE_INTEGER fsiz = { QuadPart: (LONGLONG) filesize };
PVOID mptr = NULL;
mqinfo ()->mqi_hdr = (struct mq_hdr *) mptr;
mqinfo ()->mqi_sect = sect;
mqinfo ()->mqi_sectsize = size;
/* Set sectsize prior to using filesize in NtMapViewOfSection. It will
get pagesize aligned, which breaks the next NtMapViewOfSection in fork. */
mqinfo ()->mqi_sectsize = filesize;
mqinfo ()->mqi_mode = mode;
mqinfo ()->mqi_flags = flags;
@ -60,10 +62,36 @@ fhandler_mqueue::mqinfo (int8_t *mptr, HANDLE sect, size_t size, mode_t mode,
if (!NT_SUCCESS (status))
goto err;
InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL);
status = NtCreateSection (&mqinfo ()->mqi_sect, SECTION_ALL_ACCESS, &attr,
&fsiz, PAGE_READWRITE, SEC_COMMIT, fh);
if (!NT_SUCCESS (status))
goto err;
status = NtMapViewOfSection (mqinfo ()->mqi_sect, NtCurrentProcess (),
&mptr, 0, filesize, NULL, &filesize,
ViewShare, 0, PAGE_READWRITE);
if (!NT_SUCCESS (status))
goto err;
mqinfo ()->mqi_hdr = (struct mq_hdr *) mptr;
/* Special problem on Cygwin. /dev/mqueue is just a simple dir,
so there's a chance normal files are created in there. */
if (just_open && mqinfo ()->mqi_hdr->mqh_magic != MQI_MAGIC)
{
status = STATUS_ACCESS_DENIED;
goto err;
}
mqinfo ()->mqi_magic = MQI_MAGIC;
return mqinfo ();
err:
if (mqinfo ()->mqi_sect)
NtClose (mqinfo ()->mqi_sect);
if (mqinfo ()->mqi_waitrecv)
NtClose (mqinfo ()->mqi_waitrecv);
if (mqinfo ()->mqi_waitsend)
NtClose (mqinfo ()->mqi_waitsend);
if (mqinfo ()->mqi_lock)

View File

@ -318,35 +318,6 @@ struct mq_attr defattr = { 0, 10, 8192, 0 }; /* Linux defaults. */
extern "C" off_t lseek64 (int, off_t, int);
extern "C" void *mmap64 (void *, size_t, int, int, int, off_t);
static int8_t *
_map_file (int fd, SIZE_T filesize, HANDLE &secth)
{
OBJECT_ATTRIBUTES oa;
LARGE_INTEGER fsiz = { QuadPart: (LONGLONG) filesize };
NTSTATUS status;
PVOID addr = NULL;
secth = NULL;
InitializeObjectAttributes (&oa, NULL, 0, NULL, NULL);
status = NtCreateSection (&secth, SECTION_ALL_ACCESS, &oa, &fsiz,
PAGE_READWRITE, SEC_COMMIT,
(HANDLE) _get_osfhandle (fd));
if (NT_SUCCESS (status))
{
status = NtMapViewOfSection (secth, NtCurrentProcess (), &addr, 0,
filesize, NULL, &filesize,
ViewShare, 0, PAGE_READWRITE);
if (!NT_SUCCESS (status))
{
NtClose (secth);
secth = NULL;
}
}
if (!NT_SUCCESS (status))
__seterrno_from_nt_status (status);
return (int8_t *) addr;
}
extern "C" mqd_t
mq_open (const char *name, int oflag, ...)
{
@ -355,10 +326,9 @@ mq_open (const char *name, int oflag, ...)
off_t filesize = 0;
va_list ap;
mode_t mode;
HANDLE secth;
int8_t *mptr = NULL;
fhandler_mqueue *fh;
fhandler_mqueue *fh = NULL;
struct stat statbuff;
int8_t *mptr = NULL;
struct mq_hdr *mqhdr;
struct msg_hdr *msghdr;
struct mq_attr *attr;
@ -414,11 +384,6 @@ mq_open (const char *name, int oflag, ...)
if (ftruncate64 (fd, filesize) == -1)
__leave;
/* Memory map the file */
mptr = _map_file (fd, filesize, secth);
if (!mptr)
__leave;
/* Create file descriptor for mqueue */
cygheap_fdnew fdm;
@ -429,12 +394,14 @@ mq_open (const char *name, int oflag, ...)
__leave;
fdm = fh;
mqinfo = fh->mqinfo (mptr, secth, filesize, mode, nonblock);
mqinfo = fh->mqinfo_create ((HANDLE) _get_osfhandle (fd), filesize,
mode, nonblock);
if (!mqinfo)
__leave;
/* Initialize header at beginning of file */
/* Create free list with all messages on it */
mptr = (int8_t *) mqinfo->mqi_hdr;
mqhdr = mqinfo->mqi_hdr;
mqhdr->mqh_attr.mq_flags = 0;
mqhdr->mqh_attr.mq_maxmsg = attr->mq_maxmsg;
@ -493,25 +460,6 @@ mq_open (const char *name, int oflag, ...)
__leave;
}
filesize = statbuff.st_size;
mptr = _map_file (fd, filesize, secth);
if (!mptr)
__leave;
close (fd);
fd = -1;
mqhdr = (struct mq_hdr *) mptr;
if (mqhdr->mqh_magic != MQI_MAGIC)
{
system_printf (
"Old message queue \"%s\" detected!\n"
"This file is not usable as message queue anymore due to changes in the "
"internal file layout. Please remove the file and try again.", mqname);
set_errno (EACCES);
__leave;
}
/* Create file descriptor for mqueue */
cygheap_fdnew fdm;
@ -522,11 +470,12 @@ mq_open (const char *name, int oflag, ...)
__leave;
fdm = fh;
mqinfo = fh->mqinfo (mptr, secth, filesize, statbuff.st_mode,
nonblock);
mqinfo = fh->mqinfo_open ((HANDLE) _get_osfhandle (fd), statbuff.st_size,
statbuff.st_mode, nonblock);
if (!mqinfo)
__leave;
close (fd);
return (mqd_t) fdm;
}
__except (EFAULT) {}
@ -535,11 +484,6 @@ mq_open (const char *name, int oflag, ...)
save_errno save;
if (created)
unlink (mqname);
if (mptr)
{
NtUnmapViewOfSection (NtCurrentProcess (), mptr);
NtClose (secth);
}
if (fd >= 0)
close (fd);
return (mqd_t) -1;