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