]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/fhandler_mqueue.cc
5f97264cd28ee6f458444cc425b23433336fdab8
1 /* fhandler_mqueue.cc: fhandler for POSIX message queue
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10 #include "shared_info.h"
15 fhandler_mqueue::fhandler_mqueue () :
23 fhandler_mqueue::_mqinfo (HANDLE fh
, SIZE_T filesize
, mode_t mode
, int flags
,
26 WCHAR buf
[NAME_MAX
+ sizeof ("mqueue/XXX")];
28 OBJECT_ATTRIBUTES attr
;
30 LARGE_INTEGER fsiz
= { QuadPart
: (LONGLONG
) filesize
};
33 /* Set sectsize prior to using filesize in NtMapViewOfSection. It will
34 get pagesize aligned, which breaks the next NtMapViewOfSection in fork. */
35 mqinfo ()->mqi_sectsize
= filesize
;
36 mqinfo ()->mqi_mode
= mode
;
37 mqinfo ()->mqi_flags
= flags
;
39 __small_swprintf (buf
, L
"mqueue/mtx%s", get_name ());
40 RtlInitUnicodeString (&uname
, buf
);
41 InitializeObjectAttributes (&attr
, &uname
, OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
42 get_shared_parent_dir (),
43 everyone_sd (CYG_MUTANT_ACCESS
));
44 status
= NtCreateMutant (&mqinfo ()->mqi_lock
, CYG_MUTANT_ACCESS
, &attr
,
46 if (!NT_SUCCESS (status
))
49 wcsncpy (buf
+ 7, L
"snd", 3);
50 /* same length, no RtlInitUnicodeString required */
51 InitializeObjectAttributes (&attr
, &uname
, OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
52 get_shared_parent_dir (),
53 everyone_sd (CYG_EVENT_ACCESS
));
54 status
= NtCreateEvent (&mqinfo ()->mqi_waitsend
, CYG_EVENT_ACCESS
, &attr
,
55 NotificationEvent
, FALSE
);
56 if (!NT_SUCCESS (status
))
58 wcsncpy (buf
+ 7, L
"rcv", 3);
59 /* same length, same attributes, no more init required */
60 status
= NtCreateEvent (&mqinfo ()->mqi_waitrecv
, CYG_EVENT_ACCESS
, &attr
,
61 NotificationEvent
, FALSE
);
62 if (!NT_SUCCESS (status
))
65 InitializeObjectAttributes (&attr
, NULL
, 0, NULL
, NULL
);
66 status
= NtCreateSection (&mqinfo ()->mqi_sect
, SECTION_ALL_ACCESS
, &attr
,
67 &fsiz
, PAGE_READWRITE
, SEC_COMMIT
, fh
);
68 if (!NT_SUCCESS (status
))
71 status
= NtMapViewOfSection (mqinfo ()->mqi_sect
, NtCurrentProcess (),
72 &mptr
, 0, filesize
, NULL
, &filesize
,
73 ViewShare
, 0, PAGE_READWRITE
);
74 if (!NT_SUCCESS (status
))
77 mqinfo ()->mqi_hdr
= (struct mq_hdr
*) mptr
;
79 /* Special problem on Cygwin. /dev/mqueue is just a simple dir,
80 so there's a chance normal files are created in there. */
81 if (just_open
&& mqinfo ()->mqi_hdr
->mqh_magic
!= MQI_MAGIC
)
83 status
= STATUS_ACCESS_DENIED
;
87 mqinfo ()->mqi_magic
= MQI_MAGIC
;
91 if (mqinfo ()->mqi_sect
)
92 NtClose (mqinfo ()->mqi_sect
);
93 if (mqinfo ()->mqi_waitrecv
)
94 NtClose (mqinfo ()->mqi_waitrecv
);
95 if (mqinfo ()->mqi_waitsend
)
96 NtClose (mqinfo ()->mqi_waitsend
);
97 if (mqinfo ()->mqi_lock
)
98 NtClose (mqinfo ()->mqi_lock
);
99 __seterrno_from_nt_status (status
);
104 fhandler_mqueue::get_proc_fd_name (char *buf
)
106 return strcpy (buf
, get_name ());
110 fhandler_mqueue::fstat (struct stat
*buf
)
112 int ret
= fhandler_base::fstat (buf
);
115 buf
->st_mode
= S_IFREG
| mqinfo ()->mqi_mode
;
116 buf
->st_dev
= FH_MQUEUE
;
117 buf
->st_ino
= hash_path_name (0, get_name ());
123 fhandler_mqueue::dup (fhandler_base
*child
, int flags
)
131 fhandler_mqueue::fixup_after_fork (HANDLE parent
)
136 SIZE_T filesize
= mqinfo ()->mqi_sectsize
;
139 if (!DuplicateHandle (parent
, mqinfo ()->mqi_sect
,
140 GetCurrentProcess (), &mqinfo ()->mqi_sect
,
141 0, FALSE
, DUPLICATE_SAME_ACCESS
))
143 status
= NtMapViewOfSection (mqinfo ()->mqi_sect
, NtCurrentProcess (),
144 &mptr
, 0, filesize
, NULL
, &filesize
,
145 ViewShare
, 0, PAGE_READWRITE
);
146 if (!NT_SUCCESS (status
))
147 api_fatal ("Mapping message queue failed in fork, status 0x%x\n",
150 mqinfo ()->mqi_hdr
= (struct mq_hdr
*) mptr
;
151 if (!DuplicateHandle (parent
, mqinfo ()->mqi_waitsend
,
152 GetCurrentProcess (), &mqinfo ()->mqi_waitsend
,
153 0, FALSE
, DUPLICATE_SAME_ACCESS
))
155 if (!DuplicateHandle (parent
, mqinfo ()->mqi_waitrecv
,
156 GetCurrentProcess (), &mqinfo ()->mqi_waitrecv
,
157 0, FALSE
, DUPLICATE_SAME_ACCESS
))
159 if (!DuplicateHandle (parent
, mqinfo ()->mqi_lock
,
160 GetCurrentProcess (), &mqinfo ()->mqi_lock
,
161 0, FALSE
, DUPLICATE_SAME_ACCESS
))
167 api_fatal ("Creating IPC object failed in fork, %E");
171 fhandler_mqueue::close ()
177 mqinfo ()->mqi_magic
= 0; /* just in case */
178 NtUnmapViewOfSection (NtCurrentProcess (), mqinfo ()->mqi_hdr
);
179 NtClose (mqinfo ()->mqi_sect
);
180 NtClose (mqinfo ()->mqi_waitsend
);
181 NtClose (mqinfo ()->mqi_waitrecv
);
182 NtClose (mqinfo ()->mqi_lock
);
This page took 0.04275 seconds and 4 git commands to generate.