nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * giowin32.c: IO Channels for Win32.
5 * Copyright 1998 Owen Taylor and Tor Lillqvist
6 * Copyright 1999-2000 Tor Lillqvist and Craig Setera
7 * Copyright 2001-2003 Andrew Lanoix
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 */
22  
23 /*
24 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GLib Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GLib at ftp://ftp.gtk.org/pub/gtk/.
28 */
29  
30 /*
31 * Bugs that are related to the code in this file:
32 *
33 * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition
34 * http://bugzilla.gnome.org/show_bug.cgi?id=137968
35 *
36 * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely
37 * http://bugzilla.gnome.org/show_bug.cgi?id=324234
38 *
39 * Bug 331214 - g_io_channel async socket io stalls
40 * http://bugzilla.gnome.org/show_bug.cgi?id=331214
41 *
42 * Bug 338943 - Multiple watches on the same socket
43 * http://bugzilla.gnome.org/show_bug.cgi?id=338943
44 *
45 * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless
46 * http://bugzilla.gnome.org/show_bug.cgi?id=357674
47 *
48 * Bug 425156 - GIOChannel deadlocks on a win32 socket
49 * http://bugzilla.gnome.org/show_bug.cgi?id=425156
50 *
51 * Bug 468910 - giofunc condition=0
52 * http://bugzilla.gnome.org/show_bug.cgi?id=468910
53 *
54 * Bug 500246 - Bug fixes for giowin32
55 * http://bugzilla.gnome.org/show_bug.cgi?id=500246
56 *
57 * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows
58 * http://bugzilla.gnome.org/show_bug.cgi?id=548278
59 *
60 * Bug 548536 - giowin32 problem when adding and removing watches
61 * http://bugzilla.gnome.org/show_bug.cgi?id=548536
62 *
63 * When fixing bugs related to the code in this file, either the above
64 * bugs or others, make sure that the test programs attached to the
65 * above bugs continue to work.
66 */
67  
68 #include "config.h"
69  
70 #include "glib.h"
71  
72 #include <stdlib.h>
73 #include <winsock2.h>
74 #include <windows.h>
75 #include <conio.h>
76 #include <fcntl.h>
77 #include <io.h>
78 #include <process.h>
79 #include <errno.h>
80 #include <sys/stat.h>
81  
82 #include "gstdio.h"
83 #include "glibintl.h"
84  
85  
86 typedef struct _GIOWin32Channel GIOWin32Channel;
87 typedef struct _GIOWin32Watch GIOWin32Watch;
88  
89 #define BUFFER_SIZE 4096
90  
91 typedef enum {
92 G_IO_WIN32_WINDOWS_MESSAGES, /* Windows messages */
93  
94 G_IO_WIN32_FILE_DESC, /* Unix-like file descriptors from
95 * _open() or _pipe(), except for
96 * console IO. Separate thread to read
97 * or write.
98 */
99  
100 G_IO_WIN32_CONSOLE, /* Console IO (usually stdin, stdout, stderr) */
101  
102 G_IO_WIN32_SOCKET /* Sockets. No separate thread. */
103 } GIOWin32ChannelType;
104  
105 struct _GIOWin32Channel {
106 GIOChannel channel;
107 gint fd; /* Either a Unix-like file handle as provided
108 * by the Microsoft C runtime, or a SOCKET
109 * as provided by WinSock.
110 */
111 GIOWin32ChannelType type;
112  
113 gboolean debug;
114  
115 /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */
116 HWND hwnd; /* Handle of window, or NULL */
117  
118 /* Fields used by G_IO_WIN32_FILE_DESC channels. */
119 CRITICAL_SECTION mutex;
120  
121 int direction; /* 0 means we read from it,
122 * 1 means we write to it.
123 */
124  
125 gboolean running; /* Is reader or writer thread
126 * running. FALSE if EOF has been
127 * reached by the reader thread.
128 */
129  
130 gboolean needs_close; /* If the channel has been closed while
131 * the reader thread was still running.
132 */
133  
134 guint thread_id; /* If non-NULL the channel has or has
135 * had a reader or writer thread.
136 */
137 HANDLE data_avail_event;
138  
139 gushort revents;
140  
141 /* Data is kept in a circular buffer. To be able to distinguish between
142 * empty and full buffers, we cannot fill it completely, but have to
143 * leave a one character gap.
144 *
145 * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
146 *
147 * Empty: wrp == rdp
148 * Full: (wrp + 1) % BUFFER_SIZE == rdp
149 * Partial: otherwise
150 */
151 guchar *buffer; /* (Circular) buffer */
152 gint wrp, rdp; /* Buffer indices for writing and reading */
153 HANDLE space_avail_event;
154  
155 /* Fields used by G_IO_WIN32_SOCKET channels */
156 int event_mask;
157 int last_events;
158 HANDLE event;
159 gboolean write_would_have_blocked;
160 gboolean ever_writable;
161 };
162  
163 struct _GIOWin32Watch {
164 GSource source;
165 GPollFD pollfd;
166 GIOChannel *channel;
167 GIOCondition condition;
168 };
169  
170 static void
171 g_win32_print_access_mode (int flags)
172 {
173 g_print ("%s%s%s%s%s%s%s%s%s%s",
174 ((flags & 0x3) == _O_RDWR ? "O_RDWR" :
175 ((flags & 0x3) == _O_RDONLY ? "O_RDONLY" :
176 ((flags & 0x3) == _O_WRONLY ? "O_WRONLY" : "0"))),
177 (flags & _O_APPEND ? "|O_APPEND" : ""),
178 (flags & _O_RANDOM ? "|O_RANDOM" : ""),
179 (flags & _O_SEQUENTIAL ? "|O_SEQUENTIAL" : ""),
180 (flags & _O_TEMPORARY ? "|O_TEMPORARY" : ""),
181 (flags & _O_CREAT ? "|O_CREAT" : ""),
182 (flags & _O_TRUNC ? "|O_TRUNC" : ""),
183 (flags & _O_EXCL ? "|O_EXCL" : ""),
184 (flags & _O_TEXT ? "|O_TEXT" : ""),
185 (flags & _O_BINARY ? "|O_BINARY" : ""));
186 }
187  
188 static void
189 g_win32_print_gioflags (GIOFlags flags)
190 {
191 char *bar = "";
192  
193 if (flags & G_IO_FLAG_APPEND)
194 bar = "|", g_print ("APPEND");
195 if (flags & G_IO_FLAG_NONBLOCK)
196 g_print ("%sNONBLOCK", bar), bar = "|";
197 if (flags & G_IO_FLAG_IS_READABLE)
198 g_print ("%sREADABLE", bar), bar = "|";
199 if (flags & G_IO_FLAG_IS_WRITABLE)
200 g_print ("%sWRITABLE", bar), bar = "|";
201 if (flags & G_IO_FLAG_IS_SEEKABLE)
202 g_print ("%sSEEKABLE", bar), bar = "|";
203 }
204  
205 static const char *
206 event_mask_to_string (int mask)
207 {
208 char buf[100];
209 int checked_bits = 0;
210 char *bufp = buf;
211  
212 if (mask == 0)
213 return "";
214  
215 #define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
216  
217 BIT (READ);
218 BIT (WRITE);
219 BIT (OOB);
220 BIT (ACCEPT);
221 BIT (CONNECT);
222 BIT (CLOSE);
223 BIT (QOS);
224 BIT (GROUP_QOS);
225 BIT (ROUTING_INTERFACE_CHANGE);
226 BIT (ADDRESS_LIST_CHANGE);
227  
228 #undef BIT
229  
230 if ((mask & ~checked_bits) != 0)
231 bufp += sprintf (bufp, "|%#x", mask & ~checked_bits);
232  
233 return g_quark_to_string (g_quark_from_string (buf));
234 }
235  
236 static const char *
237 condition_to_string (GIOCondition condition)
238 {
239 char buf[100];
240 int checked_bits = 0;
241 char *bufp = buf;
242  
243 if (condition == 0)
244 return "";
245  
246 #define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
247  
248 BIT (IN);
249 BIT (OUT);
250 BIT (PRI);
251 BIT (ERR);
252 BIT (HUP);
253 BIT (NVAL);
254  
255 #undef BIT
256  
257 if ((condition & ~checked_bits) != 0)
258 bufp += sprintf (bufp, "|%#x", condition & ~checked_bits);
259  
260 return g_quark_to_string (g_quark_from_string (buf));
261 }
262  
263 static gboolean
264 g_io_win32_get_debug_flag (void)
265 {
266 return (getenv ("G_IO_WIN32_DEBUG") != NULL);
267 }
268  
269 static void
270 g_io_channel_win32_init (GIOWin32Channel *channel)
271 {
272 channel->debug = g_io_win32_get_debug_flag ();
273  
274 InitializeCriticalSection (&channel->mutex);
275 channel->running = FALSE;
276 channel->needs_close = FALSE;
277 channel->thread_id = 0;
278 channel->data_avail_event = NULL;
279 channel->revents = 0;
280 channel->buffer = NULL;
281 channel->space_avail_event = NULL;
282  
283 channel->event_mask = 0;
284 channel->last_events = 0;
285 channel->event = NULL;
286 channel->write_would_have_blocked = FALSE;
287 channel->ever_writable = FALSE;
288 }
289  
290 static void
291 create_events (GIOWin32Channel *channel)
292 {
293 SECURITY_ATTRIBUTES sec_attrs;
294  
295 sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
296 sec_attrs.lpSecurityDescriptor = NULL;
297 sec_attrs.bInheritHandle = FALSE;
298  
299 /* The data available event is manual reset, the space available event
300 * is automatic reset.
301 */
302 if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
303 || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
304 {
305 gchar *emsg = g_win32_error_message (GetLastError ());
306  
307 g_error ("Error creating event: %s", emsg);
308 g_free (emsg);
309 }
310 }
311  
312 static unsigned __stdcall
313 read_thread (void *parameter)
314 {
315 GIOWin32Channel *channel = parameter;
316 guchar *buffer;
317 gint nbytes;
318  
319 g_io_channel_ref ((GIOChannel *)channel);
320  
321 if (channel->debug)
322 g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
323 channel->thread_id,
324 channel->fd,
325 channel->data_avail_event,
326 channel->space_avail_event);
327  
328 channel->direction = 0;
329 channel->buffer = g_malloc (BUFFER_SIZE);
330 channel->rdp = channel->wrp = 0;
331 channel->running = TRUE;
332  
333 SetEvent (channel->space_avail_event);
334  
335 EnterCriticalSection (&channel->mutex);
336 while (channel->running)
337 {
338 if (channel->debug)
339 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
340 channel->thread_id, channel->rdp, channel->wrp);
341 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
342 {
343 /* Buffer is full */
344 if (channel->debug)
345 g_print ("read_thread %#x: resetting space_avail\n",
346 channel->thread_id);
347 ResetEvent (channel->space_avail_event);
348 if (channel->debug)
349 g_print ("read_thread %#x: waiting for space\n",
350 channel->thread_id);
351 LeaveCriticalSection (&channel->mutex);
352 WaitForSingleObject (channel->space_avail_event, INFINITE);
353 EnterCriticalSection (&channel->mutex);
354 if (channel->debug)
355 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
356 channel->thread_id, channel->rdp, channel->wrp);
357 }
358  
359 buffer = channel->buffer + channel->wrp;
360  
361 /* Always leave at least one byte unused gap to be able to
362 * distinguish between the full and empty condition...
363 */
364 nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
365 BUFFER_SIZE - channel->wrp);
366  
367 if (channel->debug)
368 g_print ("read_thread %#x: calling read() for %d bytes\n",
369 channel->thread_id, nbytes);
370  
371 LeaveCriticalSection (&channel->mutex);
372  
373 nbytes = read (channel->fd, buffer, nbytes);
374  
375 EnterCriticalSection (&channel->mutex);
376  
377 channel->revents = G_IO_IN;
378 if (nbytes == 0)
379 channel->revents |= G_IO_HUP;
380 else if (nbytes < 0)
381 channel->revents |= G_IO_ERR;
382  
383 if (channel->debug)
384 g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
385 channel->thread_id, nbytes, channel->rdp, channel->wrp);
386  
387 if (nbytes <= 0)
388 break;
389  
390 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
391 if (channel->debug)
392 g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
393 channel->thread_id, channel->rdp, channel->wrp);
394 SetEvent (channel->data_avail_event);
395 }
396  
397 channel->running = FALSE;
398 if (channel->needs_close)
399 {
400 if (channel->debug)
401 g_print ("read_thread %#x: channel fd %d needs closing\n",
402 channel->thread_id, channel->fd);
403 close (channel->fd);
404 channel->fd = -1;
405 }
406  
407 if (channel->debug)
408 g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
409 channel->thread_id, channel->rdp, channel->wrp);
410 SetEvent (channel->data_avail_event);
411 LeaveCriticalSection (&channel->mutex);
412  
413 g_io_channel_unref ((GIOChannel *)channel);
414  
415 /* No need to call _endthreadex(), the actual thread starter routine
416 * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
417 * _endthreadex() for us.
418 */
419  
420 return 0;
421 }
422  
423 static unsigned __stdcall
424 write_thread (void *parameter)
425 {
426 GIOWin32Channel *channel = parameter;
427 guchar *buffer;
428 gint nbytes;
429  
430 g_io_channel_ref ((GIOChannel *)channel);
431  
432 if (channel->debug)
433 g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
434 channel->thread_id,
435 channel->fd,
436 channel->data_avail_event,
437 channel->space_avail_event);
438  
439 channel->direction = 1;
440 channel->buffer = g_malloc (BUFFER_SIZE);
441 channel->rdp = channel->wrp = 0;
442 channel->running = TRUE;
443  
444 SetEvent (channel->space_avail_event);
445  
446 /* We use the same event objects as for a reader thread, but with
447 * reversed meaning. So, space_avail is used if data is available
448 * for writing, and data_avail is used if space is available in the
449 * write buffer.
450 */
451  
452 EnterCriticalSection (&channel->mutex);
453 while (channel->running || channel->rdp != channel->wrp)
454 {
455 if (channel->debug)
456 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
457 channel->thread_id, channel->rdp, channel->wrp);
458 if (channel->wrp == channel->rdp)
459 {
460 /* Buffer is empty. */
461 if (channel->debug)
462 g_print ("write_thread %#x: resetting space_avail\n",
463 channel->thread_id);
464 ResetEvent (channel->space_avail_event);
465 if (channel->debug)
466 g_print ("write_thread %#x: waiting for data\n",
467 channel->thread_id);
468 channel->revents = G_IO_OUT;
469 SetEvent (channel->data_avail_event);
470 LeaveCriticalSection (&channel->mutex);
471 WaitForSingleObject (channel->space_avail_event, INFINITE);
472  
473 EnterCriticalSection (&channel->mutex);
474 if (channel->rdp == channel->wrp)
475 break;
476  
477 if (channel->debug)
478 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
479 channel->thread_id, channel->rdp, channel->wrp);
480 }
481  
482 buffer = channel->buffer + channel->rdp;
483 if (channel->rdp < channel->wrp)
484 nbytes = channel->wrp - channel->rdp;
485 else
486 nbytes = BUFFER_SIZE - channel->rdp;
487  
488 if (channel->debug)
489 g_print ("write_thread %#x: calling write() for %d bytes\n",
490 channel->thread_id, nbytes);
491  
492 LeaveCriticalSection (&channel->mutex);
493 nbytes = write (channel->fd, buffer, nbytes);
494 EnterCriticalSection (&channel->mutex);
495  
496 if (channel->debug)
497 g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
498 channel->thread_id, channel->fd, nbytes, channel->rdp, channel->wrp);
499  
500 channel->revents = 0;
501 if (nbytes > 0)
502 channel->revents |= G_IO_OUT;
503 else if (nbytes <= 0)
504 channel->revents |= G_IO_ERR;
505  
506 channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
507  
508 if (nbytes <= 0)
509 break;
510  
511 if (channel->debug)
512 g_print ("write_thread: setting data_avail for thread %#x\n",
513 channel->thread_id);
514 SetEvent (channel->data_avail_event);
515 }
516  
517 channel->running = FALSE;
518 if (channel->needs_close)
519 {
520 if (channel->debug)
521 g_print ("write_thread %#x: channel fd %d needs closing\n",
522 channel->thread_id, channel->fd);
523 close (channel->fd);
524 channel->fd = -1;
525 }
526  
527 LeaveCriticalSection (&channel->mutex);
528  
529 g_io_channel_unref ((GIOChannel *)channel);
530  
531 return 0;
532 }
533  
534 static void
535 create_thread (GIOWin32Channel *channel,
536 GIOCondition condition,
537 unsigned (__stdcall *thread) (void *parameter))
538 {
539 HANDLE thread_handle;
540  
541 thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
542 &channel->thread_id);
543 if (thread_handle == 0)
544 g_warning ("Error creating thread: %s.",
545 g_strerror (errno));
546 else if (!CloseHandle (thread_handle))
547 {
548 gchar *emsg = g_win32_error_message (GetLastError ());
549  
550 g_warning ("Error closing thread handle: %s.", emsg);
551 g_free (emsg);
552 }
553  
554 WaitForSingleObject (channel->space_avail_event, INFINITE);
555 }
556  
557 static GIOStatus
558 buffer_read (GIOWin32Channel *channel,
559 gchar *dest,
560 gsize count,
561 gsize *bytes_read,
562 GError **err)
563 {
564 guint nbytes;
565 guint left = count;
566  
567 EnterCriticalSection (&channel->mutex);
568 if (channel->debug)
569 g_print ("reading from thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
570 channel->thread_id, count, channel->rdp, channel->wrp);
571  
572 if (channel->wrp == channel->rdp)
573 {
574 LeaveCriticalSection (&channel->mutex);
575 if (channel->debug)
576 g_print ("waiting for data from thread %#x\n", channel->thread_id);
577 WaitForSingleObject (channel->data_avail_event, INFINITE);
578 if (channel->debug)
579 g_print ("done waiting for data from thread %#x\n", channel->thread_id);
580 EnterCriticalSection (&channel->mutex);
581 if (channel->wrp == channel->rdp && !channel->running)
582 {
583 if (channel->debug)
584 g_print ("wrp==rdp, !running\n");
585 LeaveCriticalSection (&channel->mutex);
586 *bytes_read = 0;
587 return G_IO_STATUS_EOF;
588 }
589 }
590  
591 if (channel->rdp < channel->wrp)
592 nbytes = channel->wrp - channel->rdp;
593 else
594 nbytes = BUFFER_SIZE - channel->rdp;
595 LeaveCriticalSection (&channel->mutex);
596 nbytes = MIN (left, nbytes);
597 if (channel->debug)
598 g_print ("moving %d bytes from thread %#x\n",
599 nbytes, channel->thread_id);
600 memcpy (dest, channel->buffer + channel->rdp, nbytes);
601 dest += nbytes;
602 left -= nbytes;
603 EnterCriticalSection (&channel->mutex);
604 channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
605 if (channel->debug)
606 g_print ("setting space_avail for thread %#x\n", channel->thread_id);
607 SetEvent (channel->space_avail_event);
608 if (channel->debug)
609 g_print ("for thread %#x: rdp=%d, wrp=%d\n",
610 channel->thread_id, channel->rdp, channel->wrp);
611 if (channel->running && channel->wrp == channel->rdp)
612 {
613 if (channel->debug)
614 g_print ("resetting data_avail of thread %#x\n",
615 channel->thread_id);
616 ResetEvent (channel->data_avail_event);
617 };
618 LeaveCriticalSection (&channel->mutex);
619  
620 /* We have no way to indicate any errors form the actual
621 * read() or recv() call in the reader thread. Should we have?
622 */
623 *bytes_read = count - left;
624 return (*bytes_read > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
625 }
626  
627  
628 static GIOStatus
629 buffer_write (GIOWin32Channel *channel,
630 const gchar *dest,
631 gsize count,
632 gsize *bytes_written,
633 GError **err)
634 {
635 guint nbytes;
636 guint left = count;
637  
638 EnterCriticalSection (&channel->mutex);
639 if (channel->debug)
640 g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
641 channel->thread_id, count, channel->rdp, channel->wrp);
642  
643 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
644 {
645 /* Buffer is full */
646 if (channel->debug)
647 g_print ("buffer_write: tid %#x: resetting data_avail\n",
648 channel->thread_id);
649 ResetEvent (channel->data_avail_event);
650 if (channel->debug)
651 g_print ("buffer_write: tid %#x: waiting for space\n",
652 channel->thread_id);
653 LeaveCriticalSection (&channel->mutex);
654 WaitForSingleObject (channel->data_avail_event, INFINITE);
655 EnterCriticalSection (&channel->mutex);
656 if (channel->debug)
657 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
658 channel->thread_id, channel->rdp, channel->wrp);
659 }
660  
661 nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
662 BUFFER_SIZE - channel->wrp);
663  
664 LeaveCriticalSection (&channel->mutex);
665 nbytes = MIN (left, nbytes);
666 if (channel->debug)
667 g_print ("buffer_write: tid %#x: writing %d bytes\n",
668 channel->thread_id, nbytes);
669 memcpy (channel->buffer + channel->wrp, dest, nbytes);
670 dest += nbytes;
671 left -= nbytes;
672 EnterCriticalSection (&channel->mutex);
673  
674 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
675 if (channel->debug)
676 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
677 channel->thread_id, channel->rdp, channel->wrp);
678 SetEvent (channel->space_avail_event);
679  
680 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
681 {
682 /* Buffer is full */
683 if (channel->debug)
684 g_print ("buffer_write: tid %#x: resetting data_avail\n",
685 channel->thread_id);
686 ResetEvent (channel->data_avail_event);
687 }
688  
689 LeaveCriticalSection (&channel->mutex);
690  
691 /* We have no way to indicate any errors form the actual
692 * write() call in the writer thread. Should we have?
693 */
694 *bytes_written = count - left;
695 return (*bytes_written > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
696 }
697  
698  
699 static gboolean
700 g_io_win32_prepare (GSource *source,
701 gint *timeout)
702 {
703 GIOWin32Watch *watch = (GIOWin32Watch *)source;
704 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
705 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
706 int event_mask;
707  
708 *timeout = -1;
709  
710 if (channel->debug)
711 g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel);
712  
713 switch (channel->type)
714 {
715 case G_IO_WIN32_WINDOWS_MESSAGES:
716 if (channel->debug)
717 g_print (" MSG");
718 break;
719  
720 case G_IO_WIN32_CONSOLE:
721 if (channel->debug)
722 g_print (" CON");
723 break;
724  
725 case G_IO_WIN32_FILE_DESC:
726 if (channel->debug)
727 g_print (" FD thread=%#x buffer_condition:{%s}"
728 "\n watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}",
729 channel->thread_id, condition_to_string (buffer_condition),
730 condition_to_string (watch->pollfd.events),
731 condition_to_string (watch->pollfd.revents),
732 condition_to_string (channel->revents));
733  
734 EnterCriticalSection (&channel->mutex);
735 if (channel->running)
736 {
737 if (channel->direction == 0 && channel->wrp == channel->rdp)
738 {
739 if (channel->debug)
740 g_print ("\n setting revents=0");
741 channel->revents = 0;
742 }
743 }
744 else
745 {
746 if (channel->direction == 1
747 && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
748 {
749 if (channel->debug)
750 g_print ("\n setting revents=0");
751 channel->revents = 0;
752 }
753 }
754 LeaveCriticalSection (&channel->mutex);
755 break;
756  
757 case G_IO_WIN32_SOCKET:
758 if (channel->debug)
759 g_print (" SOCK");
760 event_mask = 0;
761 if (watch->condition & G_IO_IN)
762 event_mask |= (FD_READ | FD_ACCEPT);
763 if (watch->condition & G_IO_OUT)
764 event_mask |= (FD_WRITE | FD_CONNECT);
765 event_mask |= FD_CLOSE;
766  
767 if (channel->event_mask != event_mask)
768 {
769 if (channel->debug)
770 g_print ("\n WSAEventSelect(%d,%p,{%s})",
771 channel->fd, (HANDLE) watch->pollfd.fd,
772 event_mask_to_string (event_mask));
773 if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd,
774 event_mask) == SOCKET_ERROR)
775 if (channel->debug)
776 {
777 gchar *emsg = g_win32_error_message (WSAGetLastError ());
778  
779 g_print (" failed: %s", emsg);
780 g_free (emsg);
781 }
782 channel->event_mask = event_mask;
783  
784 if (channel->debug)
785 g_print ("\n setting last_events=0");
786 channel->last_events = 0;
787  
788 if ((event_mask & FD_WRITE) &&
789 channel->ever_writable &&
790 !channel->write_would_have_blocked)
791 {
792 if (channel->debug)
793 g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
794 WSASetEvent ((WSAEVENT) watch->pollfd.fd);
795 }
796 }
797 break;
798  
799 default:
800 g_assert_not_reached ();
801 abort ();
802 }
803 if (channel->debug)
804 g_print ("\n");
805  
806 return ((watch->condition & buffer_condition) == watch->condition);
807 }
808  
809 static gboolean
810 g_io_win32_check (GSource *source)
811 {
812 MSG msg;
813 GIOWin32Watch *watch = (GIOWin32Watch *)source;
814 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
815 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
816 WSANETWORKEVENTS events;
817  
818 if (channel->debug)
819 g_print ("g_io_win32_check: source=%p channel=%p", source, channel);
820  
821 switch (channel->type)
822 {
823 case G_IO_WIN32_WINDOWS_MESSAGES:
824 if (channel->debug)
825 g_print (" MSG\n");
826 return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
827  
828 case G_IO_WIN32_FILE_DESC:
829 if (channel->debug)
830 g_print (" FD thread=%#x buffer_condition=%s\n"
831 " watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
832 channel->thread_id, condition_to_string (buffer_condition),
833 condition_to_string (watch->pollfd.events),
834 condition_to_string (watch->pollfd.revents),
835 condition_to_string (channel->revents));
836  
837 watch->pollfd.revents = (watch->pollfd.events & channel->revents);
838  
839 return ((watch->pollfd.revents | buffer_condition) & watch->condition);
840  
841 case G_IO_WIN32_CONSOLE:
842 if (channel->debug)
843 g_print (" CON\n");
844 if (watch->channel->is_writeable)
845 return TRUE;
846 else if (watch->channel->is_readable)
847 {
848 INPUT_RECORD buffer;
849 DWORD n;
850 if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) &&
851 n == 1)
852 {
853 /* _kbhit() does quite complex processing to find out
854 * whether at least one of the key events pending corresponds
855 * to a "real" character that can be read.
856 */
857 if (_kbhit ())
858 return TRUE;
859  
860 /* Discard all other kinds of events */
861 ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n);
862 }
863 }
864 return FALSE;
865  
866 case G_IO_WIN32_SOCKET:
867 if (channel->debug)
868 g_print (" SOCK");
869 if (channel->last_events & FD_WRITE)
870 {
871 if (channel->debug)
872 g_print (" sock=%d event=%p last_events has FD_WRITE",
873 channel->fd, (HANDLE) watch->pollfd.fd);
874 }
875 else
876 {
877 WSAEnumNetworkEvents (channel->fd, 0, &events);
878  
879 if (channel->debug)
880 g_print ("\n revents={%s} condition={%s}"
881 "\n WSAEnumNetworkEvents(%d,0) sets events={%s}",
882 condition_to_string (watch->pollfd.revents),
883 condition_to_string (watch->condition),
884 channel->fd,
885 event_mask_to_string (events.lNetworkEvents));
886  
887 if (watch->pollfd.revents != 0 &&
888 events.lNetworkEvents == 0 &&
889 !(channel->event_mask & FD_WRITE))
890 {
891 channel->event_mask = 0;
892 if (channel->debug)
893 g_print ("\n WSAEventSelect(%d,%p,{})",
894 channel->fd, (HANDLE) watch->pollfd.fd);
895 WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0);
896 if (channel->debug)
897 g_print (" ResetEvent(%p)",
898 (HANDLE) watch->pollfd.fd);
899 ResetEvent ((HANDLE) watch->pollfd.fd);
900 }
901 else if (events.lNetworkEvents & FD_WRITE)
902 channel->ever_writable = TRUE;
903 channel->last_events = events.lNetworkEvents;
904 }
905  
906 watch->pollfd.revents = 0;
907 if (channel->last_events & (FD_READ | FD_ACCEPT))
908 watch->pollfd.revents |= G_IO_IN;
909  
910 if (channel->last_events & FD_WRITE)
911 watch->pollfd.revents |= G_IO_OUT;
912 else
913 {
914 /* We have called WSAEnumNetworkEvents() above but it didn't
915 * set FD_WRITE.
916 */
917 if (events.lNetworkEvents & FD_CONNECT)
918 {
919 if (events.iErrorCode[FD_CONNECT_BIT] == 0)
920 watch->pollfd.revents |= G_IO_OUT;
921 else
922 watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR);
923 }
924 if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
925 watch->pollfd.revents |= G_IO_HUP;
926 }
927  
928 /* Regardless of WSAEnumNetworkEvents() result, if watching for
929 * writability, and if we have ever got a FD_WRITE event, and
930 * unless last write would have blocked, set G_IO_OUT. But never
931 * set both G_IO_OUT and G_IO_HUP.
932 */
933 if (!(watch->pollfd.revents & G_IO_HUP) &&
934 channel->ever_writable &&
935 !channel->write_would_have_blocked &&
936 (channel->event_mask & FD_WRITE))
937 watch->pollfd.revents |= G_IO_OUT;
938  
939 if (channel->debug)
940 g_print ("\n revents={%s} retval={%s}\n",
941 condition_to_string (watch->pollfd.revents),
942 condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
943  
944 return ((watch->pollfd.revents | buffer_condition) & watch->condition);
945  
946 default:
947 g_assert_not_reached ();
948 abort ();
949 }
950 }
951  
952 static gboolean
953 g_io_win32_dispatch (GSource *source,
954 GSourceFunc callback,
955 gpointer user_data)
956 {
957 GIOFunc func = (GIOFunc)callback;
958 GIOWin32Watch *watch = (GIOWin32Watch *)source;
959 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
960 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
961  
962 if (!func)
963 {
964 g_warning ("IO Watch dispatched without callback\n"
965 "You must call g_source_connect().");
966 return FALSE;
967 }
968  
969 if (channel->debug)
970 g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
971 condition_to_string (watch->pollfd.revents),
972 condition_to_string (watch->condition),
973 condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
974  
975 return (*func) (watch->channel,
976 (watch->pollfd.revents | buffer_condition) & watch->condition,
977 user_data);
978 }
979  
980 static void
981 g_io_win32_finalize (GSource *source)
982 {
983 GIOWin32Watch *watch = (GIOWin32Watch *)source;
984 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
985  
986 if (channel->debug)
987 g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel);
988  
989 switch (channel->type)
990 {
991 case G_IO_WIN32_WINDOWS_MESSAGES:
992 if (channel->debug)
993 g_print (" MSG");
994 break;
995  
996 case G_IO_WIN32_CONSOLE:
997 if (channel->debug)
998 g_print (" CON");
999 break;
1000  
1001 case G_IO_WIN32_FILE_DESC:
1002 if (channel->debug)
1003 g_print (" FD thread=%#x", channel->thread_id);
1004 break;
1005  
1006 case G_IO_WIN32_SOCKET:
1007 if (channel->debug)
1008 g_print (" SOCK sock=%d", channel->fd);
1009 break;
1010  
1011 default:
1012 g_assert_not_reached ();
1013 abort ();
1014 }
1015 if (channel->debug)
1016 g_print ("\n");
1017 g_io_channel_unref (watch->channel);
1018 }
1019  
1020 GSourceFuncs g_io_watch_funcs = {
1021 g_io_win32_prepare,
1022 g_io_win32_check,
1023 g_io_win32_dispatch,
1024 g_io_win32_finalize
1025 };
1026  
1027 static GIOStatus
1028 g_io_win32_msg_read (GIOChannel *channel,
1029 gchar *buf,
1030 gsize count,
1031 gsize *bytes_read,
1032 GError **err)
1033 {
1034 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1035 MSG msg; /* In case of alignment problems */
1036  
1037 *bytes_read = 0;
1038  
1039 if (count < sizeof (MSG))
1040 {
1041 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1042 "Incorrect message size"); /* Informative enough error message? */
1043 return G_IO_STATUS_ERROR;
1044 }
1045  
1046 if (win32_channel->debug)
1047 g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n",
1048 channel, win32_channel->hwnd);
1049 if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
1050 return G_IO_STATUS_AGAIN;
1051  
1052 memmove (buf, &msg, sizeof (MSG));
1053 *bytes_read = sizeof (MSG);
1054  
1055 return G_IO_STATUS_NORMAL;
1056 }
1057  
1058 static GIOStatus
1059 g_io_win32_msg_write (GIOChannel *channel,
1060 const gchar *buf,
1061 gsize count,
1062 gsize *bytes_written,
1063 GError **err)
1064 {
1065 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1066 MSG msg;
1067  
1068 *bytes_written = 0;
1069  
1070 if (count != sizeof (MSG))
1071 {
1072 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1073 "Incorrect message size"); /* Informative enough error message? */
1074 return G_IO_STATUS_ERROR;
1075 }
1076  
1077 /* In case of alignment problems */
1078 memmove (&msg, buf, sizeof (MSG));
1079 if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
1080 {
1081 gchar *emsg = g_win32_error_message (GetLastError ());
1082  
1083 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg);
1084 g_free (emsg);
1085  
1086 return G_IO_STATUS_ERROR;
1087 }
1088  
1089 *bytes_written = sizeof (MSG);
1090  
1091 return G_IO_STATUS_NORMAL;
1092 }
1093  
1094 static GIOStatus
1095 g_io_win32_msg_close (GIOChannel *channel,
1096 GError **err)
1097 {
1098 /* Nothing to be done. Or should we set hwnd to some invalid value? */
1099  
1100 return G_IO_STATUS_NORMAL;
1101 }
1102  
1103 static void
1104 g_io_win32_free (GIOChannel *channel)
1105 {
1106 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1107  
1108 if (win32_channel->debug)
1109 g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd);
1110  
1111 DeleteCriticalSection (&win32_channel->mutex);
1112  
1113 if (win32_channel->data_avail_event)
1114 if (!CloseHandle (win32_channel->data_avail_event))
1115 if (win32_channel->debug)
1116 {
1117 gchar *emsg = g_win32_error_message (GetLastError ());
1118  
1119 g_print (" CloseHandle(%p) failed: %s\n",
1120 win32_channel->data_avail_event, emsg);
1121 g_free (emsg);
1122 }
1123  
1124 g_free (win32_channel->buffer);
1125  
1126 if (win32_channel->space_avail_event)
1127 if (!CloseHandle (win32_channel->space_avail_event))
1128 if (win32_channel->debug)
1129 {
1130 gchar *emsg = g_win32_error_message (GetLastError ());
1131  
1132 g_print (" CloseHandle(%p) failed: %s\n",
1133 win32_channel->space_avail_event, emsg);
1134 g_free (emsg);
1135 }
1136  
1137 if (win32_channel->type == G_IO_WIN32_SOCKET &&
1138 win32_channel->fd != -1)
1139 if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR)
1140 if (win32_channel->debug)
1141 {
1142 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1143  
1144 g_print (" WSAEventSelect(%d,NULL,{}) failed: %s\n",
1145 win32_channel->fd, emsg);
1146 g_free (emsg);
1147 }
1148  
1149 if (win32_channel->event)
1150 if (!WSACloseEvent (win32_channel->event))
1151 if (win32_channel->debug)
1152 {
1153 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1154  
1155 g_print (" WSACloseEvent(%p) failed: %s\n",
1156 win32_channel->event, emsg);
1157 g_free (emsg);
1158 }
1159  
1160 g_free (win32_channel);
1161 }
1162  
1163 static GSource *
1164 g_io_win32_msg_create_watch (GIOChannel *channel,
1165 GIOCondition condition)
1166 {
1167 GIOWin32Watch *watch;
1168 GSource *source;
1169  
1170 source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1171 g_source_set_name (source, "GIOChannel (Win32)");
1172 watch = (GIOWin32Watch *)source;
1173  
1174 watch->channel = channel;
1175 g_io_channel_ref (channel);
1176  
1177 watch->condition = condition;
1178  
1179 watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE;
1180 watch->pollfd.events = condition;
1181  
1182 g_source_add_poll (source, &watch->pollfd);
1183  
1184 return source;
1185 }
1186  
1187 static GIOStatus
1188 g_io_win32_fd_and_console_read (GIOChannel *channel,
1189 gchar *buf,
1190 gsize count,
1191 gsize *bytes_read,
1192 GError **err)
1193 {
1194 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1195 gint result;
1196  
1197 if (win32_channel->debug)
1198 g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
1199 win32_channel->fd, count);
1200  
1201 if (win32_channel->thread_id)
1202 {
1203 return buffer_read (win32_channel, buf, count, bytes_read, err);
1204 }
1205  
1206 result = read (win32_channel->fd, buf, count);
1207  
1208 if (win32_channel->debug)
1209 g_print ("g_io_win32_fd_read: read() => %d\n", result);
1210  
1211 if (result < 0)
1212 {
1213 *bytes_read = 0;
1214  
1215 switch (errno)
1216 {
1217 #ifdef EAGAIN
1218 case EAGAIN:
1219 return G_IO_STATUS_AGAIN;
1220 #endif
1221 default:
1222 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1223 g_io_channel_error_from_errno (errno),
1224 g_strerror (errno));
1225 return G_IO_STATUS_ERROR;
1226 }
1227 }
1228  
1229 *bytes_read = result;
1230  
1231 return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
1232 }
1233  
1234 static GIOStatus
1235 g_io_win32_fd_and_console_write (GIOChannel *channel,
1236 const gchar *buf,
1237 gsize count,
1238 gsize *bytes_written,
1239 GError **err)
1240 {
1241 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1242 gint result;
1243  
1244 if (win32_channel->thread_id)
1245 {
1246 return buffer_write (win32_channel, buf, count, bytes_written, err);
1247 }
1248  
1249 result = write (win32_channel->fd, buf, count);
1250 if (win32_channel->debug)
1251 g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
1252 win32_channel->fd, count, result);
1253  
1254 if (result < 0)
1255 {
1256 *bytes_written = 0;
1257  
1258 switch (errno)
1259 {
1260 #ifdef EAGAIN
1261 case EAGAIN:
1262 return G_IO_STATUS_AGAIN;
1263 #endif
1264 default:
1265 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1266 g_io_channel_error_from_errno (errno),
1267 g_strerror (errno));
1268 return G_IO_STATUS_ERROR;
1269 }
1270 }
1271  
1272 *bytes_written = result;
1273  
1274 return G_IO_STATUS_NORMAL;
1275 }
1276  
1277 static GIOStatus
1278 g_io_win32_fd_seek (GIOChannel *channel,
1279 gint64 offset,
1280 GSeekType type,
1281 GError **err)
1282 {
1283 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1284 int whence;
1285 off_t tmp_offset;
1286 off_t result;
1287  
1288 switch (type)
1289 {
1290 case G_SEEK_SET:
1291 whence = SEEK_SET;
1292 break;
1293 case G_SEEK_CUR:
1294 whence = SEEK_CUR;
1295 break;
1296 case G_SEEK_END:
1297 whence = SEEK_END;
1298 break;
1299 default:
1300 whence = -1; /* Keep the compiler quiet */
1301 g_assert_not_reached ();
1302 abort ();
1303 }
1304  
1305 tmp_offset = offset;
1306 if (tmp_offset != offset)
1307 {
1308 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1309 g_io_channel_error_from_errno (EINVAL),
1310 g_strerror (EINVAL));
1311 return G_IO_STATUS_ERROR;
1312 }
1313  
1314 result = lseek (win32_channel->fd, tmp_offset, whence);
1315  
1316 if (result < 0)
1317 {
1318 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1319 g_io_channel_error_from_errno (errno),
1320 g_strerror (errno));
1321 return G_IO_STATUS_ERROR;
1322 }
1323  
1324 return G_IO_STATUS_NORMAL;
1325 }
1326  
1327 static GIOStatus
1328 g_io_win32_fd_close (GIOChannel *channel,
1329 GError **err)
1330 {
1331 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1332  
1333 if (win32_channel->debug)
1334 g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
1335 win32_channel->thread_id,
1336 win32_channel->fd);
1337 EnterCriticalSection (&win32_channel->mutex);
1338 if (win32_channel->running)
1339 {
1340 if (win32_channel->debug)
1341 g_print ("thread %#x: running, marking fd %d for later close\n",
1342 win32_channel->thread_id, win32_channel->fd);
1343 win32_channel->running = FALSE;
1344 win32_channel->needs_close = TRUE;
1345 if (win32_channel->direction == 0)
1346 SetEvent (win32_channel->data_avail_event);
1347 else
1348 SetEvent (win32_channel->space_avail_event);
1349 }
1350 else
1351 {
1352 if (win32_channel->debug)
1353 g_print ("closing fd %d\n", win32_channel->fd);
1354 close (win32_channel->fd);
1355 if (win32_channel->debug)
1356 g_print ("closed fd %d, setting to -1\n",
1357 win32_channel->fd);
1358 win32_channel->fd = -1;
1359 }
1360 LeaveCriticalSection (&win32_channel->mutex);
1361  
1362 /* FIXME error detection? */
1363  
1364 return G_IO_STATUS_NORMAL;
1365 }
1366  
1367 static GSource *
1368 g_io_win32_fd_create_watch (GIOChannel *channel,
1369 GIOCondition condition)
1370 {
1371 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1372 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1373 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1374  
1375 watch->channel = channel;
1376 g_io_channel_ref (channel);
1377  
1378 watch->condition = condition;
1379  
1380 if (win32_channel->data_avail_event == NULL)
1381 create_events (win32_channel);
1382  
1383 watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
1384 watch->pollfd.events = condition;
1385  
1386 if (win32_channel->debug)
1387 g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
1388 channel, win32_channel->fd,
1389 condition_to_string (condition), (HANDLE) watch->pollfd.fd);
1390  
1391 EnterCriticalSection (&win32_channel->mutex);
1392 if (win32_channel->thread_id == 0)
1393 {
1394 if (condition & G_IO_IN)
1395 create_thread (win32_channel, condition, read_thread);
1396 else if (condition & G_IO_OUT)
1397 create_thread (win32_channel, condition, write_thread);
1398 }
1399  
1400 g_source_add_poll (source, &watch->pollfd);
1401 LeaveCriticalSection (&win32_channel->mutex);
1402  
1403 return source;
1404 }
1405  
1406 static GIOStatus
1407 g_io_win32_console_close (GIOChannel *channel,
1408 GError **err)
1409 {
1410 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1411  
1412 if (close (win32_channel->fd) < 0)
1413 {
1414 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1415 g_io_channel_error_from_errno (errno),
1416 g_strerror (errno));
1417 return G_IO_STATUS_ERROR;
1418 }
1419  
1420 return G_IO_STATUS_NORMAL;
1421 }
1422  
1423 static GSource *
1424 g_io_win32_console_create_watch (GIOChannel *channel,
1425 GIOCondition condition)
1426 {
1427 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1428 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1429 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1430  
1431 watch->channel = channel;
1432 g_io_channel_ref (channel);
1433  
1434 watch->condition = condition;
1435  
1436 watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
1437 watch->pollfd.events = condition;
1438  
1439 g_source_add_poll (source, &watch->pollfd);
1440  
1441 return source;
1442 }
1443  
1444 static GIOStatus
1445 g_io_win32_sock_read (GIOChannel *channel,
1446 gchar *buf,
1447 gsize count,
1448 gsize *bytes_read,
1449 GError **err)
1450 {
1451 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1452 gint result;
1453 GIOChannelError error;
1454 int winsock_error;
1455  
1456 if (win32_channel->debug)
1457 g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1458 channel, win32_channel->fd, count);
1459  
1460 result = recv (win32_channel->fd, buf, count, 0);
1461 if (result == SOCKET_ERROR)
1462 winsock_error = WSAGetLastError ();
1463  
1464 if (win32_channel->debug)
1465 g_print (" recv=%d", result);
1466  
1467 if (result == SOCKET_ERROR)
1468 {
1469 gchar *emsg = g_win32_error_message (winsock_error);
1470  
1471 if (win32_channel->debug)
1472 g_print (" %s\n", emsg);
1473  
1474 *bytes_read = 0;
1475  
1476 switch (winsock_error)
1477 {
1478 case WSAEINVAL:
1479 error = G_IO_CHANNEL_ERROR_INVAL;
1480 break;
1481 case WSAEWOULDBLOCK:
1482 g_free (emsg);
1483 return G_IO_STATUS_AGAIN;
1484 default:
1485 error = G_IO_CHANNEL_ERROR_FAILED;
1486 break;
1487 }
1488 g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1489 g_free (emsg);
1490  
1491 return G_IO_STATUS_ERROR;
1492 }
1493 else
1494 {
1495 if (win32_channel->debug)
1496 g_print ("\n");
1497 *bytes_read = result;
1498 if (result == 0)
1499 return G_IO_STATUS_EOF;
1500 else
1501 return G_IO_STATUS_NORMAL;
1502 }
1503 }
1504  
1505 static GIOStatus
1506 g_io_win32_sock_write (GIOChannel *channel,
1507 const gchar *buf,
1508 gsize count,
1509 gsize *bytes_written,
1510 GError **err)
1511 {
1512 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1513 gint result;
1514 GIOChannelError error;
1515 int winsock_error;
1516  
1517 if (win32_channel->debug)
1518 g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1519 channel, win32_channel->fd, count);
1520  
1521 result = send (win32_channel->fd, buf, count, 0);
1522 if (result == SOCKET_ERROR)
1523 winsock_error = WSAGetLastError ();
1524  
1525 if (win32_channel->debug)
1526 g_print (" send=%d", result);
1527  
1528 if (result == SOCKET_ERROR)
1529 {
1530 gchar *emsg = g_win32_error_message (winsock_error);
1531  
1532 if (win32_channel->debug)
1533 g_print (" %s\n", emsg);
1534  
1535 *bytes_written = 0;
1536  
1537 switch (winsock_error)
1538 {
1539 case WSAEINVAL:
1540 error = G_IO_CHANNEL_ERROR_INVAL;
1541 break;
1542 case WSAEWOULDBLOCK:
1543 win32_channel->write_would_have_blocked = TRUE;
1544 win32_channel->last_events = 0;
1545 g_free (emsg);
1546 return G_IO_STATUS_AGAIN;
1547 default:
1548 error = G_IO_CHANNEL_ERROR_FAILED;
1549 break;
1550 }
1551 g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1552 g_free (emsg);
1553  
1554 return G_IO_STATUS_ERROR;
1555 }
1556 else
1557 {
1558 if (win32_channel->debug)
1559 g_print ("\n");
1560 *bytes_written = result;
1561 win32_channel->write_would_have_blocked = FALSE;
1562  
1563 return G_IO_STATUS_NORMAL;
1564 }
1565 }
1566  
1567 static GIOStatus
1568 g_io_win32_sock_close (GIOChannel *channel,
1569 GError **err)
1570 {
1571 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1572  
1573 if (win32_channel->fd != -1)
1574 {
1575 if (win32_channel->debug)
1576 g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
1577 channel, win32_channel->fd);
1578  
1579 closesocket (win32_channel->fd);
1580 win32_channel->fd = -1;
1581 }
1582  
1583 /* FIXME error detection? */
1584  
1585 return G_IO_STATUS_NORMAL;
1586 }
1587  
1588 static GSource *
1589 g_io_win32_sock_create_watch (GIOChannel *channel,
1590 GIOCondition condition)
1591 {
1592 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1593 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1594 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1595  
1596 watch->channel = channel;
1597 g_io_channel_ref (channel);
1598  
1599 watch->condition = condition;
1600  
1601 if (win32_channel->event == 0)
1602 win32_channel->event = WSACreateEvent ();
1603  
1604 watch->pollfd.fd = (gintptr) win32_channel->event;
1605 watch->pollfd.events = condition;
1606  
1607 if (win32_channel->debug)
1608 g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
1609 channel, win32_channel->fd, (HANDLE) watch->pollfd.fd,
1610 condition_to_string (watch->condition));
1611  
1612 g_source_add_poll (source, &watch->pollfd);
1613  
1614 return source;
1615 }
1616  
1617 GIOChannel *
1618 g_io_channel_new_file (const gchar *filename,
1619 const gchar *mode,
1620 GError **error)
1621 {
1622 int fid, flags, pmode;
1623 GIOChannel *channel;
1624  
1625 enum { /* Cheesy hack */
1626 MODE_R = 1 << 0,
1627 MODE_W = 1 << 1,
1628 MODE_A = 1 << 2,
1629 MODE_PLUS = 1 << 3,
1630 };
1631 int mode_num;
1632  
1633 g_return_val_if_fail (filename != NULL, NULL);
1634 g_return_val_if_fail (mode != NULL, NULL);
1635 g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
1636  
1637 switch (mode[0])
1638 {
1639 case 'r':
1640 mode_num = MODE_R;
1641 break;
1642 case 'w':
1643 mode_num = MODE_W;
1644 break;
1645 case 'a':
1646 mode_num = MODE_A;
1647 break;
1648 default:
1649 g_warning ("Invalid GIOFileMode %s.", mode);
1650 return NULL;
1651 }
1652  
1653 switch (mode[1])
1654 {
1655 case '\0':
1656 break;
1657 case '+':
1658 if (mode[2] == '\0')
1659 {
1660 mode_num |= MODE_PLUS;
1661 break;
1662 }
1663 /* Fall through */
1664 default:
1665 g_warning ("Invalid GIOFileMode %s.", mode);
1666 return NULL;
1667 }
1668  
1669 switch (mode_num)
1670 {
1671 case MODE_R:
1672 flags = O_RDONLY;
1673 pmode = _S_IREAD;
1674 break;
1675 case MODE_W:
1676 flags = O_WRONLY | O_TRUNC | O_CREAT;
1677 pmode = _S_IWRITE;
1678 break;
1679 case MODE_A:
1680 flags = O_WRONLY | O_APPEND | O_CREAT;
1681 pmode = _S_IWRITE;
1682 break;
1683 case MODE_R | MODE_PLUS:
1684 flags = O_RDWR;
1685 pmode = _S_IREAD | _S_IWRITE;
1686 break;
1687 case MODE_W | MODE_PLUS:
1688 flags = O_RDWR | O_TRUNC | O_CREAT;
1689 pmode = _S_IREAD | _S_IWRITE;
1690 break;
1691 case MODE_A | MODE_PLUS:
1692 flags = O_RDWR | O_APPEND | O_CREAT;
1693 pmode = _S_IREAD | _S_IWRITE;
1694 break;
1695 default:
1696 g_assert_not_reached ();
1697 abort ();
1698 }
1699  
1700 /* always open 'untranslated' */
1701 fid = g_open (filename, flags | _O_BINARY, pmode);
1702  
1703 if (g_io_win32_get_debug_flag ())
1704 {
1705 g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename);
1706 g_win32_print_access_mode (flags|_O_BINARY);
1707 g_print (",%#o)=%d\n", pmode, fid);
1708 }
1709  
1710 if (fid < 0)
1711 {
1712 g_set_error_literal (error, G_FILE_ERROR,
1713 g_file_error_from_errno (errno),
1714 g_strerror (errno));
1715 return (GIOChannel *)NULL;
1716 }
1717  
1718 channel = g_io_channel_win32_new_fd (fid);
1719  
1720 /* XXX: move this to g_io_channel_win32_new_fd () */
1721 channel->close_on_unref = TRUE;
1722 channel->is_seekable = TRUE;
1723  
1724 /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
1725 * correspond to actual readability/writeability. Set to FALSE those
1726 * that mode doesn't allow
1727 */
1728 switch (mode_num)
1729 {
1730 case MODE_R:
1731 channel->is_writeable = FALSE;
1732 break;
1733 case MODE_W:
1734 case MODE_A:
1735 channel->is_readable = FALSE;
1736 break;
1737 case MODE_R | MODE_PLUS:
1738 case MODE_W | MODE_PLUS:
1739 case MODE_A | MODE_PLUS:
1740 break;
1741 default:
1742 g_assert_not_reached ();
1743 abort ();
1744 }
1745  
1746 return channel;
1747 }
1748  
1749 #if !defined (_WIN64)
1750  
1751 #undef g_io_channel_new_file
1752  
1753 /* Binary compatibility version. Not for newly compiled code. */
1754  
1755 GIOChannel *
1756 g_io_channel_new_file (const gchar *filename,
1757 const gchar *mode,
1758 GError **error)
1759 {
1760 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
1761 GIOChannel *retval;
1762  
1763 if (utf8_filename == NULL)
1764 return NULL;
1765  
1766 retval = g_io_channel_new_file_utf8 (utf8_filename, mode, error);
1767  
1768 g_free (utf8_filename);
1769  
1770 return retval;
1771 }
1772  
1773 #endif
1774  
1775 static GIOStatus
1776 g_io_win32_unimpl_set_flags (GIOChannel *channel,
1777 GIOFlags flags,
1778 GError **err)
1779 {
1780 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1781  
1782 if (win32_channel->debug)
1783 {
1784 g_print ("g_io_win32_unimpl_set_flags: ");
1785 g_win32_print_gioflags (flags);
1786 g_print ("\n");
1787 }
1788  
1789 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1790 G_IO_CHANNEL_ERROR_FAILED,
1791 "Not implemented on Win32");
1792  
1793 return G_IO_STATUS_ERROR;
1794 }
1795  
1796 static GIOFlags
1797 g_io_win32_fd_get_flags_internal (GIOChannel *channel,
1798 struct _stati64 *st)
1799 {
1800 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1801 gchar c;
1802 DWORD count;
1803  
1804 if (st->st_mode & _S_IFIFO)
1805 {
1806 channel->is_readable =
1807 (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) != 0) || GetLastError () == ERROR_BROKEN_PIPE;
1808 channel->is_writeable =
1809 (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1810 channel->is_seekable = FALSE;
1811 }
1812 else
1813 {
1814 channel->is_readable =
1815 (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1816 channel->is_writeable =
1817 (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1818 channel->is_seekable = TRUE;
1819 }
1820  
1821 /* XXX: G_IO_FLAG_APPEND */
1822 /* XXX: G_IO_FLAG_NONBLOCK */
1823  
1824 return 0;
1825 }
1826  
1827 static GIOFlags
1828 g_io_win32_fd_get_flags (GIOChannel *channel)
1829 {
1830 struct _stati64 st;
1831 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1832  
1833 g_return_val_if_fail (win32_channel != NULL, 0);
1834 g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0);
1835  
1836 if (0 == _fstati64 (win32_channel->fd, &st))
1837 return g_io_win32_fd_get_flags_internal (channel, &st);
1838 else
1839 return 0;
1840 }
1841  
1842 static GIOFlags
1843 g_io_win32_console_get_flags_internal (GIOChannel *channel)
1844 {
1845 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1846 HANDLE handle = (HANDLE) _get_osfhandle (win32_channel->fd);
1847 gchar c;
1848 DWORD count;
1849 INPUT_RECORD record;
1850  
1851 channel->is_readable = PeekConsoleInput (handle, &record, 1, &count);
1852 channel->is_writeable = WriteFile (handle, &c, 0, &count, NULL);
1853 channel->is_seekable = FALSE;
1854  
1855 return 0;
1856 }
1857  
1858 static GIOFlags
1859 g_io_win32_console_get_flags (GIOChannel *channel)
1860 {
1861 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1862  
1863 g_return_val_if_fail (win32_channel != NULL, 0);
1864 g_return_val_if_fail (win32_channel->type == G_IO_WIN32_CONSOLE, 0);
1865  
1866 return g_io_win32_console_get_flags_internal (channel);
1867 }
1868  
1869 static GIOFlags
1870 g_io_win32_msg_get_flags (GIOChannel *channel)
1871 {
1872 return 0;
1873 }
1874  
1875 static GIOStatus
1876 g_io_win32_sock_set_flags (GIOChannel *channel,
1877 GIOFlags flags,
1878 GError **err)
1879 {
1880 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1881 u_long arg;
1882  
1883 if (win32_channel->debug)
1884 {
1885 g_print ("g_io_win32_sock_set_flags: ");
1886 g_win32_print_gioflags (flags);
1887 g_print ("\n");
1888 }
1889  
1890 if (flags & G_IO_FLAG_NONBLOCK)
1891 {
1892 arg = 1;
1893 if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
1894 {
1895 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1896  
1897 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1898 G_IO_CHANNEL_ERROR_FAILED,
1899 emsg);
1900 g_free (emsg);
1901  
1902 return G_IO_STATUS_ERROR;
1903 }
1904 }
1905 else
1906 {
1907 arg = 0;
1908 if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
1909 {
1910 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1911  
1912 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1913 G_IO_CHANNEL_ERROR_FAILED,
1914 emsg);
1915 g_free (emsg);
1916  
1917 return G_IO_STATUS_ERROR;
1918 }
1919 }
1920  
1921 return G_IO_STATUS_NORMAL;
1922 }
1923  
1924 static GIOFlags
1925 g_io_win32_sock_get_flags (GIOChannel *channel)
1926 {
1927 /* Could we do something here? */
1928 return 0;
1929 }
1930  
1931 static GIOFuncs win32_channel_msg_funcs = {
1932 g_io_win32_msg_read,
1933 g_io_win32_msg_write,
1934 NULL,
1935 g_io_win32_msg_close,
1936 g_io_win32_msg_create_watch,
1937 g_io_win32_free,
1938 g_io_win32_unimpl_set_flags,
1939 g_io_win32_msg_get_flags,
1940 };
1941  
1942 static GIOFuncs win32_channel_fd_funcs = {
1943 g_io_win32_fd_and_console_read,
1944 g_io_win32_fd_and_console_write,
1945 g_io_win32_fd_seek,
1946 g_io_win32_fd_close,
1947 g_io_win32_fd_create_watch,
1948 g_io_win32_free,
1949 g_io_win32_unimpl_set_flags,
1950 g_io_win32_fd_get_flags,
1951 };
1952  
1953 static GIOFuncs win32_channel_console_funcs = {
1954 g_io_win32_fd_and_console_read,
1955 g_io_win32_fd_and_console_write,
1956 NULL,
1957 g_io_win32_console_close,
1958 g_io_win32_console_create_watch,
1959 g_io_win32_free,
1960 g_io_win32_unimpl_set_flags,
1961 g_io_win32_console_get_flags,
1962 };
1963  
1964 static GIOFuncs win32_channel_sock_funcs = {
1965 g_io_win32_sock_read,
1966 g_io_win32_sock_write,
1967 NULL,
1968 g_io_win32_sock_close,
1969 g_io_win32_sock_create_watch,
1970 g_io_win32_free,
1971 g_io_win32_sock_set_flags,
1972 g_io_win32_sock_get_flags,
1973 };
1974  
1975 /**
1976 * g_io_channel_win32_new_messages:
1977 * @hwnd: a window handle.
1978 *
1979 * Creates a new #GIOChannel given a window handle on Windows.
1980 *
1981 * This function creates a #GIOChannel that can be used to poll for
1982 * Windows messages for the window in question.
1983 *
1984 * Returns: a new #GIOChannel.
1985 **/
1986 GIOChannel *
1987 #if GLIB_SIZEOF_VOID_P == 8
1988 g_io_channel_win32_new_messages (gsize hwnd)
1989 #else
1990 g_io_channel_win32_new_messages (guint hwnd)
1991 #endif
1992 {
1993 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
1994 GIOChannel *channel = (GIOChannel *)win32_channel;
1995  
1996 g_io_channel_init (channel);
1997 g_io_channel_win32_init (win32_channel);
1998 if (win32_channel->debug)
1999 g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n",
2000 channel, (HWND) hwnd);
2001 channel->funcs = &win32_channel_msg_funcs;
2002 win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
2003 win32_channel->hwnd = (HWND) hwnd;
2004  
2005 /* XXX: check this. */
2006 channel->is_readable = IsWindow (win32_channel->hwnd);
2007 channel->is_writeable = IsWindow (win32_channel->hwnd);
2008  
2009 channel->is_seekable = FALSE;
2010  
2011 return channel;
2012 }
2013  
2014 static GIOChannel *
2015 g_io_channel_win32_new_fd_internal (gint fd,
2016 struct _stati64 *st)
2017 {
2018 GIOWin32Channel *win32_channel;
2019 GIOChannel *channel;
2020  
2021 win32_channel = g_new (GIOWin32Channel, 1);
2022 channel = (GIOChannel *)win32_channel;
2023  
2024 g_io_channel_init (channel);
2025 g_io_channel_win32_init (win32_channel);
2026  
2027 win32_channel->fd = fd;
2028  
2029 if (win32_channel->debug)
2030 g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n",
2031 channel, fd);
2032  
2033 if (st->st_mode & _S_IFCHR) /* console */
2034 {
2035 channel->funcs = &win32_channel_console_funcs;
2036 win32_channel->type = G_IO_WIN32_CONSOLE;
2037 g_io_win32_console_get_flags_internal (channel);
2038 }
2039 else
2040 {
2041 channel->funcs = &win32_channel_fd_funcs;
2042 win32_channel->type = G_IO_WIN32_FILE_DESC;
2043 g_io_win32_fd_get_flags_internal (channel, st);
2044 }
2045  
2046 return channel;
2047 }
2048  
2049 /**
2050 * g_io_channel_win32_new_fd:
2051 * @fd: a C library file descriptor.
2052 *
2053 * Creates a new #GIOChannel given a file descriptor on Windows. This
2054 * works for file descriptors from the C runtime.
2055 *
2056 * This function works for file descriptors as returned by the open(),
2057 * creat(), pipe() and fileno() calls in the Microsoft C runtime. In
2058 * order to meaningfully use this function your code should use the
2059 * same C runtime as GLib uses, which is msvcrt.dll. Note that in
2060 * current Microsoft compilers it is near impossible to convince it to
2061 * build code that would use msvcrt.dll. The last Microsoft compiler
2062 * version that supported using msvcrt.dll as the C runtime was version
2063 * 6. The GNU compiler and toolchain for Windows, also known as Mingw,
2064 * fully supports msvcrt.dll.
2065 *
2066 * If you have created a #GIOChannel for a file descriptor and started
2067 * watching (polling) it, you shouldn't call read() on the file
2068 * descriptor. This is because adding polling for a file descriptor is
2069 * implemented in GLib on Windows by starting a thread that sits
2070 * blocked in a read() from the file descriptor most of the time. All
2071 * reads from the file descriptor should be done by this internal GLib
2072 * thread. Your code should call only g_io_channel_read().
2073 *
2074 * This function is available only in GLib on Windows.
2075 *
2076 * Returns: a new #GIOChannel.
2077 **/
2078 GIOChannel *
2079 g_io_channel_win32_new_fd (gint fd)
2080 {
2081 struct _stati64 st;
2082  
2083 if (_fstati64 (fd, &st) == -1)
2084 {
2085 g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd);
2086 return NULL;
2087 }
2088  
2089 return g_io_channel_win32_new_fd_internal (fd, &st);
2090 }
2091  
2092 gint
2093 g_io_channel_win32_get_fd (GIOChannel *channel)
2094 {
2095 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2096  
2097 return win32_channel->fd;
2098 }
2099  
2100 /**
2101 * g_io_channel_win32_new_socket:
2102 * @socket: a Winsock socket
2103 *
2104 * Creates a new #GIOChannel given a socket on Windows.
2105 *
2106 * This function works for sockets created by Winsock. It's available
2107 * only in GLib on Windows.
2108 *
2109 * Polling a #GSource created to watch a channel for a socket puts the
2110 * socket in non-blocking mode. This is a side-effect of the
2111 * implementation and unavoidable.
2112 *
2113 * Returns: a new #GIOChannel
2114 **/
2115 GIOChannel *
2116 g_io_channel_win32_new_socket (int socket)
2117 {
2118 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
2119 GIOChannel *channel = (GIOChannel *)win32_channel;
2120  
2121 g_io_channel_init (channel);
2122 g_io_channel_win32_init (win32_channel);
2123 if (win32_channel->debug)
2124 g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
2125 channel, socket);
2126 channel->funcs = &win32_channel_sock_funcs;
2127 win32_channel->type = G_IO_WIN32_SOCKET;
2128 win32_channel->fd = socket;
2129  
2130 channel->is_readable = TRUE;
2131 channel->is_writeable = TRUE;
2132 channel->is_seekable = FALSE;
2133  
2134 return channel;
2135 }
2136  
2137 GIOChannel *
2138 g_io_channel_unix_new (gint fd)
2139 {
2140 gboolean is_fd, is_socket;
2141 struct _stati64 st;
2142 int optval, optlen;
2143  
2144 is_fd = (_fstati64 (fd, &st) == 0);
2145  
2146 optlen = sizeof (optval);
2147 is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
2148  
2149 if (is_fd && is_socket)
2150 g_warning ("g_io_channel_unix_new: %d is both a file descriptor and a socket. File descriptor interpretation assumed. To avoid ambiguity, call either g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket() instead.", fd);
2151  
2152 if (is_fd)
2153 return g_io_channel_win32_new_fd_internal (fd, &st);
2154  
2155 if (is_socket)
2156 return g_io_channel_win32_new_socket(fd);
2157  
2158 g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd);
2159  
2160 return NULL;
2161 }
2162  
2163 gint
2164 g_io_channel_unix_get_fd (GIOChannel *channel)
2165 {
2166 return g_io_channel_win32_get_fd (channel);
2167 }
2168  
2169 void
2170 g_io_channel_win32_set_debug (GIOChannel *channel,
2171 gboolean flag)
2172 {
2173 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2174  
2175 win32_channel->debug = flag;
2176 }
2177  
2178 gint
2179 g_io_channel_win32_poll (GPollFD *fds,
2180 gint n_fds,
2181 gint timeout)
2182 {
2183 g_return_val_if_fail (n_fds >= 0, 0);
2184  
2185 return g_poll (fds, n_fds, timeout);
2186 }
2187  
2188 void
2189 g_io_channel_win32_make_pollfd (GIOChannel *channel,
2190 GIOCondition condition,
2191 GPollFD *fd)
2192 {
2193 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2194  
2195 switch (win32_channel->type)
2196 {
2197 case G_IO_WIN32_FILE_DESC:
2198 if (win32_channel->data_avail_event == NULL)
2199 create_events (win32_channel);
2200  
2201 fd->fd = (gintptr) win32_channel->data_avail_event;
2202  
2203 if (win32_channel->thread_id == 0)
2204 {
2205 /* Is it meaningful for a file descriptor to be polled for
2206 * both IN and OUT? For what kind of file descriptor would
2207 * that be? Doesn't seem to make sense, in practise the file
2208 * descriptors handled here are always read or write ends of
2209 * pipes surely, and thus unidirectional.
2210 */
2211 if (condition & G_IO_IN)
2212 create_thread (win32_channel, condition, read_thread);
2213 else if (condition & G_IO_OUT)
2214 create_thread (win32_channel, condition, write_thread);
2215 }
2216 break;
2217  
2218 case G_IO_WIN32_CONSOLE:
2219 fd->fd = _get_osfhandle (win32_channel->fd);
2220 break;
2221  
2222 case G_IO_WIN32_SOCKET:
2223 fd->fd = (gintptr) WSACreateEvent ();
2224 break;
2225  
2226 case G_IO_WIN32_WINDOWS_MESSAGES:
2227 fd->fd = G_WIN32_MSG_HANDLE;
2228 break;
2229  
2230 default:
2231 g_assert_not_reached ();
2232 abort ();
2233 }
2234  
2235 fd->events = condition;
2236 }
2237  
2238 #ifndef _WIN64
2239  
2240 /* Binary compatibility */
2241 GIOChannel *
2242 g_io_channel_win32_new_stream_socket (int socket)
2243 {
2244 return g_io_channel_win32_new_socket (socket);
2245 }
2246  
2247 #endif