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