Define fstat() for msvc build
[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 #ifdef _MSC_VER
85 #define fstat(a,b) _fstat(a,b)
86 #endif
87
88 #include "gstdio.h"
89 #include "glibintl.h"
90
91 #include "galias.h"
92
93 typedef struct _GIOWin32Channel GIOWin32Channel;
94 typedef struct _GIOWin32Watch GIOWin32Watch;
95
96 #define BUFFER_SIZE 4096
97
98 typedef enum {
99   G_IO_WIN32_WINDOWS_MESSAGES,  /* Windows messages */
100
101   G_IO_WIN32_FILE_DESC,         /* Unix-like file descriptors from
102                                  * _open() or _pipe(), except for
103                                  * console IO. Separate thread to read
104                                  * or write.
105                                  */
106
107   G_IO_WIN32_CONSOLE,           /* Console IO (usually stdin, stdout, stderr) */
108
109   G_IO_WIN32_SOCKET             /* Sockets. No separate thread. */
110 } GIOWin32ChannelType;
111
112 struct _GIOWin32Channel {
113   GIOChannel channel;
114   gint fd;                      /* Either a Unix-like file handle as provided
115                                  * by the Microsoft C runtime, or a SOCKET
116                                  * as provided by WinSock.
117                                  */
118   GIOWin32ChannelType type;
119   
120   gboolean debug;
121
122   /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */
123   HWND hwnd;                    /* Handle of window, or NULL */
124   
125   /* Fields used by G_IO_WIN32_FILE_DESC channels. */
126   CRITICAL_SECTION mutex;
127
128   int direction;                /* 0 means we read from it,
129                                  * 1 means we write to it.
130                                  */
131
132   gboolean running;             /* Is reader or writer thread
133                                  * running. FALSE if EOF has been
134                                  * reached by the reader thread.
135                                  */
136
137   gboolean needs_close;         /* If the channel has been closed while
138                                  * the reader thread was still running.
139                                  */
140
141   guint thread_id;              /* If non-NULL the channel has or has
142                                  * had a reader or writer thread.
143                                  */
144   HANDLE data_avail_event;
145
146   gushort revents;
147
148   /* Data is kept in a circular buffer. To be able to distinguish between
149    * empty and full buffers, we cannot fill it completely, but have to
150    * leave a one character gap.
151    *
152    * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
153    *
154    * Empty:    wrp == rdp
155    * Full:     (wrp + 1) % BUFFER_SIZE == rdp
156    * Partial:  otherwise
157    */
158   guchar *buffer;               /* (Circular) buffer */
159   gint wrp, rdp;                /* Buffer indices for writing and reading */
160   HANDLE space_avail_event;
161
162   /* Fields used by G_IO_WIN32_SOCKET channels */
163   int event_mask;
164   int last_events;
165   HANDLE event;
166   gboolean write_would_have_blocked;
167   gboolean ever_writable;
168 };
169
170 struct _GIOWin32Watch {
171   GSource       source;
172   GPollFD       pollfd;
173   GIOChannel   *channel;
174   GIOCondition  condition;
175 };
176
177 static void
178 g_win32_print_access_mode (int flags)
179 {
180   g_print ("%s%s%s%s%s%s%s%s%s%s",
181            ((flags & 0x3) == _O_RDWR ? "O_RDWR" :
182             ((flags & 0x3) == _O_RDONLY ? "O_RDONLY" :
183              ((flags & 0x3) == _O_WRONLY ? "O_WRONLY" : "0"))),
184            (flags & _O_APPEND ? "|O_APPEND" : ""),
185            (flags & _O_RANDOM ? "|O_RANDOM" : ""),
186            (flags & _O_SEQUENTIAL ? "|O_SEQUENTIAL" : ""),
187            (flags & _O_TEMPORARY ? "|O_TEMPORARY" : ""),
188            (flags & _O_CREAT ? "|O_CREAT" : ""),
189            (flags & _O_TRUNC ? "|O_TRUNC" : ""),
190            (flags & _O_EXCL ? "|O_EXCL" : ""),
191            (flags & _O_TEXT ? "|O_TEXT" : ""),
192            (flags & _O_BINARY ? "|O_BINARY" : ""));
193 }
194
195 static void
196 g_win32_print_gioflags (GIOFlags flags)
197 {
198   char *bar = "";
199
200   if (flags & G_IO_FLAG_APPEND)
201     bar = "|", g_print ("APPEND");
202   if (flags & G_IO_FLAG_NONBLOCK)
203     g_print ("%sNONBLOCK", bar), bar = "|";
204   if (flags & G_IO_FLAG_IS_READABLE)
205     g_print ("%sREADABLE", bar), bar = "|";
206   if (flags & G_IO_FLAG_IS_WRITEABLE)
207     g_print ("%sWRITEABLE", bar), bar = "|";
208   if (flags & G_IO_FLAG_IS_SEEKABLE)
209     g_print ("%sSEEKABLE", bar), bar = "|";
210 }
211
212 static const char *
213 event_mask_to_string (int mask)
214 {
215   char buf[100];
216   int checked_bits = 0;
217   char *bufp = buf;
218
219   if (mask == 0)
220     return "";
221
222 #define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
223
224   BIT (READ);
225   BIT (WRITE);
226   BIT (OOB);
227   BIT (ACCEPT);
228   BIT (CONNECT);
229   BIT (CLOSE);
230   BIT (QOS);
231   BIT (GROUP_QOS);
232   BIT (ROUTING_INTERFACE_CHANGE);
233   BIT (ADDRESS_LIST_CHANGE);
234   
235 #undef BIT
236
237   if ((mask & ~checked_bits) != 0)
238           bufp += sprintf (bufp, "|%#x", mask & ~checked_bits);
239   
240   return g_quark_to_string (g_quark_from_string (buf));
241 }
242
243 static const char *
244 condition_to_string (GIOCondition condition)
245 {
246   char buf[100];
247   int checked_bits = 0;
248   char *bufp = buf;
249
250   if (condition == 0)
251     return "";
252
253 #define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
254
255   BIT (IN);
256   BIT (OUT);
257   BIT (PRI);
258   BIT (ERR);
259   BIT (HUP);
260   BIT (NVAL);
261   
262 #undef BIT
263
264   if ((condition & ~checked_bits) != 0)
265           bufp += sprintf (bufp, "|%#x", condition & ~checked_bits);
266   
267   return g_quark_to_string (g_quark_from_string (buf));
268 }
269
270 static gboolean
271 g_io_win32_get_debug_flag (void)
272 {
273   return (getenv ("G_IO_WIN32_DEBUG") != NULL);
274 }
275
276 static void
277 g_io_channel_win32_init (GIOWin32Channel *channel)
278 {
279   channel->debug = g_io_win32_get_debug_flag ();
280
281   InitializeCriticalSection (&channel->mutex);
282   channel->running = FALSE;
283   channel->needs_close = FALSE;
284   channel->thread_id = 0;
285   channel->data_avail_event = NULL;
286   channel->revents = 0;
287   channel->buffer = NULL;
288   channel->space_avail_event = NULL;
289
290   channel->event_mask = 0;
291   channel->last_events = 0;
292   channel->event = NULL;
293   channel->write_would_have_blocked = FALSE;
294   channel->ever_writable = FALSE;
295 }
296
297 static void
298 create_events (GIOWin32Channel *channel)
299 {
300   SECURITY_ATTRIBUTES sec_attrs;
301   
302   sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
303   sec_attrs.lpSecurityDescriptor = NULL;
304   sec_attrs.bInheritHandle = FALSE;
305
306   /* The data available event is manual reset, the space available event
307    * is automatic reset.
308    */
309   if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
310       || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
311     {
312       gchar *emsg = g_win32_error_message (GetLastError ());
313
314       g_error ("Error creating event: %s", emsg);
315       g_free (emsg);
316     }
317 }
318
319 static unsigned __stdcall
320 read_thread (void *parameter)
321 {
322   GIOWin32Channel *channel = parameter;
323   guchar *buffer;
324   gint nbytes;
325
326   g_io_channel_ref ((GIOChannel *)channel);
327
328   if (channel->debug)
329     g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
330              channel->thread_id,
331              channel->fd,
332              channel->data_avail_event,
333              channel->space_avail_event);
334
335   channel->direction = 0;
336   channel->buffer = g_malloc (BUFFER_SIZE);
337   channel->rdp = channel->wrp = 0;
338   channel->running = TRUE;
339
340   SetEvent (channel->space_avail_event);
341   
342   EnterCriticalSection (&channel->mutex);
343   while (channel->running)
344     {
345       if (channel->debug)
346         g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
347                  channel->thread_id, channel->rdp, channel->wrp);
348       if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
349         {
350           /* Buffer is full */
351           if (channel->debug)
352             g_print ("read_thread %#x: resetting space_avail\n",
353                      channel->thread_id);
354           ResetEvent (channel->space_avail_event);
355           if (channel->debug)
356             g_print ("read_thread %#x: waiting for space\n",
357                      channel->thread_id);
358           LeaveCriticalSection (&channel->mutex);
359           WaitForSingleObject (channel->space_avail_event, INFINITE);
360           EnterCriticalSection (&channel->mutex);
361           if (channel->debug)
362             g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
363                      channel->thread_id, channel->rdp, channel->wrp);
364         }
365       
366       buffer = channel->buffer + channel->wrp;
367       
368       /* Always leave at least one byte unused gap to be able to
369        * distinguish between the full and empty condition...
370        */
371       nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
372                     BUFFER_SIZE - channel->wrp);
373
374       if (channel->debug)
375         g_print ("read_thread %#x: calling read() for %d bytes\n",
376                  channel->thread_id, nbytes);
377
378       LeaveCriticalSection (&channel->mutex);
379
380       nbytes = read (channel->fd, buffer, nbytes);
381       
382       EnterCriticalSection (&channel->mutex);
383
384       channel->revents = G_IO_IN;
385       if (nbytes == 0)
386         channel->revents |= G_IO_HUP;
387       else if (nbytes < 0)
388         channel->revents |= G_IO_ERR;
389
390       if (channel->debug)
391         g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
392                  channel->thread_id, nbytes, channel->rdp, channel->wrp);
393
394       if (nbytes <= 0)
395         break;
396
397       channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
398       if (channel->debug)
399         g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
400                  channel->thread_id, channel->rdp, channel->wrp);
401       SetEvent (channel->data_avail_event);
402     }
403   
404   channel->running = FALSE;
405   if (channel->needs_close)
406     {
407       if (channel->debug)
408         g_print ("read_thread %#x: channel fd %d needs closing\n",
409                  channel->thread_id, channel->fd);
410       close (channel->fd);
411       channel->fd = -1;
412     }
413
414   if (channel->debug)
415     g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
416              channel->thread_id, channel->rdp, channel->wrp);
417   SetEvent (channel->data_avail_event);
418   LeaveCriticalSection (&channel->mutex);
419   
420   g_io_channel_unref ((GIOChannel *)channel);
421   
422   /* No need to call _endthreadex(), the actual thread starter routine
423    * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
424    * _endthreadex() for us.
425    */
426
427   return 0;
428 }
429
430 static unsigned __stdcall
431 write_thread (void *parameter)
432 {
433   GIOWin32Channel *channel = parameter;
434   guchar *buffer;
435   gint nbytes;
436
437   g_io_channel_ref ((GIOChannel *)channel);
438
439   if (channel->debug)
440     g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
441              channel->thread_id,
442              channel->fd,
443              channel->data_avail_event,
444              channel->space_avail_event);
445   
446   channel->direction = 1;
447   channel->buffer = g_malloc (BUFFER_SIZE);
448   channel->rdp = channel->wrp = 0;
449   channel->running = TRUE;
450
451   SetEvent (channel->space_avail_event);
452
453   /* We use the same event objects as for a reader thread, but with
454    * reversed meaning. So, space_avail is used if data is available
455    * for writing, and data_avail is used if space is available in the
456    * write buffer.
457    */
458
459   EnterCriticalSection (&channel->mutex);
460   while (channel->running || channel->rdp != channel->wrp)
461     {
462       if (channel->debug)
463         g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
464                  channel->thread_id, channel->rdp, channel->wrp);
465       if (channel->wrp == channel->rdp)
466         {
467           /* Buffer is empty. */
468           if (channel->debug)
469             g_print ("write_thread %#x: resetting space_avail\n",
470                      channel->thread_id);
471           ResetEvent (channel->space_avail_event);
472           if (channel->debug)
473             g_print ("write_thread %#x: waiting for data\n",
474                      channel->thread_id);
475           channel->revents = G_IO_OUT;
476           SetEvent (channel->data_avail_event);
477           LeaveCriticalSection (&channel->mutex);
478           WaitForSingleObject (channel->space_avail_event, INFINITE);
479
480           EnterCriticalSection (&channel->mutex);
481           if (channel->rdp == channel->wrp)
482             break;
483
484           if (channel->debug)
485             g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
486                      channel->thread_id, channel->rdp, channel->wrp);
487         }
488       
489       buffer = channel->buffer + channel->rdp;
490       if (channel->rdp < channel->wrp)
491         nbytes = channel->wrp - channel->rdp;
492       else
493         nbytes = BUFFER_SIZE - channel->rdp;
494
495       if (channel->debug)
496         g_print ("write_thread %#x: calling write() for %d bytes\n",
497                  channel->thread_id, nbytes);
498
499       LeaveCriticalSection (&channel->mutex);
500       nbytes = write (channel->fd, buffer, nbytes);
501       EnterCriticalSection (&channel->mutex);
502
503       if (channel->debug)
504         g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
505                  channel->thread_id, channel->fd, nbytes, channel->rdp, channel->wrp);
506
507       channel->revents = 0;
508       if (nbytes > 0)
509         channel->revents |= G_IO_OUT;
510       else if (nbytes <= 0)
511         channel->revents |= G_IO_ERR;
512
513       channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
514
515       if (nbytes <= 0)
516         break;
517
518       if (channel->debug)
519         g_print ("write_thread: setting data_avail for thread %#x\n",
520                  channel->thread_id);
521       SetEvent (channel->data_avail_event);
522     }
523   
524   channel->running = FALSE;
525   if (channel->needs_close)
526     {
527       if (channel->debug)
528         g_print ("write_thread %#x: channel fd %d needs closing\n",
529                  channel->thread_id, channel->fd);
530       close (channel->fd);
531       channel->fd = -1;
532     }
533
534   LeaveCriticalSection (&channel->mutex);
535   
536   g_io_channel_unref ((GIOChannel *)channel);
537   
538   return 0;
539 }
540
541 static void
542 create_thread (GIOWin32Channel     *channel,
543                GIOCondition         condition,
544                unsigned (__stdcall *thread) (void *parameter))
545 {
546   HANDLE thread_handle;
547
548   thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
549                                            &channel->thread_id);
550   if (thread_handle == 0)
551     g_warning ("Error creating thread: %s.",
552                g_strerror (errno));
553   else if (!CloseHandle (thread_handle))
554     {
555       gchar *emsg = g_win32_error_message (GetLastError ());
556
557       g_warning ("Error closing thread handle: %s.", emsg);
558       g_free (emsg);
559     }
560
561   WaitForSingleObject (channel->space_avail_event, INFINITE);
562 }
563
564 static GIOStatus
565 buffer_read (GIOWin32Channel *channel,
566              gchar           *dest,
567              gsize            count,
568              gsize           *bytes_read,
569              GError         **err)
570 {
571   guint nbytes;
572   guint left = count;
573   
574   EnterCriticalSection (&channel->mutex);
575   if (channel->debug)
576     g_print ("reading from thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
577              channel->thread_id, count, channel->rdp, channel->wrp);
578   
579   if (channel->wrp == channel->rdp)
580     {
581       LeaveCriticalSection (&channel->mutex);
582       if (channel->debug)
583         g_print ("waiting for data from thread %#x\n", channel->thread_id);
584       WaitForSingleObject (channel->data_avail_event, INFINITE);
585       if (channel->debug)
586         g_print ("done waiting for data from thread %#x\n", channel->thread_id);
587       EnterCriticalSection (&channel->mutex);
588       if (channel->wrp == channel->rdp && !channel->running)
589         {
590           if (channel->debug)
591             g_print ("wrp==rdp, !running\n");
592           LeaveCriticalSection (&channel->mutex);
593           *bytes_read = 0;
594           return G_IO_STATUS_EOF;
595         }
596     }
597   
598   if (channel->rdp < channel->wrp)
599     nbytes = channel->wrp - channel->rdp;
600   else
601     nbytes = BUFFER_SIZE - channel->rdp;
602   LeaveCriticalSection (&channel->mutex);
603   nbytes = MIN (left, nbytes);
604   if (channel->debug)
605     g_print ("moving %d bytes from thread %#x\n",
606              nbytes, channel->thread_id);
607   memcpy (dest, channel->buffer + channel->rdp, nbytes);
608   dest += nbytes;
609   left -= nbytes;
610   EnterCriticalSection (&channel->mutex);
611   channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
612   if (channel->debug)
613     g_print ("setting space_avail for thread %#x\n", channel->thread_id);
614   SetEvent (channel->space_avail_event);
615   if (channel->debug)
616     g_print ("for thread %#x: rdp=%d, wrp=%d\n",
617              channel->thread_id, channel->rdp, channel->wrp);
618   if (channel->running && channel->wrp == channel->rdp)
619     {
620       if (channel->debug)
621         g_print ("resetting data_avail of thread %#x\n",
622                  channel->thread_id);
623       ResetEvent (channel->data_avail_event);
624     };
625   LeaveCriticalSection (&channel->mutex);
626   
627   /* We have no way to indicate any errors form the actual
628    * read() or recv() call in the reader thread. Should we have?
629    */
630   *bytes_read = count - left;
631   return (*bytes_read > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
632 }
633
634
635 static GIOStatus
636 buffer_write (GIOWin32Channel *channel,
637               const gchar     *dest,
638               gsize            count,
639               gsize           *bytes_written,
640               GError         **err)
641 {
642   guint nbytes;
643   guint left = count;
644   
645   EnterCriticalSection (&channel->mutex);
646   if (channel->debug)
647     g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
648              channel->thread_id, count, channel->rdp, channel->wrp);
649   
650   if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
651     {
652       /* Buffer is full */
653       if (channel->debug)
654         g_print ("buffer_write: tid %#x: resetting data_avail\n",
655                  channel->thread_id);
656       ResetEvent (channel->data_avail_event);
657       if (channel->debug)
658         g_print ("buffer_write: tid %#x: waiting for space\n",
659                  channel->thread_id);
660       LeaveCriticalSection (&channel->mutex);
661       WaitForSingleObject (channel->data_avail_event, INFINITE);
662       EnterCriticalSection (&channel->mutex);
663       if (channel->debug)
664         g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
665                  channel->thread_id, channel->rdp, channel->wrp);
666     }
667    
668   nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
669                 BUFFER_SIZE - channel->wrp);
670
671   LeaveCriticalSection (&channel->mutex);
672   nbytes = MIN (left, nbytes);
673   if (channel->debug)
674     g_print ("buffer_write: tid %#x: writing %d bytes\n",
675              channel->thread_id, nbytes);
676   memcpy (channel->buffer + channel->wrp, dest, nbytes);
677   dest += nbytes;
678   left -= nbytes;
679   EnterCriticalSection (&channel->mutex);
680
681   channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
682   if (channel->debug)
683     g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
684              channel->thread_id, channel->rdp, channel->wrp);
685   SetEvent (channel->space_avail_event);
686
687   if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
688     {
689       /* Buffer is full */
690       if (channel->debug)
691         g_print ("buffer_write: tid %#x: resetting data_avail\n",
692                  channel->thread_id);
693       ResetEvent (channel->data_avail_event);
694     }
695
696   LeaveCriticalSection (&channel->mutex);
697   
698   /* We have no way to indicate any errors form the actual
699    * write() call in the writer thread. Should we have?
700    */
701   *bytes_written = count - left;
702   return (*bytes_written > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
703 }
704
705
706 static gboolean
707 g_io_win32_prepare (GSource *source,
708                     gint    *timeout)
709 {
710   GIOWin32Watch *watch = (GIOWin32Watch *)source;
711   GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
712   GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
713   int event_mask;
714   
715   *timeout = -1;
716   
717   if (channel->debug)
718     g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel);
719
720   switch (channel->type)
721     {
722     case G_IO_WIN32_WINDOWS_MESSAGES:
723       if (channel->debug)
724         g_print (" MSG");
725       break;
726
727     case G_IO_WIN32_CONSOLE:
728       if (channel->debug)
729         g_print (" CON");
730       break;
731
732     case G_IO_WIN32_FILE_DESC:
733       if (channel->debug)
734         g_print (" FD thread=%#x buffer_condition:{%s}"
735                  "\n  watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}",
736                  channel->thread_id, condition_to_string (buffer_condition),
737                  condition_to_string (watch->pollfd.events),
738                  condition_to_string (watch->pollfd.revents),
739                  condition_to_string (channel->revents));
740       
741       EnterCriticalSection (&channel->mutex);
742       if (channel->running)
743         {
744           if (channel->direction == 0 && channel->wrp == channel->rdp)
745             {
746               if (channel->debug)
747                 g_print ("\n  setting revents=0");
748               channel->revents = 0;
749             }
750         }
751       else
752         {
753           if (channel->direction == 1
754               && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
755             {
756               if (channel->debug)
757                 g_print ("\n setting revents=0");
758               channel->revents = 0;
759             }
760         }         
761       LeaveCriticalSection (&channel->mutex);
762       break;
763
764     case G_IO_WIN32_SOCKET:
765       if (channel->debug)
766         g_print (" SOCK");
767       event_mask = 0;
768       if (watch->condition & G_IO_IN)
769         event_mask |= (FD_READ | FD_ACCEPT);
770       if (watch->condition & G_IO_OUT)
771         event_mask |= (FD_WRITE | FD_CONNECT);
772       event_mask |= FD_CLOSE;
773
774       if (channel->event_mask != event_mask)
775         {
776           if (channel->debug)
777             g_print ("\n  WSAEventSelect(%d,%p,{%s})",
778                      channel->fd, (HANDLE) watch->pollfd.fd,
779                      event_mask_to_string (event_mask));
780           if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd,
781                               event_mask) == SOCKET_ERROR)
782             if (channel->debug)
783               {
784                 gchar *emsg = g_win32_error_message (WSAGetLastError ());
785
786                 g_print (" failed: %s", emsg);
787                 g_free (emsg);
788               }
789           channel->event_mask = event_mask;
790
791           if (channel->debug)
792             g_print ("\n  setting last_events=0");
793           channel->last_events = 0;
794
795           if ((event_mask & FD_WRITE) &&
796               channel->ever_writable &&
797               !channel->write_would_have_blocked)
798             {
799               if (channel->debug)
800                 g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
801               WSASetEvent ((WSAEVENT) watch->pollfd.fd);
802             }
803         }
804       break;
805
806     default:
807       g_assert_not_reached ();
808       abort ();
809     }
810   if (channel->debug)
811     g_print ("\n");
812
813   return ((watch->condition & buffer_condition) == watch->condition);
814 }
815
816 static gboolean
817 g_io_win32_check (GSource *source)
818 {
819   MSG msg;
820   GIOWin32Watch *watch = (GIOWin32Watch *)source;
821   GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
822   GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
823   WSANETWORKEVENTS events;
824
825   if (channel->debug)
826     g_print ("g_io_win32_check: source=%p channel=%p", source, channel);
827
828   switch (channel->type)
829     {
830     case G_IO_WIN32_WINDOWS_MESSAGES:
831       if (channel->debug)
832         g_print (" MSG\n");
833       return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
834
835     case G_IO_WIN32_FILE_DESC:
836       if (channel->debug)
837         g_print (" FD thread=%#x buffer_condition=%s\n"
838                  "  watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
839                  channel->thread_id, condition_to_string (buffer_condition),
840                  condition_to_string (watch->pollfd.events),
841                  condition_to_string (watch->pollfd.revents),
842                  condition_to_string (channel->revents));
843       
844       watch->pollfd.revents = (watch->pollfd.events & channel->revents);
845
846       return ((watch->pollfd.revents | buffer_condition) & watch->condition);
847
848     case G_IO_WIN32_CONSOLE:
849       if (channel->debug)
850         g_print (" CON\n");
851       if (watch->channel->is_writeable)
852         return TRUE;
853       else if (watch->channel->is_readable)
854         {
855           INPUT_RECORD buffer;
856           DWORD n;
857           if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) &&
858               n == 1)
859             {
860               /* _kbhit() does quite complex processing to find out
861                * whether at least one of the key events pending corresponds
862                * to a "real" character that can be read.
863                */
864               if (_kbhit ())
865                 return TRUE;
866               
867               /* Discard all other kinds of events */
868               ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n);
869             }
870         }
871       return FALSE;
872
873     case G_IO_WIN32_SOCKET:
874       if (channel->debug)
875         g_print (" SOCK");
876       if (channel->last_events & FD_WRITE)
877         {
878           if (channel->debug)
879             g_print (" sock=%d event=%p last_events has FD_WRITE",
880                      channel->fd, (HANDLE) watch->pollfd.fd);
881         }
882       else
883         {
884           WSAEnumNetworkEvents (channel->fd, 0, &events);
885
886           if (channel->debug)
887             g_print ("\n  revents={%s} condition={%s}"
888                      "\n  WSAEnumNetworkEvents(%d,0) sets events={%s}",
889                      condition_to_string (watch->pollfd.revents),
890                      condition_to_string (watch->condition),
891                      channel->fd, 
892                      event_mask_to_string (events.lNetworkEvents));
893           
894           if (watch->pollfd.revents != 0 &&
895               events.lNetworkEvents == 0 &&
896               !(channel->event_mask & FD_WRITE))
897             {
898               channel->event_mask = 0;
899               if (channel->debug)
900                 g_print ("\n  WSAEventSelect(%d,%p,{})",
901                          channel->fd, (HANDLE) watch->pollfd.fd);
902               WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0);
903               if (channel->debug)
904                 g_print ("  ResetEvent(%p)",
905                          (HANDLE) watch->pollfd.fd);
906               ResetEvent ((HANDLE) watch->pollfd.fd);
907             }
908           else if (events.lNetworkEvents & FD_WRITE)
909             channel->ever_writable = TRUE;
910           channel->last_events = events.lNetworkEvents;
911         }
912
913       watch->pollfd.revents = 0;
914       if (channel->last_events & (FD_READ | FD_ACCEPT))
915         watch->pollfd.revents |= G_IO_IN;
916
917       if (channel->last_events & FD_WRITE)
918         watch->pollfd.revents |= G_IO_OUT;
919       else
920         {
921           /* We have called WSAEnumNetworkEvents() above but it didn't
922            * set FD_WRITE.
923            */
924           if (events.lNetworkEvents & FD_CONNECT)
925             {
926               if (events.iErrorCode[FD_CONNECT_BIT] == 0)
927                 watch->pollfd.revents |= G_IO_OUT;
928               else
929                 watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR);
930             }
931           if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
932             watch->pollfd.revents |= G_IO_HUP;
933         }
934
935       /* Regardless of WSAEnumNetworkEvents() result, if watching for
936        * writability, and if we have ever got a FD_WRITE event, and
937        * unless last write would have blocked, set G_IO_OUT. But never
938        * set both G_IO_OUT and G_IO_HUP.
939        */
940       if (!(watch->pollfd.revents & G_IO_HUP) &&
941           channel->ever_writable &&
942           !channel->write_would_have_blocked &&
943           (channel->event_mask & FD_WRITE))
944         watch->pollfd.revents |= G_IO_OUT;
945
946       if (channel->debug)
947         g_print ("\n  revents={%s} retval={%s}\n",
948                  condition_to_string (watch->pollfd.revents),
949                  condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
950
951       return ((watch->pollfd.revents | buffer_condition) & watch->condition);
952
953     default:
954       g_assert_not_reached ();
955       abort ();
956     }
957 }
958
959 static gboolean
960 g_io_win32_dispatch (GSource     *source,
961                      GSourceFunc  callback,
962                      gpointer     user_data)
963 {
964   GIOFunc func = (GIOFunc)callback;
965   GIOWin32Watch *watch = (GIOWin32Watch *)source;
966   GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
967   GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
968   
969   if (!func)
970     {
971       g_warning ("IO Watch dispatched without callback\n"
972                  "You must call g_source_connect().");
973       return FALSE;
974     }
975   
976   if (channel->debug)
977     g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
978              condition_to_string (watch->pollfd.revents),
979              condition_to_string (watch->condition),
980              condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
981
982   return (*func) (watch->channel,
983                   (watch->pollfd.revents | buffer_condition) & watch->condition,
984                   user_data);
985 }
986
987 static void
988 g_io_win32_finalize (GSource *source)
989 {
990   GIOWin32Watch *watch = (GIOWin32Watch *)source;
991   GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
992   
993   if (channel->debug)
994     g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel);
995
996   switch (channel->type)
997     {
998     case G_IO_WIN32_WINDOWS_MESSAGES:
999       if (channel->debug)
1000         g_print (" MSG");
1001       break;
1002
1003     case G_IO_WIN32_CONSOLE:
1004       if (channel->debug)
1005         g_print (" CON");
1006       break;
1007
1008     case G_IO_WIN32_FILE_DESC:
1009       if (channel->debug)
1010         g_print (" FD thread=%#x", channel->thread_id);
1011       break;
1012
1013     case G_IO_WIN32_SOCKET:
1014       if (channel->debug)
1015         g_print (" SOCK sock=%d", channel->fd);
1016       break;
1017
1018     default:
1019       g_assert_not_reached ();
1020       abort ();
1021     }
1022   if (channel->debug)
1023     g_print ("\n");
1024   g_io_channel_unref (watch->channel);
1025 }
1026
1027 GSourceFuncs g_io_watch_funcs = {
1028   g_io_win32_prepare,
1029   g_io_win32_check,
1030   g_io_win32_dispatch,
1031   g_io_win32_finalize
1032 };
1033
1034 static GIOStatus
1035 g_io_win32_msg_read (GIOChannel *channel,
1036                      gchar      *buf,
1037                      gsize       count,
1038                      gsize      *bytes_read,
1039                      GError    **err)
1040 {
1041   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1042   MSG msg;               /* In case of alignment problems */
1043   
1044   if (count < sizeof (MSG))
1045     {
1046       g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1047                            "Incorrect message size"); /* Informative enough error message? */
1048       return G_IO_STATUS_ERROR;
1049     }
1050   
1051   if (win32_channel->debug)
1052     g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n",
1053              channel, win32_channel->hwnd);
1054   if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
1055     return G_IO_STATUS_AGAIN;
1056
1057   memmove (buf, &msg, sizeof (MSG));
1058   *bytes_read = sizeof (MSG);
1059
1060   return G_IO_STATUS_NORMAL;
1061 }
1062
1063 static GIOStatus
1064 g_io_win32_msg_write (GIOChannel  *channel,
1065                       const gchar *buf,
1066                       gsize        count,
1067                       gsize       *bytes_written,
1068                       GError     **err)
1069 {
1070   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1071   MSG msg;
1072   
1073   if (count != sizeof (MSG))
1074     {
1075       g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1076                            "Incorrect message size"); /* Informative enough error message? */
1077       return G_IO_STATUS_ERROR;
1078     }
1079   
1080   /* In case of alignment problems */
1081   memmove (&msg, buf, sizeof (MSG));
1082   if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
1083     {
1084       gchar *emsg = g_win32_error_message (GetLastError ());
1085
1086       g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg);
1087       g_free (emsg);
1088
1089       return G_IO_STATUS_ERROR;
1090     }
1091
1092   *bytes_written = sizeof (MSG);
1093
1094   return G_IO_STATUS_NORMAL;
1095 }
1096
1097 static GIOStatus
1098 g_io_win32_msg_close (GIOChannel *channel,
1099                       GError    **err)
1100 {
1101   /* Nothing to be done. Or should we set hwnd to some invalid value? */
1102
1103   return G_IO_STATUS_NORMAL;
1104 }
1105
1106 static void
1107 g_io_win32_free (GIOChannel *channel)
1108 {
1109   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1110   
1111   if (win32_channel->debug)
1112     g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd);
1113
1114   DeleteCriticalSection (&win32_channel->mutex);
1115
1116   if (win32_channel->data_avail_event)
1117     if (!CloseHandle (win32_channel->data_avail_event))
1118       if (win32_channel->debug)
1119         {
1120           gchar *emsg = g_win32_error_message (GetLastError ());
1121
1122           g_print ("  CloseHandle(%p) failed: %s\n",
1123                    win32_channel->data_avail_event, emsg);
1124           g_free (emsg);
1125         }
1126
1127   g_free (win32_channel->buffer);
1128
1129   if (win32_channel->space_avail_event)
1130     if (!CloseHandle (win32_channel->space_avail_event))
1131       if (win32_channel->debug)
1132         {
1133           gchar *emsg = g_win32_error_message (GetLastError ());
1134
1135           g_print ("  CloseHandle(%p) failed: %s\n",
1136                    win32_channel->space_avail_event, emsg);
1137           g_free (emsg);
1138         }
1139
1140   if (win32_channel->type == G_IO_WIN32_SOCKET)
1141     if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR)
1142       if (win32_channel->debug)
1143         {
1144           gchar *emsg = g_win32_error_message (WSAGetLastError ());
1145
1146           g_print ("  WSAEventSelect(%d,NULL,{}) failed: %s\n",
1147                    win32_channel->fd, emsg);
1148           g_free (emsg);
1149         }
1150
1151   if (win32_channel->event)
1152     if (!WSACloseEvent (win32_channel->event))
1153       if (win32_channel->debug)
1154         {
1155           gchar *emsg = g_win32_error_message (WSAGetLastError ());
1156
1157           g_print ("  WSACloseEvent(%p) failed: %s\n",
1158                    win32_channel->event, emsg);
1159           g_free (emsg);
1160         }
1161
1162   g_free (win32_channel);
1163 }
1164
1165 static GSource *
1166 g_io_win32_msg_create_watch (GIOChannel   *channel,
1167                              GIOCondition  condition)
1168 {
1169   GIOWin32Watch *watch;
1170   GSource *source;
1171
1172   source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1173   watch = (GIOWin32Watch *)source;
1174   
1175   watch->channel = channel;
1176   g_io_channel_ref (channel);
1177   
1178   watch->condition = condition;
1179   
1180   watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE;
1181   watch->pollfd.events = condition;
1182   
1183   g_source_add_poll (source, &watch->pollfd);
1184   
1185   return source;
1186 }
1187
1188 static GIOStatus
1189 g_io_win32_fd_and_console_read (GIOChannel *channel,
1190                                 gchar      *buf,
1191                                 gsize       count,
1192                                 gsize      *bytes_read,
1193                                 GError    **err)
1194 {
1195   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1196   gint result;
1197   
1198   if (win32_channel->debug)
1199     g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
1200              win32_channel->fd, count);
1201   
1202   if (win32_channel->thread_id)
1203     {
1204       return buffer_read (win32_channel, buf, count, bytes_read, err);
1205     }
1206
1207   result = read (win32_channel->fd, buf, count);
1208
1209   if (win32_channel->debug)
1210     g_print ("g_io_win32_fd_read: read() => %d\n", result);
1211
1212   if (result < 0)
1213     {
1214       *bytes_read = 0;
1215
1216       switch (errno)
1217         {
1218 #ifdef EAGAIN
1219         case EAGAIN:
1220           return G_IO_STATUS_AGAIN;
1221 #endif
1222         default:
1223           g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1224                                g_io_channel_error_from_errno (errno),
1225                                g_strerror (errno));
1226           return G_IO_STATUS_ERROR;
1227         }
1228     }
1229
1230   *bytes_read = result;
1231
1232   return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
1233 }
1234
1235 static GIOStatus
1236 g_io_win32_fd_and_console_write (GIOChannel  *channel,
1237                                  const gchar *buf,
1238                                  gsize        count,
1239                                  gsize       *bytes_written,
1240                                  GError     **err)
1241 {
1242   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1243   gint result;
1244
1245   if (win32_channel->thread_id)
1246     {
1247       return buffer_write (win32_channel, buf, count, bytes_written, err);
1248     }
1249   
1250   result = write (win32_channel->fd, buf, count);
1251   if (win32_channel->debug)
1252     g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
1253              win32_channel->fd, count, result);
1254
1255   if (result < 0)
1256     {
1257       *bytes_written = 0;
1258
1259       switch (errno)
1260         {
1261 #ifdef EAGAIN
1262         case EAGAIN:
1263           return G_IO_STATUS_AGAIN;
1264 #endif
1265         default:
1266           g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1267                                g_io_channel_error_from_errno (errno),
1268                                g_strerror (errno));
1269           return G_IO_STATUS_ERROR;
1270         }
1271     }
1272
1273   *bytes_written = result;
1274
1275   return G_IO_STATUS_NORMAL;
1276 }
1277
1278 static GIOStatus
1279 g_io_win32_fd_seek (GIOChannel *channel,
1280                     gint64      offset,
1281                     GSeekType   type,
1282                     GError    **err)
1283 {
1284   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1285   int whence;
1286   off_t tmp_offset;
1287   off_t result;
1288   
1289   switch (type)
1290     {
1291     case G_SEEK_SET:
1292       whence = SEEK_SET;
1293       break;
1294     case G_SEEK_CUR:
1295       whence = SEEK_CUR;
1296       break;
1297     case G_SEEK_END:
1298       whence = SEEK_END;
1299       break;
1300     default:
1301       whence = -1; /* Keep the compiler quiet */
1302       g_assert_not_reached ();
1303       abort ();
1304     }
1305
1306   tmp_offset = offset;
1307   if (tmp_offset != offset)
1308     {
1309       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1310                            g_io_channel_error_from_errno (EINVAL),
1311                            g_strerror (EINVAL));
1312       return G_IO_STATUS_ERROR;
1313     }
1314   
1315   result = lseek (win32_channel->fd, tmp_offset, whence);
1316   
1317   if (result < 0)
1318     {
1319       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1320                            g_io_channel_error_from_errno (errno),
1321                            g_strerror (errno));
1322       return G_IO_STATUS_ERROR;
1323     }
1324
1325   return G_IO_STATUS_NORMAL;
1326 }
1327
1328 static GIOStatus
1329 g_io_win32_fd_close (GIOChannel *channel,
1330                      GError    **err)
1331 {
1332   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1333   
1334   if (win32_channel->debug)
1335     g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
1336              win32_channel->thread_id,
1337              win32_channel->fd);
1338   EnterCriticalSection (&win32_channel->mutex);
1339   if (win32_channel->running)
1340     {
1341       if (win32_channel->debug)
1342         g_print ("thread %#x: running, marking fd %d for later close\n",
1343                  win32_channel->thread_id, win32_channel->fd);
1344       win32_channel->running = FALSE;
1345       win32_channel->needs_close = TRUE;
1346       if (win32_channel->direction == 0)
1347         SetEvent (win32_channel->data_avail_event);
1348       else
1349         SetEvent (win32_channel->space_avail_event);
1350     }
1351   else
1352     {
1353       if (win32_channel->debug)
1354         g_print ("closing fd %d\n", win32_channel->fd);
1355       close (win32_channel->fd);
1356       if (win32_channel->debug)
1357         g_print ("closed fd %d, setting to -1\n",
1358                  win32_channel->fd);
1359       win32_channel->fd = -1;
1360     }
1361   LeaveCriticalSection (&win32_channel->mutex);
1362
1363   /* FIXME error detection? */
1364
1365   return G_IO_STATUS_NORMAL;
1366 }
1367
1368 static GSource *
1369 g_io_win32_fd_create_watch (GIOChannel    *channel,
1370                             GIOCondition   condition)
1371 {
1372   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1373   GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1374   GIOWin32Watch *watch = (GIOWin32Watch *)source;
1375
1376   watch->channel = channel;
1377   g_io_channel_ref (channel);
1378   
1379   watch->condition = condition;
1380   
1381   if (win32_channel->data_avail_event == NULL)
1382     create_events (win32_channel);
1383
1384   watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
1385   watch->pollfd.events = condition;
1386   
1387   if (win32_channel->debug)
1388     g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
1389              channel, win32_channel->fd,
1390              condition_to_string (condition), (HANDLE) watch->pollfd.fd);
1391
1392   EnterCriticalSection (&win32_channel->mutex);
1393   if (win32_channel->thread_id == 0)
1394     {
1395       if (condition & G_IO_IN)
1396         create_thread (win32_channel, condition, read_thread);
1397       else if (condition & G_IO_OUT)
1398         create_thread (win32_channel, condition, write_thread);
1399     }
1400
1401   g_source_add_poll (source, &watch->pollfd);
1402   LeaveCriticalSection (&win32_channel->mutex);
1403
1404   return source;
1405 }
1406
1407 static GIOStatus
1408 g_io_win32_console_close (GIOChannel *channel,
1409                           GError    **err)
1410 {
1411   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1412   
1413   if (close (win32_channel->fd) < 0)
1414     {
1415       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1416                            g_io_channel_error_from_errno (errno),
1417                            g_strerror (errno));
1418       return G_IO_STATUS_ERROR;
1419     }
1420
1421   return G_IO_STATUS_NORMAL;
1422 }
1423
1424 static GSource *
1425 g_io_win32_console_create_watch (GIOChannel    *channel,
1426                                  GIOCondition   condition)
1427 {
1428   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1429   GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1430   GIOWin32Watch *watch = (GIOWin32Watch *)source;
1431
1432   watch->channel = channel;
1433   g_io_channel_ref (channel);
1434   
1435   watch->condition = condition;
1436   
1437   watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
1438   watch->pollfd.events = condition;
1439   
1440   g_source_add_poll (source, &watch->pollfd);
1441
1442   return source;
1443 }
1444
1445 static GIOStatus
1446 g_io_win32_sock_read (GIOChannel *channel,
1447                       gchar      *buf,
1448                       gsize       count,
1449                       gsize      *bytes_read,
1450                       GError    **err)
1451 {
1452   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1453   gint result;
1454   GIOChannelError error;
1455   int winsock_error;
1456
1457   if (win32_channel->debug)
1458     g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1459              channel, win32_channel->fd, count);
1460
1461   result = recv (win32_channel->fd, buf, count, 0);
1462   if (result == SOCKET_ERROR)
1463     winsock_error = WSAGetLastError ();
1464
1465   if (win32_channel->debug)
1466     g_print (" recv=%d", result);
1467   
1468   if (result == SOCKET_ERROR)
1469     {
1470       gchar *emsg = g_win32_error_message (winsock_error);
1471
1472       if (win32_channel->debug)
1473         g_print (" %s\n", emsg);
1474
1475       *bytes_read = 0;
1476
1477       switch (winsock_error)
1478         {
1479         case WSAEINVAL:
1480           error = G_IO_CHANNEL_ERROR_INVAL;
1481           break;
1482         case WSAEWOULDBLOCK:
1483           g_free (emsg);
1484           return G_IO_STATUS_AGAIN;
1485         default:
1486           error = G_IO_CHANNEL_ERROR_FAILED;
1487           break;
1488         }
1489       g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1490       g_free (emsg);
1491
1492       return G_IO_STATUS_ERROR;
1493     }
1494   else
1495     {
1496       if (win32_channel->debug)
1497         g_print ("\n");
1498       *bytes_read = result;
1499       if (result == 0)
1500         return G_IO_STATUS_EOF;
1501       else
1502         return G_IO_STATUS_NORMAL;
1503     }
1504 }
1505
1506 static GIOStatus
1507 g_io_win32_sock_write (GIOChannel  *channel,
1508                        const gchar *buf,
1509                        gsize        count,
1510                        gsize       *bytes_written,
1511                        GError     **err)
1512 {
1513   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1514   gint result;
1515   GIOChannelError error;
1516   int winsock_error;
1517   
1518   if (win32_channel->debug)
1519     g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1520              channel, win32_channel->fd, count);
1521
1522   result = send (win32_channel->fd, buf, count, 0);
1523   if (result == SOCKET_ERROR)
1524     winsock_error = WSAGetLastError ();
1525
1526   if (win32_channel->debug)
1527     g_print (" send=%d", result);
1528   
1529   if (result == SOCKET_ERROR)
1530     {
1531       gchar *emsg = g_win32_error_message (winsock_error);
1532
1533       if (win32_channel->debug)
1534         g_print (" %s\n", emsg);
1535
1536       *bytes_written = 0;
1537
1538       switch (winsock_error)
1539         {
1540         case WSAEINVAL:
1541           error = G_IO_CHANNEL_ERROR_INVAL;
1542           break;
1543         case WSAEWOULDBLOCK:
1544           win32_channel->write_would_have_blocked = TRUE;
1545           win32_channel->last_events = 0;
1546           g_free (emsg);
1547           return G_IO_STATUS_AGAIN;
1548         default:
1549           error = G_IO_CHANNEL_ERROR_FAILED;
1550           break;
1551         }
1552       g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1553       g_free (emsg);
1554
1555       return G_IO_STATUS_ERROR;
1556     }
1557   else
1558     {
1559       if (win32_channel->debug)
1560         g_print ("\n");
1561       *bytes_written = result;
1562       win32_channel->write_would_have_blocked = FALSE;
1563
1564       return G_IO_STATUS_NORMAL;
1565     }
1566 }
1567
1568 static GIOStatus
1569 g_io_win32_sock_close (GIOChannel *channel,
1570                        GError    **err)
1571 {
1572   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1573
1574   if (win32_channel->fd != -1)
1575     {
1576       if (win32_channel->debug)
1577         g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
1578                  channel, win32_channel->fd);
1579       
1580       closesocket (win32_channel->fd);
1581       win32_channel->fd = -1;
1582     }
1583
1584   /* FIXME error detection? */
1585
1586   return G_IO_STATUS_NORMAL;
1587 }
1588
1589 static GSource *
1590 g_io_win32_sock_create_watch (GIOChannel    *channel,
1591                               GIOCondition   condition)
1592 {
1593   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1594   GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1595   GIOWin32Watch *watch = (GIOWin32Watch *)source;
1596   
1597   watch->channel = channel;
1598   g_io_channel_ref (channel);
1599   
1600   watch->condition = condition;
1601
1602   if (win32_channel->event == 0)
1603     win32_channel->event = WSACreateEvent ();
1604
1605   watch->pollfd.fd = (gintptr) win32_channel->event;
1606   watch->pollfd.events = condition;
1607   
1608   if (win32_channel->debug)
1609     g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
1610              channel, win32_channel->fd, (HANDLE) watch->pollfd.fd,
1611              condition_to_string (watch->condition));
1612
1613   g_source_add_poll (source, &watch->pollfd);
1614
1615   return source;
1616 }
1617
1618 GIOChannel *
1619 g_io_channel_new_file (const gchar  *filename,
1620                        const gchar  *mode,
1621                        GError      **error)
1622 {
1623   int fid, flags, pmode;
1624   GIOChannel *channel;
1625
1626   enum { /* Cheesy hack */
1627     MODE_R = 1 << 0,
1628     MODE_W = 1 << 1,
1629     MODE_A = 1 << 2,
1630     MODE_PLUS = 1 << 3,
1631   } 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 stat *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 stat 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 == fstat (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 GIOChannel *
1976 #if GLIB_SIZEOF_VOID_P == 8
1977 g_io_channel_win32_new_messages (gsize hwnd)
1978 #else
1979 g_io_channel_win32_new_messages (guint hwnd)
1980 #endif
1981 {
1982   GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
1983   GIOChannel *channel = (GIOChannel *)win32_channel;
1984
1985   g_io_channel_init (channel);
1986   g_io_channel_win32_init (win32_channel);
1987   if (win32_channel->debug)
1988     g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n",
1989              channel, (HWND) hwnd);
1990   channel->funcs = &win32_channel_msg_funcs;
1991   win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
1992   win32_channel->hwnd = (HWND) hwnd;
1993
1994   /* XXX: check this. */
1995   channel->is_readable = IsWindow (win32_channel->hwnd);
1996   channel->is_writeable = IsWindow (win32_channel->hwnd);
1997
1998   channel->is_seekable = FALSE;
1999
2000   return channel;
2001 }
2002
2003 static GIOChannel *
2004 g_io_channel_win32_new_fd_internal (gint         fd,
2005                                     struct stat *st)
2006 {
2007   GIOWin32Channel *win32_channel;
2008   GIOChannel *channel;
2009
2010   win32_channel = g_new (GIOWin32Channel, 1);
2011   channel = (GIOChannel *)win32_channel;
2012
2013   g_io_channel_init (channel);
2014   g_io_channel_win32_init (win32_channel);
2015
2016   win32_channel->fd = fd;
2017
2018   if (win32_channel->debug)
2019     g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n",
2020              channel, fd);
2021
2022   if (st->st_mode & _S_IFCHR) /* console */
2023     {
2024       channel->funcs = &win32_channel_console_funcs;
2025       win32_channel->type = G_IO_WIN32_CONSOLE;
2026       g_io_win32_console_get_flags_internal (channel);
2027     }
2028   else
2029     {
2030       channel->funcs = &win32_channel_fd_funcs;
2031       win32_channel->type = G_IO_WIN32_FILE_DESC;
2032       g_io_win32_fd_get_flags_internal (channel, st);
2033     }
2034   
2035   return channel;
2036 }
2037
2038 GIOChannel *
2039 g_io_channel_win32_new_fd (gint fd)
2040 {
2041   struct stat st;
2042
2043   if (fstat (fd, &st) == -1)
2044     {
2045       g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd);
2046       return NULL;
2047     }
2048
2049   return g_io_channel_win32_new_fd_internal (fd, &st);
2050 }
2051
2052 gint
2053 g_io_channel_win32_get_fd (GIOChannel *channel)
2054 {
2055   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2056
2057   return win32_channel->fd;
2058 }
2059
2060 GIOChannel *
2061 g_io_channel_win32_new_socket (int socket)
2062 {
2063   GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
2064   GIOChannel *channel = (GIOChannel *)win32_channel;
2065
2066   g_io_channel_init (channel);
2067   g_io_channel_win32_init (win32_channel);
2068   if (win32_channel->debug)
2069     g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
2070              channel, socket);
2071   channel->funcs = &win32_channel_sock_funcs;
2072   win32_channel->type = G_IO_WIN32_SOCKET;
2073   win32_channel->fd = socket;
2074
2075   channel->is_readable = TRUE;
2076   channel->is_writeable = TRUE;
2077   channel->is_seekable = FALSE;
2078
2079   return channel;
2080 }
2081
2082 GIOChannel *
2083 g_io_channel_unix_new (gint fd)
2084 {
2085   gboolean is_fd, is_socket;
2086   struct stat st;
2087   int optval, optlen;
2088
2089   is_fd = (fstat (fd, &st) == 0);
2090
2091   optlen = sizeof (optval);
2092   is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
2093
2094   if (is_fd && is_socket)
2095     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);
2096
2097   if (is_fd)
2098     return g_io_channel_win32_new_fd_internal (fd, &st);
2099
2100   if (is_socket)
2101     return g_io_channel_win32_new_socket(fd);
2102
2103   g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd);
2104
2105   return NULL;
2106 }
2107
2108 gint
2109 g_io_channel_unix_get_fd (GIOChannel *channel)
2110 {
2111   return g_io_channel_win32_get_fd (channel);
2112 }
2113
2114 void
2115 g_io_channel_win32_set_debug (GIOChannel *channel,
2116                               gboolean    flag)
2117 {
2118   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2119
2120   win32_channel->debug = flag;
2121 }
2122
2123 gint
2124 g_io_channel_win32_poll (GPollFD *fds,
2125                          gint     n_fds,
2126                          gint     timeout)
2127 {
2128   g_return_val_if_fail (n_fds >= 0, 0);
2129
2130   return g_poll (fds, n_fds, timeout);
2131 }
2132
2133 void
2134 g_io_channel_win32_make_pollfd (GIOChannel   *channel,
2135                                 GIOCondition  condition,
2136                                 GPollFD      *fd)
2137 {
2138   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2139
2140   switch (win32_channel->type)
2141     {
2142     case G_IO_WIN32_FILE_DESC:
2143       if (win32_channel->data_avail_event == NULL)
2144         create_events (win32_channel);
2145
2146       fd->fd = (gintptr) win32_channel->data_avail_event;
2147
2148       if (win32_channel->thread_id == 0)
2149         {
2150           /* Is it meaningful for a file descriptor to be polled for
2151            * both IN and OUT? For what kind of file descriptor would
2152            * that be? Doesn't seem to make sense, in practise the file
2153            * descriptors handled here are always read or write ends of
2154            * pipes surely, and thus unidirectional.
2155            */
2156           if (condition & G_IO_IN)
2157             create_thread (win32_channel, condition, read_thread);
2158           else if (condition & G_IO_OUT)
2159             create_thread (win32_channel, condition, write_thread);
2160         }
2161       break;
2162
2163     case G_IO_WIN32_CONSOLE:
2164       fd->fd = _get_osfhandle (win32_channel->fd);
2165       break;
2166
2167     case G_IO_WIN32_SOCKET:
2168       fd->fd = (gintptr) WSACreateEvent ();
2169       break;
2170       
2171     case G_IO_WIN32_WINDOWS_MESSAGES:
2172       fd->fd = G_WIN32_MSG_HANDLE;
2173       break;
2174
2175     default:
2176       g_assert_not_reached ();
2177       abort ();
2178     }
2179   
2180   fd->events = condition;
2181 }
2182
2183 #ifndef _WIN64
2184
2185 /* Binary compatibility */
2186 GIOChannel *
2187 g_io_channel_win32_new_stream_socket (int socket)
2188 {
2189   return g_io_channel_win32_new_socket (socket);
2190 }
2191
2192 #endif
2193
2194 #define __G_IO_WIN32_C__
2195 #include "galiasdef.c"