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 *_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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 §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
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue