Cygwin: pinfo: use stpcpy where appropriate
[newlib-cygwin.git] / winsup / cygwin / fhandler / windows.cc
blob90ab48daafe59af100c093c3f3bcbecf29fba81c
1 /* fhandler_windows.cc: code to access windows message queues.
3 Written by Sergey S. Okhapkin (sos@prospect.com.ru).
4 Feedback and testing by Andy Piper (andyp@parallax.co.uk).
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10 details. */
12 #include "winsup.h"
13 #include "cygerrno.h"
14 #include "path.h"
15 #include "fhandler.h"
16 #include "sigproc.h"
17 #include "thread.h"
21 The following unix-style calls are supported:
23 open ("/dev/windows", flags, mode=0)
24 - create a unix fd for message queue.
26 read (fd, buf, len)
27 - return next message from queue. buf must point to MSG
28 structure, len must be >= sizeof (MSG). If read is set to
29 non-blocking and the queue is empty, read call returns -1
30 immediately with errno set to EAGAIN, otherwise it blocks
31 untill the message will be received.
33 write (fd, buf, len)
34 - send a message pointed by buf. len argument ignored.
36 ioctl (fd, command, *param)
37 - control read()/write() behavior.
38 ioctl (fd, WINDOWS_POST, NULL): write() will PostMessage();
39 ioctl (fd, WINDOWS_SEND, NULL): write() will SendMessage();
40 ioctl (fd, WINDOWS_HWND, &hWnd): read() messages for
41 hWnd window.
43 select () call marks read fd when any message posted to queue.
46 fhandler_windows::fhandler_windows ()
47 : fhandler_base (), hWnd_ (NULL), method_ (WINDOWS_POST)
51 int
52 fhandler_windows::open (int flags, mode_t mode)
54 return fhandler_base::open ((flags & ~O_TEXT) | O_BINARY, mode);
57 ssize_t
58 fhandler_windows::write (const void *buf, size_t)
60 MSG *ptr = (MSG *) buf;
62 if (method_ == WINDOWS_POST)
64 if (!PostMessageW (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam))
66 __seterrno ();
67 return -1;
70 else if (!SendNotifyMessageW (ptr->hwnd, ptr->message, ptr->wParam,
71 ptr->lParam))
73 __seterrno ();
74 return -1;
76 return sizeof (MSG);
79 void
80 fhandler_windows::read (void *buf, size_t& len)
82 MSG *ptr = (MSG *) buf;
84 if (len < sizeof (MSG))
86 set_errno (EINVAL);
87 len = (size_t) -1;
88 return;
91 HANDLE w4[2];
92 wait_signal_arrived here (w4[0]);
93 DWORD cnt = 1;
94 if ((w4[1] = pthread::get_cancel_event ()) != NULL)
95 ++cnt;
96 for (;;)
98 switch (MsgWaitForMultipleObjectsEx (cnt, w4,
99 is_nonblocking () ? 0 : INFINITE,
100 QS_ALLINPUT | QS_ALLPOSTMESSAGE,
101 MWMO_INPUTAVAILABLE))
103 case WAIT_OBJECT_0:
104 if (_my_tls.call_signal_handler ())
105 continue;
106 len = (size_t) -1;
107 set_errno (EINTR);
108 break;
109 case WAIT_OBJECT_0 + 1:
110 if (cnt > 1) /* WAIT_OBJECT_0 + 1 is the cancel event object. */
112 pthread::static_cancel_self ();
113 break;
115 fallthrough;
116 case WAIT_OBJECT_0 + 2:
117 if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
119 len = (size_t) -1;
120 __seterrno ();
122 else if (ptr->message == WM_QUIT)
123 len = 0;
124 else
125 len = sizeof (MSG);
126 break;
127 case WAIT_TIMEOUT:
128 len = (size_t) -1;
129 set_errno (EAGAIN);
130 break;
131 default:
132 len = (size_t) -1;
133 __seterrno ();
134 break;
136 break;
141 fhandler_windows::ioctl (unsigned int cmd, void *val)
143 switch (cmd)
145 case WINDOWS_POST:
146 case WINDOWS_SEND:
147 method_ = cmd;
148 break;
149 case WINDOWS_HWND:
150 if (val == NULL)
152 set_errno (EINVAL);
153 return -1;
155 hWnd_ = * ((HWND *) val);
156 break;
157 default:
158 return fhandler_base::ioctl (cmd, val);
160 return 0;