]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/fhandler_windows.cc
Throughout, update copyrights to reflect dates which correspond to main-branch
[newlib-cygwin.git] / winsup / cygwin / fhandler_windows.cc
CommitLineData
1fd5e000
CF
1/* fhandler_windows.cc: code to access windows message queues.
2
bc837d22
CF
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012
4 Red Hat, Inc.
1fd5e000
CF
5
6 Written by Sergey S. Okhapkin (sos@prospect.com.ru).
7 Feedback and testing by Andy Piper (andyp@parallax.co.uk).
8
9This file is part of Cygwin.
10
11This software is a copyrighted work licensed under the terms of the
12Cygwin license. Please consult the file "CYGWIN_LICENSE" for
13details. */
14
1fd5e000 15#include "winsup.h"
d0b178fe
DD
16#include <wingdi.h>
17#include <winuser.h>
9e2baf8d 18#include "cygerrno.h"
7ac61736 19#include "path.h"
bccd5e0d 20#include "fhandler.h"
79e741ef
CV
21#include "sigproc.h"
22#include "thread.h"
23
1fd5e000
CF
24
25/*
26The following unix-style calls are supported:
27
28 open ("/dev/windows", flags, mode=0)
29 - create a unix fd for message queue.
1fd5e000
CF
30
31 read (fd, buf, len)
32 - return next message from queue. buf must point to MSG
33 structure, len must be >= sizeof (MSG). If read is set to
34 non-blocking and the queue is empty, read call returns -1
35 immediately with errno set to EAGAIN, otherwise it blocks
36 untill the message will be received.
37
38 write (fd, buf, len)
39 - send a message pointed by buf. len argument ignored.
40
41 ioctl (fd, command, *param)
42 - control read()/write() behavior.
43 ioctl (fd, WINDOWS_POST, NULL): write() will PostMessage();
44 ioctl (fd, WINDOWS_SEND, NULL): write() will SendMessage();
45 ioctl (fd, WINDOWS_HWND, &hWnd): read() messages for
46 hWnd window.
47
48 select () call marks read fd when any message posted to queue.
49*/
50
0476bae5 51fhandler_windows::fhandler_windows ()
7ac61736 52 : fhandler_base (), hWnd_ (NULL), method_ (WINDOWS_POST)
1fd5e000 53{
1fd5e000
CF
54}
55
56int
7ac61736 57fhandler_windows::open (int flags, mode_t)
1fd5e000 58{
1bc9effd 59 set_flags ((flags & ~O_TEXT) | O_BINARY);
56551a9b 60 close_on_exec (true);
f3ea62a8 61 set_open_status ();
1fd5e000
CF
62 return 1;
63}
64
43c23d4b 65ssize_t __stdcall
1fd5e000
CF
66fhandler_windows::write (const void *buf, size_t)
67{
68 MSG *ptr = (MSG *) buf;
69
70 if (method_ == WINDOWS_POST)
71 {
79e741ef 72 if (!PostMessageW (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam))
1fd5e000
CF
73 {
74 __seterrno ();
75 return -1;
76 }
1fd5e000 77 }
79e741ef
CV
78 else if (!SendNotifyMessageW (ptr->hwnd, ptr->message, ptr->wParam,
79 ptr->lParam))
80 {
81 __seterrno ();
82 return -1;
83 }
84 return sizeof (MSG);
1fd5e000
CF
85}
86
8bce0d72
CF
87void __stdcall
88fhandler_windows::read (void *buf, size_t& len)
1fd5e000
CF
89{
90 MSG *ptr = (MSG *) buf;
1fd5e000
CF
91
92 if (len < sizeof (MSG))
93 {
94 set_errno (EINVAL);
6cce721b 95 len = (size_t) -1;
8bce0d72 96 return;
1fd5e000
CF
97 }
98
962f9a2c 99 HANDLE w4[3] = { get_handle (), };
44aa2292 100 set_signal_arrived here (w4[1]);
79e741ef 101 DWORD cnt = 2;
a91ac4dc
CV
102 if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
103 ++cnt;
962f9a2c 104 for (;;)
79e741ef 105 {
962f9a2c
CF
106 switch (MsgWaitForMultipleObjectsEx (cnt, w4,
107 is_nonblocking () ? 0 : INFINITE,
108 QS_ALLINPUT | QS_ALLPOSTMESSAGE,
109 MWMO_INPUTAVAILABLE))
79e741ef 110 {
962f9a2c
CF
111 case WAIT_OBJECT_0:
112 if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
113 {
114 len = (size_t) -1;
115 __seterrno ();
116 }
117 else if (ptr->message == WM_QUIT)
118 len = 0;
119 else
120 len = sizeof (MSG);
121 break;
122 case WAIT_OBJECT_0 + 1:
123 if (_my_tls.call_signal_handler ())
124 continue;
125 len = (size_t) -1;
126 set_errno (EINTR);
127 break;
128 case WAIT_OBJECT_0 + 2:
129 pthread::static_cancel_self ();
130 break;
131 case WAIT_TIMEOUT:
132 len = (size_t) -1;
133 set_errno (EAGAIN);
134 break;
135 default:
79e741ef
CV
136 len = (size_t) -1;
137 __seterrno ();
962f9a2c 138 break;
79e741ef 139 }
79e741ef
CV
140 break;
141 }
1fd5e000
CF
142}
143
144int
145fhandler_windows::ioctl (unsigned int cmd, void *val)
146{
147 switch (cmd)
148 {
149 case WINDOWS_POST:
150 case WINDOWS_SEND:
151 method_ = cmd;
152 break;
153 case WINDOWS_HWND:
154 if (val == NULL)
155 {
156 set_errno (EINVAL);
157 return -1;
158 }
159 hWnd_ = * ((HWND *) val);
160 break;
161 default:
e9b5cc32 162 return fhandler_base::ioctl (cmd, val);
1fd5e000
CF
163 }
164 return 0;
165}
166
167void
56551a9b 168fhandler_windows::set_close_on_exec (bool val)
1fd5e000
CF
169{
170 if (get_handle ())
335556d5 171 fhandler_base::set_close_on_exec (val);
1fd5e000 172 else
56551a9b 173 fhandler_base::close_on_exec (val);
1fd5e000
CF
174 void *h = hWnd_;
175 if (h)
6027d26d 176 set_no_inheritance (h, val);
1fd5e000
CF
177}
178
179void
180fhandler_windows::fixup_after_fork (HANDLE parent)
181{
182 if (get_handle ())
335556d5 183 fhandler_base::fixup_after_fork (parent);
1fd5e000
CF
184 void *h = hWnd_;
185 if (h)
186 fork_fixup (parent, h, "hWnd_");
187}
This page took 0.405501 seconds and 5 git commands to generate.