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:
parent
5b380b1ca6
commit
723f38b10a
|
@ -3107,6 +3107,8 @@ class fhandler_mqueue: public fhandler_base
|
||||||
{
|
{
|
||||||
struct mq_info mqi;
|
struct mq_info mqi;
|
||||||
|
|
||||||
|
struct mq_info *_mqinfo (HANDLE, SIZE_T, mode_t, int, bool);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fhandler_mqueue ();
|
fhandler_mqueue ();
|
||||||
fhandler_mqueue (void *) {}
|
fhandler_mqueue (void *) {}
|
||||||
|
@ -3116,7 +3118,14 @@ public:
|
||||||
|
|
||||||
char *get_proc_fd_name (char *);
|
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; }
|
struct mq_info *mqinfo () { return &mqi; }
|
||||||
|
|
||||||
void fixup_after_fork (HANDLE);
|
void fixup_after_fork (HANDLE);
|
||||||
|
|
|
@ -20,17 +20,19 @@ fhandler_mqueue::fhandler_mqueue () :
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mq_info *
|
struct mq_info *
|
||||||
fhandler_mqueue::mqinfo (int8_t *mptr, HANDLE sect, size_t size, mode_t mode,
|
fhandler_mqueue::_mqinfo (HANDLE fh, SIZE_T filesize, mode_t mode, int flags,
|
||||||
int flags)
|
bool just_open)
|
||||||
{
|
{
|
||||||
WCHAR buf[MAX_PATH];
|
WCHAR buf[NAME_MAX + sizeof ("mqueue/XXX")];
|
||||||
UNICODE_STRING uname;
|
UNICODE_STRING uname;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
LARGE_INTEGER fsiz = { QuadPart: (LONGLONG) filesize };
|
||||||
|
PVOID mptr = NULL;
|
||||||
|
|
||||||
mqinfo ()->mqi_hdr = (struct mq_hdr *) mptr;
|
/* Set sectsize prior to using filesize in NtMapViewOfSection. It will
|
||||||
mqinfo ()->mqi_sect = sect;
|
get pagesize aligned, which breaks the next NtMapViewOfSection in fork. */
|
||||||
mqinfo ()->mqi_sectsize = size;
|
mqinfo ()->mqi_sectsize = filesize;
|
||||||
mqinfo ()->mqi_mode = mode;
|
mqinfo ()->mqi_mode = mode;
|
||||||
mqinfo ()->mqi_flags = flags;
|
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))
|
if (!NT_SUCCESS (status))
|
||||||
goto err;
|
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;
|
mqinfo ()->mqi_magic = MQI_MAGIC;
|
||||||
return mqinfo ();
|
return mqinfo ();
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
if (mqinfo ()->mqi_sect)
|
||||||
|
NtClose (mqinfo ()->mqi_sect);
|
||||||
|
if (mqinfo ()->mqi_waitrecv)
|
||||||
|
NtClose (mqinfo ()->mqi_waitrecv);
|
||||||
if (mqinfo ()->mqi_waitsend)
|
if (mqinfo ()->mqi_waitsend)
|
||||||
NtClose (mqinfo ()->mqi_waitsend);
|
NtClose (mqinfo ()->mqi_waitsend);
|
||||||
if (mqinfo ()->mqi_lock)
|
if (mqinfo ()->mqi_lock)
|
||||||
|
|
|
@ -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" off_t lseek64 (int, off_t, int);
|
||||||
extern "C" void *mmap64 (void *, size_t, int, int, int, off_t);
|
extern "C" void *mmap64 (void *, size_t, int, int, int, off_t);
|
||||||
|
|
||||||
static int8_t *
|
|
||||||
_map_file (int fd, SIZE_T filesize, HANDLE §h)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES oa;
|
|
||||||
LARGE_INTEGER fsiz = { QuadPart: (LONGLONG) filesize };
|
|
||||||
NTSTATUS status;
|
|
||||||
PVOID addr = NULL;
|
|
||||||
|
|
||||||
secth = NULL;
|
|
||||||
InitializeObjectAttributes (&oa, NULL, 0, NULL, NULL);
|
|
||||||
status = NtCreateSection (§h, 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
|
extern "C" mqd_t
|
||||||
mq_open (const char *name, int oflag, ...)
|
mq_open (const char *name, int oflag, ...)
|
||||||
{
|
{
|
||||||
|
@ -355,10 +326,9 @@ mq_open (const char *name, int oflag, ...)
|
||||||
off_t filesize = 0;
|
off_t filesize = 0;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
HANDLE secth;
|
fhandler_mqueue *fh = NULL;
|
||||||
int8_t *mptr = NULL;
|
|
||||||
fhandler_mqueue *fh;
|
|
||||||
struct stat statbuff;
|
struct stat statbuff;
|
||||||
|
int8_t *mptr = NULL;
|
||||||
struct mq_hdr *mqhdr;
|
struct mq_hdr *mqhdr;
|
||||||
struct msg_hdr *msghdr;
|
struct msg_hdr *msghdr;
|
||||||
struct mq_attr *attr;
|
struct mq_attr *attr;
|
||||||
|
@ -414,11 +384,6 @@ mq_open (const char *name, int oflag, ...)
|
||||||
if (ftruncate64 (fd, filesize) == -1)
|
if (ftruncate64 (fd, filesize) == -1)
|
||||||
__leave;
|
__leave;
|
||||||
|
|
||||||
/* Memory map the file */
|
|
||||||
mptr = _map_file (fd, filesize, secth);
|
|
||||||
if (!mptr)
|
|
||||||
__leave;
|
|
||||||
|
|
||||||
/* Create file descriptor for mqueue */
|
/* Create file descriptor for mqueue */
|
||||||
cygheap_fdnew fdm;
|
cygheap_fdnew fdm;
|
||||||
|
|
||||||
|
@ -429,12 +394,14 @@ mq_open (const char *name, int oflag, ...)
|
||||||
__leave;
|
__leave;
|
||||||
fdm = fh;
|
fdm = fh;
|
||||||
|
|
||||||
mqinfo = fh->mqinfo (mptr, secth, filesize, mode, nonblock);
|
mqinfo = fh->mqinfo_create ((HANDLE) _get_osfhandle (fd), filesize,
|
||||||
|
mode, nonblock);
|
||||||
if (!mqinfo)
|
if (!mqinfo)
|
||||||
__leave;
|
__leave;
|
||||||
|
|
||||||
/* Initialize header at beginning of file */
|
/* Initialize header at beginning of file */
|
||||||
/* Create free list with all messages on it */
|
/* Create free list with all messages on it */
|
||||||
|
mptr = (int8_t *) mqinfo->mqi_hdr;
|
||||||
mqhdr = mqinfo->mqi_hdr;
|
mqhdr = mqinfo->mqi_hdr;
|
||||||
mqhdr->mqh_attr.mq_flags = 0;
|
mqhdr->mqh_attr.mq_flags = 0;
|
||||||
mqhdr->mqh_attr.mq_maxmsg = attr->mq_maxmsg;
|
mqhdr->mqh_attr.mq_maxmsg = attr->mq_maxmsg;
|
||||||
|
@ -493,25 +460,6 @@ mq_open (const char *name, int oflag, ...)
|
||||||
__leave;
|
__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 */
|
/* Create file descriptor for mqueue */
|
||||||
cygheap_fdnew fdm;
|
cygheap_fdnew fdm;
|
||||||
|
|
||||||
|
@ -522,11 +470,12 @@ mq_open (const char *name, int oflag, ...)
|
||||||
__leave;
|
__leave;
|
||||||
fdm = fh;
|
fdm = fh;
|
||||||
|
|
||||||
mqinfo = fh->mqinfo (mptr, secth, filesize, statbuff.st_mode,
|
mqinfo = fh->mqinfo_open ((HANDLE) _get_osfhandle (fd), statbuff.st_size,
|
||||||
nonblock);
|
statbuff.st_mode, nonblock);
|
||||||
if (!mqinfo)
|
if (!mqinfo)
|
||||||
__leave;
|
__leave;
|
||||||
|
|
||||||
|
close (fd);
|
||||||
return (mqd_t) fdm;
|
return (mqd_t) fdm;
|
||||||
}
|
}
|
||||||
__except (EFAULT) {}
|
__except (EFAULT) {}
|
||||||
|
@ -535,11 +484,6 @@ mq_open (const char *name, int oflag, ...)
|
||||||
save_errno save;
|
save_errno save;
|
||||||
if (created)
|
if (created)
|
||||||
unlink (mqname);
|
unlink (mqname);
|
||||||
if (mptr)
|
|
||||||
{
|
|
||||||
NtUnmapViewOfSection (NtCurrentProcess (), mptr);
|
|
||||||
NtClose (secth);
|
|
||||||
}
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close (fd);
|
close (fd);
|
||||||
return (mqd_t) -1;
|
return (mqd_t) -1;
|
||||||
|
|
Loading…
Reference in New Issue