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