]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/fhandler_mqueue.cc
Cygwin: POSIX msg queues: move IPC object creation into fhandler
[newlib-cygwin.git] / winsup / cygwin / fhandler_mqueue.cc
1 /* fhandler_mqueue.cc: fhandler for POSIX message queue
2
3 This file is part of Cygwin.
4
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
8
9 #include "winsup.h"
10 #include "shared_info.h"
11 #include "path.h"
12 #include "fhandler.h"
13 #include "dtable.h"
14
15 fhandler_mqueue::fhandler_mqueue () :
16 fhandler_base ()
17 {
18 nohandle (true);
19 close_on_exec (true);
20 }
21
22 struct mq_info *
23 fhandler_mqueue::mqinfo (const char *name, int8_t *mptr, HANDLE sect,
24 size_t size, mode_t mode, int flags)
25 {
26 WCHAR buf[MAX_PATH];
27 UNICODE_STRING uname;
28 OBJECT_ATTRIBUTES attr;
29 NTSTATUS status;
30
31 set_name (name);
32 mqinfo ()->mqi_hdr = (struct mq_hdr *) mptr;
33 mqinfo ()->mqi_sect = sect;
34 mqinfo ()->mqi_sectsize = size;
35 mqinfo ()->mqi_mode = mode;
36 mqinfo ()->mqi_flags = flags;
37
38 __small_swprintf (buf, L"mqueue/mtx%s", name);
39 RtlInitUnicodeString (&uname, buf);
40 InitializeObjectAttributes (&attr, &uname, OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
41 get_shared_parent_dir (),
42 everyone_sd (CYG_MUTANT_ACCESS));
43 status = NtCreateMutant (&mqinfo ()->mqi_lock, CYG_MUTANT_ACCESS, &attr,
44 FALSE);
45 if (!NT_SUCCESS (status))
46 goto err;
47
48 wcsncpy (buf + 7, L"snd", 3);
49 /* same length, no RtlInitUnicodeString required */
50 InitializeObjectAttributes (&attr, &uname, OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
51 get_shared_parent_dir (),
52 everyone_sd (CYG_EVENT_ACCESS));
53 status = NtCreateEvent (&mqinfo ()->mqi_waitsend, CYG_EVENT_ACCESS, &attr,
54 NotificationEvent, FALSE);
55 if (!NT_SUCCESS (status))
56 goto err;
57 wcsncpy (buf + 7, L"rcv", 3);
58 /* same length, same attributes, no more init required */
59 status = NtCreateEvent (&mqinfo ()->mqi_waitrecv, CYG_EVENT_ACCESS, &attr,
60 NotificationEvent, FALSE);
61 if (!NT_SUCCESS (status))
62 goto err;
63
64 mqinfo ()->mqi_magic = MQI_MAGIC;
65 return mqinfo ();
66
67 err:
68 if (mqinfo ()->mqi_waitsend)
69 NtClose (mqinfo ()->mqi_waitsend);
70 if (mqinfo ()->mqi_lock)
71 NtClose (mqinfo ()->mqi_lock);
72 __seterrno_from_nt_status (status);
73 return NULL;
74 }
75
76 char *
77 fhandler_mqueue::get_proc_fd_name (char *buf)
78 {
79 return strcpy (buf, get_name ());
80 }
81
82 int __reg2
83 fhandler_mqueue::fstat (struct stat *buf)
84 {
85 int ret = fhandler_base::fstat (buf);
86 if (!ret)
87 {
88 buf->st_mode = S_IFREG | mqinfo ()->mqi_mode;
89 buf->st_dev = FH_MQUEUE;
90 buf->st_ino = hash_path_name (0, get_name ());
91 }
92 return ret;
93 }
94
95 int
96 fhandler_mqueue::dup (fhandler_base *child, int flags)
97 {
98 /* FIXME */
99 set_errno (EBADF);
100 return -1;
101 }
102
103 void
104 fhandler_mqueue::fixup_after_fork (HANDLE parent)
105 {
106 __try
107 {
108 PVOID mptr = NULL;
109 SIZE_T filesize = mqinfo ()->mqi_sectsize;
110 NTSTATUS status;
111
112 DuplicateHandle (parent, mqinfo ()->mqi_sect,
113 GetCurrentProcess (), &mqinfo ()->mqi_sect,
114 0, FALSE, DUPLICATE_SAME_ACCESS);
115 status = NtMapViewOfSection (mqinfo ()->mqi_sect, NtCurrentProcess (),
116 &mptr, 0, filesize, NULL, &filesize,
117 ViewShare, 0, PAGE_READWRITE);
118 if (!NT_SUCCESS (status))
119 api_fatal ("Mapping message queue failed in fork\n");
120 else
121 mqinfo ()->mqi_hdr = (struct mq_hdr *) mptr;
122 DuplicateHandle (parent, mqinfo ()->mqi_waitsend,
123 GetCurrentProcess (), &mqinfo ()->mqi_waitsend,
124 0, FALSE, DUPLICATE_SAME_ACCESS);
125 DuplicateHandle (parent, mqinfo ()->mqi_waitrecv,
126 GetCurrentProcess (), &mqinfo ()->mqi_waitrecv,
127 0, FALSE, DUPLICATE_SAME_ACCESS);
128 DuplicateHandle (parent, mqinfo ()->mqi_lock,
129 GetCurrentProcess (), &mqinfo ()->mqi_lock,
130 0, FALSE, DUPLICATE_SAME_ACCESS);
131 }
132 __except (EFAULT) {}
133 __endtry
134 }
135
136 int
137 fhandler_mqueue::close ()
138 {
139 int ret = -1;
140
141 __try
142 {
143 mqinfo ()->mqi_magic = 0; /* just in case */
144 NtUnmapViewOfSection (NtCurrentProcess (), mqinfo ()->mqi_hdr);
145 NtClose (mqinfo ()->mqi_sect);
146 NtClose (mqinfo ()->mqi_waitsend);
147 NtClose (mqinfo ()->mqi_waitrecv);
148 NtClose (mqinfo ()->mqi_lock);
149 ret = 0;
150 }
151 __except (EFAULT) {}
152 __endtry
153 return ret;
154 }
This page took 0.044641 seconds and 6 git commands to generate.