gwin32: Remove old win32 codepage ABI compat code
[glib.git] / glib / giowin32.c
blobe659585dcc5663a0fee14c32ed5e1dedcd32bdf1
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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
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.
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.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GLib Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GLib at ftp://ftp.gtk.org/pub/gtk/.
31 * Bugs that are related to the code in this file:
33 * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition
34 * http://bugzilla.gnome.org/show_bug.cgi?id=137968
36 * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely
37 * http://bugzilla.gnome.org/show_bug.cgi?id=324234
39 * Bug 331214 - g_io_channel async socket io stalls
40 * http://bugzilla.gnome.org/show_bug.cgi?id=331214
42 * Bug 338943 - Multiple watches on the same socket
43 * http://bugzilla.gnome.org/show_bug.cgi?id=338943
45 * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless
46 * http://bugzilla.gnome.org/show_bug.cgi?id=357674
48 * Bug 425156 - GIOChannel deadlocks on a win32 socket
49 * http://bugzilla.gnome.org/show_bug.cgi?id=425156
51 * Bug 468910 - giofunc condition=0
52 * http://bugzilla.gnome.org/show_bug.cgi?id=468910
54 * Bug 500246 - Bug fixes for giowin32
55 * http://bugzilla.gnome.org/show_bug.cgi?id=500246
57 * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows
58 * http://bugzilla.gnome.org/show_bug.cgi?id=548278
60 * Bug 548536 - giowin32 problem when adding and removing watches
61 * http://bugzilla.gnome.org/show_bug.cgi?id=548536
63 * When fixing bugs related to the code in this file, either the above
64 * bugs or others, make sure that the test programs attached to the
65 * above bugs continue to work.
68 #include "config.h"
70 #include "glib.h"
72 #include <stdlib.h>
73 #include <winsock2.h>
74 #include <windows.h>
75 #include <conio.h>
76 #include <fcntl.h>
77 #include <io.h>
78 #include <process.h>
79 #include <errno.h>
80 #include <sys/stat.h>
82 #include "gstdio.h"
83 #include "glibintl.h"
86 typedef struct _GIOWin32Channel GIOWin32Channel;
87 typedef struct _GIOWin32Watch GIOWin32Watch;
89 #define BUFFER_SIZE 4096
91 typedef enum {
92 G_IO_WIN32_WINDOWS_MESSAGES, /* Windows messages */
94 G_IO_WIN32_FILE_DESC, /* Unix-like file descriptors from
95 * _open() or _pipe(), except for
96 * console IO. Separate thread to read
97 * or write.
100 G_IO_WIN32_CONSOLE, /* Console IO (usually stdin, stdout, stderr) */
102 G_IO_WIN32_SOCKET /* Sockets. No separate thread. */
103 } GIOWin32ChannelType;
105 struct _GIOWin32Channel {
106 GIOChannel channel;
107 gint fd; /* Either a Unix-like file handle as provided
108 * by the Microsoft C runtime, or a SOCKET
109 * as provided by WinSock.
111 GIOWin32ChannelType type;
113 gboolean debug;
115 /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */
116 HWND hwnd; /* Handle of window, or NULL */
118 /* Fields used by G_IO_WIN32_FILE_DESC channels. */
119 CRITICAL_SECTION mutex;
121 int direction; /* 0 means we read from it,
122 * 1 means we write to it.
125 gboolean running; /* Is reader or writer thread
126 * running. FALSE if EOF has been
127 * reached by the reader thread.
130 gboolean needs_close; /* If the channel has been closed while
131 * the reader thread was still running.
134 guint thread_id; /* If non-NULL the channel has or has
135 * had a reader or writer thread.
137 HANDLE data_avail_event;
139 gushort revents;
141 /* Data is kept in a circular buffer. To be able to distinguish between
142 * empty and full buffers, we cannot fill it completely, but have to
143 * leave a one character gap.
145 * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
147 * Empty: wrp == rdp
148 * Full: (wrp + 1) % BUFFER_SIZE == rdp
149 * Partial: otherwise
151 guchar *buffer; /* (Circular) buffer */
152 gint wrp, rdp; /* Buffer indices for writing and reading */
153 HANDLE space_avail_event;
155 /* Fields used by G_IO_WIN32_SOCKET channels */
156 int event_mask;
157 int last_events;
158 HANDLE event;
159 gboolean write_would_have_blocked;
160 gboolean ever_writable;
163 struct _GIOWin32Watch {
164 GSource source;
165 GPollFD pollfd;
166 GIOChannel *channel;
167 GIOCondition condition;
170 static void
171 g_win32_print_access_mode (int flags)
173 g_print ("%s%s%s%s%s%s%s%s%s%s",
174 ((flags & 0x3) == _O_RDWR ? "O_RDWR" :
175 ((flags & 0x3) == _O_RDONLY ? "O_RDONLY" :
176 ((flags & 0x3) == _O_WRONLY ? "O_WRONLY" : "0"))),
177 (flags & _O_APPEND ? "|O_APPEND" : ""),
178 (flags & _O_RANDOM ? "|O_RANDOM" : ""),
179 (flags & _O_SEQUENTIAL ? "|O_SEQUENTIAL" : ""),
180 (flags & _O_TEMPORARY ? "|O_TEMPORARY" : ""),
181 (flags & _O_CREAT ? "|O_CREAT" : ""),
182 (flags & _O_TRUNC ? "|O_TRUNC" : ""),
183 (flags & _O_EXCL ? "|O_EXCL" : ""),
184 (flags & _O_TEXT ? "|O_TEXT" : ""),
185 (flags & _O_BINARY ? "|O_BINARY" : ""));
188 static void
189 g_win32_print_gioflags (GIOFlags flags)
191 char *bar = "";
193 if (flags & G_IO_FLAG_APPEND)
194 bar = "|", g_print ("APPEND");
195 if (flags & G_IO_FLAG_NONBLOCK)
196 g_print ("%sNONBLOCK", bar), bar = "|";
197 if (flags & G_IO_FLAG_IS_READABLE)
198 g_print ("%sREADABLE", bar), bar = "|";
199 if (flags & G_IO_FLAG_IS_WRITABLE)
200 g_print ("%sWRITABLE", bar), bar = "|";
201 if (flags & G_IO_FLAG_IS_SEEKABLE)
202 g_print ("%sSEEKABLE", bar), bar = "|";
205 static const char *
206 event_mask_to_string (int mask)
208 char buf[100];
209 int checked_bits = 0;
210 char *bufp = buf;
212 if (mask == 0)
213 return "";
215 #define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
217 BIT (READ);
218 BIT (WRITE);
219 BIT (OOB);
220 BIT (ACCEPT);
221 BIT (CONNECT);
222 BIT (CLOSE);
223 BIT (QOS);
224 BIT (GROUP_QOS);
225 BIT (ROUTING_INTERFACE_CHANGE);
226 BIT (ADDRESS_LIST_CHANGE);
228 #undef BIT
230 if ((mask & ~checked_bits) != 0)
231 bufp += sprintf (bufp, "|%#x", mask & ~checked_bits);
233 return g_quark_to_string (g_quark_from_string (buf));
236 static const char *
237 condition_to_string (GIOCondition condition)
239 char buf[100];
240 int checked_bits = 0;
241 char *bufp = buf;
243 if (condition == 0)
244 return "";
246 #define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
248 BIT (IN);
249 BIT (OUT);
250 BIT (PRI);
251 BIT (ERR);
252 BIT (HUP);
253 BIT (NVAL);
255 #undef BIT
257 if ((condition & ~checked_bits) != 0)
258 bufp += sprintf (bufp, "|%#x", condition & ~checked_bits);
260 return g_quark_to_string (g_quark_from_string (buf));
263 static gboolean
264 g_io_win32_get_debug_flag (void)
266 return (getenv ("G_IO_WIN32_DEBUG") != NULL);
269 static void
270 g_io_channel_win32_init (GIOWin32Channel *channel)
272 channel->debug = g_io_win32_get_debug_flag ();
274 InitializeCriticalSection (&channel->mutex);
275 channel->running = FALSE;
276 channel->needs_close = FALSE;
277 channel->thread_id = 0;
278 channel->data_avail_event = NULL;
279 channel->revents = 0;
280 channel->buffer = NULL;
281 channel->space_avail_event = NULL;
283 channel->event_mask = 0;
284 channel->last_events = 0;
285 channel->event = NULL;
286 channel->write_would_have_blocked = FALSE;
287 channel->ever_writable = FALSE;
290 static void
291 create_events (GIOWin32Channel *channel)
293 SECURITY_ATTRIBUTES sec_attrs;
295 sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
296 sec_attrs.lpSecurityDescriptor = NULL;
297 sec_attrs.bInheritHandle = FALSE;
299 /* The data available event is manual reset, the space available event
300 * is automatic reset.
302 if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
303 || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
305 gchar *emsg = g_win32_error_message (GetLastError ());
307 g_error ("Error creating event: %s", emsg);
308 g_free (emsg);
312 static unsigned __stdcall
313 read_thread (void *parameter)
315 GIOWin32Channel *channel = parameter;
316 guchar *buffer;
317 gint nbytes;
319 g_io_channel_ref ((GIOChannel *)channel);
321 if (channel->debug)
322 g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
323 channel->thread_id,
324 channel->fd,
325 channel->data_avail_event,
326 channel->space_avail_event);
328 channel->direction = 0;
329 channel->buffer = g_malloc (BUFFER_SIZE);
330 channel->rdp = channel->wrp = 0;
331 channel->running = TRUE;
333 SetEvent (channel->space_avail_event);
335 EnterCriticalSection (&channel->mutex);
336 while (channel->running)
338 if (channel->debug)
339 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
340 channel->thread_id, channel->rdp, channel->wrp);
341 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
343 /* Buffer is full */
344 if (channel->debug)
345 g_print ("read_thread %#x: resetting space_avail\n",
346 channel->thread_id);
347 ResetEvent (channel->space_avail_event);
348 if (channel->debug)
349 g_print ("read_thread %#x: waiting for space\n",
350 channel->thread_id);
351 LeaveCriticalSection (&channel->mutex);
352 WaitForSingleObject (channel->space_avail_event, INFINITE);
353 EnterCriticalSection (&channel->mutex);
354 if (channel->debug)
355 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
356 channel->thread_id, channel->rdp, channel->wrp);
359 buffer = channel->buffer + channel->wrp;
361 /* Always leave at least one byte unused gap to be able to
362 * distinguish between the full and empty condition...
364 nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
365 BUFFER_SIZE - channel->wrp);
367 if (channel->debug)
368 g_print ("read_thread %#x: calling read() for %d bytes\n",
369 channel->thread_id, nbytes);
371 LeaveCriticalSection (&channel->mutex);
373 nbytes = read (channel->fd, buffer, nbytes);
375 EnterCriticalSection (&channel->mutex);
377 channel->revents = G_IO_IN;
378 if (nbytes == 0)
379 channel->revents |= G_IO_HUP;
380 else if (nbytes < 0)
381 channel->revents |= G_IO_ERR;
383 if (channel->debug)
384 g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
385 channel->thread_id, nbytes, channel->rdp, channel->wrp);
387 if (nbytes <= 0)
388 break;
390 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
391 if (channel->debug)
392 g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
393 channel->thread_id, channel->rdp, channel->wrp);
394 SetEvent (channel->data_avail_event);
397 channel->running = FALSE;
398 if (channel->needs_close)
400 if (channel->debug)
401 g_print ("read_thread %#x: channel fd %d needs closing\n",
402 channel->thread_id, channel->fd);
403 close (channel->fd);
404 channel->fd = -1;
407 if (channel->debug)
408 g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
409 channel->thread_id, channel->rdp, channel->wrp);
410 SetEvent (channel->data_avail_event);
411 LeaveCriticalSection (&channel->mutex);
413 g_io_channel_unref ((GIOChannel *)channel);
415 /* No need to call _endthreadex(), the actual thread starter routine
416 * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
417 * _endthreadex() for us.
420 return 0;
423 static unsigned __stdcall
424 write_thread (void *parameter)
426 GIOWin32Channel *channel = parameter;
427 guchar *buffer;
428 gint nbytes;
430 g_io_channel_ref ((GIOChannel *)channel);
432 if (channel->debug)
433 g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
434 channel->thread_id,
435 channel->fd,
436 channel->data_avail_event,
437 channel->space_avail_event);
439 channel->direction = 1;
440 channel->buffer = g_malloc (BUFFER_SIZE);
441 channel->rdp = channel->wrp = 0;
442 channel->running = TRUE;
444 SetEvent (channel->space_avail_event);
446 /* We use the same event objects as for a reader thread, but with
447 * reversed meaning. So, space_avail is used if data is available
448 * for writing, and data_avail is used if space is available in the
449 * write buffer.
452 EnterCriticalSection (&channel->mutex);
453 while (channel->running || channel->rdp != channel->wrp)
455 if (channel->debug)
456 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
457 channel->thread_id, channel->rdp, channel->wrp);
458 if (channel->wrp == channel->rdp)
460 /* Buffer is empty. */
461 if (channel->debug)
462 g_print ("write_thread %#x: resetting space_avail\n",
463 channel->thread_id);
464 ResetEvent (channel->space_avail_event);
465 if (channel->debug)
466 g_print ("write_thread %#x: waiting for data\n",
467 channel->thread_id);
468 channel->revents = G_IO_OUT;
469 SetEvent (channel->data_avail_event);
470 LeaveCriticalSection (&channel->mutex);
471 WaitForSingleObject (channel->space_avail_event, INFINITE);
473 EnterCriticalSection (&channel->mutex);
474 if (channel->rdp == channel->wrp)
475 break;
477 if (channel->debug)
478 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
479 channel->thread_id, channel->rdp, channel->wrp);
482 buffer = channel->buffer + channel->rdp;
483 if (channel->rdp < channel->wrp)
484 nbytes = channel->wrp - channel->rdp;
485 else
486 nbytes = BUFFER_SIZE - channel->rdp;
488 if (channel->debug)
489 g_print ("write_thread %#x: calling write() for %d bytes\n",
490 channel->thread_id, nbytes);
492 LeaveCriticalSection (&channel->mutex);
493 nbytes = write (channel->fd, buffer, nbytes);
494 EnterCriticalSection (&channel->mutex);
496 if (channel->debug)
497 g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
498 channel->thread_id, channel->fd, nbytes, channel->rdp, channel->wrp);
500 channel->revents = 0;
501 if (nbytes > 0)
502 channel->revents |= G_IO_OUT;
503 else if (nbytes <= 0)
504 channel->revents |= G_IO_ERR;
506 channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
508 if (nbytes <= 0)
509 break;
511 if (channel->debug)
512 g_print ("write_thread: setting data_avail for thread %#x\n",
513 channel->thread_id);
514 SetEvent (channel->data_avail_event);
517 channel->running = FALSE;
518 if (channel->needs_close)
520 if (channel->debug)
521 g_print ("write_thread %#x: channel fd %d needs closing\n",
522 channel->thread_id, channel->fd);
523 close (channel->fd);
524 channel->fd = -1;
527 LeaveCriticalSection (&channel->mutex);
529 g_io_channel_unref ((GIOChannel *)channel);
531 return 0;
534 static void
535 create_thread (GIOWin32Channel *channel,
536 GIOCondition condition,
537 unsigned (__stdcall *thread) (void *parameter))
539 HANDLE thread_handle;
541 thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
542 &channel->thread_id);
543 if (thread_handle == 0)
544 g_warning ("Error creating thread: %s.",
545 g_strerror (errno));
546 else if (!CloseHandle (thread_handle))
548 gchar *emsg = g_win32_error_message (GetLastError ());
550 g_warning ("Error closing thread handle: %s.", emsg);
551 g_free (emsg);
554 WaitForSingleObject (channel->space_avail_event, INFINITE);
557 static GIOStatus
558 buffer_read (GIOWin32Channel *channel,
559 gchar *dest,
560 gsize count,
561 gsize *bytes_read,
562 GError **err)
564 guint nbytes;
565 guint left = count;
567 EnterCriticalSection (&channel->mutex);
568 if (channel->debug)
569 g_print ("reading from thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
570 channel->thread_id, count, channel->rdp, channel->wrp);
572 if (channel->wrp == channel->rdp)
574 LeaveCriticalSection (&channel->mutex);
575 if (channel->debug)
576 g_print ("waiting for data from thread %#x\n", channel->thread_id);
577 WaitForSingleObject (channel->data_avail_event, INFINITE);
578 if (channel->debug)
579 g_print ("done waiting for data from thread %#x\n", channel->thread_id);
580 EnterCriticalSection (&channel->mutex);
581 if (channel->wrp == channel->rdp && !channel->running)
583 if (channel->debug)
584 g_print ("wrp==rdp, !running\n");
585 LeaveCriticalSection (&channel->mutex);
586 *bytes_read = 0;
587 return G_IO_STATUS_EOF;
591 if (channel->rdp < channel->wrp)
592 nbytes = channel->wrp - channel->rdp;
593 else
594 nbytes = BUFFER_SIZE - channel->rdp;
595 LeaveCriticalSection (&channel->mutex);
596 nbytes = MIN (left, nbytes);
597 if (channel->debug)
598 g_print ("moving %d bytes from thread %#x\n",
599 nbytes, channel->thread_id);
600 memcpy (dest, channel->buffer + channel->rdp, nbytes);
601 dest += nbytes;
602 left -= nbytes;
603 EnterCriticalSection (&channel->mutex);
604 channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
605 if (channel->debug)
606 g_print ("setting space_avail for thread %#x\n", channel->thread_id);
607 SetEvent (channel->space_avail_event);
608 if (channel->debug)
609 g_print ("for thread %#x: rdp=%d, wrp=%d\n",
610 channel->thread_id, channel->rdp, channel->wrp);
611 if (channel->running && channel->wrp == channel->rdp)
613 if (channel->debug)
614 g_print ("resetting data_avail of thread %#x\n",
615 channel->thread_id);
616 ResetEvent (channel->data_avail_event);
618 LeaveCriticalSection (&channel->mutex);
620 /* We have no way to indicate any errors form the actual
621 * read() or recv() call in the reader thread. Should we have?
623 *bytes_read = count - left;
624 return (*bytes_read > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
628 static GIOStatus
629 buffer_write (GIOWin32Channel *channel,
630 const gchar *dest,
631 gsize count,
632 gsize *bytes_written,
633 GError **err)
635 guint nbytes;
636 guint left = count;
638 EnterCriticalSection (&channel->mutex);
639 if (channel->debug)
640 g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
641 channel->thread_id, count, channel->rdp, channel->wrp);
643 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
645 /* Buffer is full */
646 if (channel->debug)
647 g_print ("buffer_write: tid %#x: resetting data_avail\n",
648 channel->thread_id);
649 ResetEvent (channel->data_avail_event);
650 if (channel->debug)
651 g_print ("buffer_write: tid %#x: waiting for space\n",
652 channel->thread_id);
653 LeaveCriticalSection (&channel->mutex);
654 WaitForSingleObject (channel->data_avail_event, INFINITE);
655 EnterCriticalSection (&channel->mutex);
656 if (channel->debug)
657 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
658 channel->thread_id, channel->rdp, channel->wrp);
661 nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
662 BUFFER_SIZE - channel->wrp);
664 LeaveCriticalSection (&channel->mutex);
665 nbytes = MIN (left, nbytes);
666 if (channel->debug)
667 g_print ("buffer_write: tid %#x: writing %d bytes\n",
668 channel->thread_id, nbytes);
669 memcpy (channel->buffer + channel->wrp, dest, nbytes);
670 dest += nbytes;
671 left -= nbytes;
672 EnterCriticalSection (&channel->mutex);
674 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
675 if (channel->debug)
676 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
677 channel->thread_id, channel->rdp, channel->wrp);
678 SetEvent (channel->space_avail_event);
680 if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
682 /* Buffer is full */
683 if (channel->debug)
684 g_print ("buffer_write: tid %#x: resetting data_avail\n",
685 channel->thread_id);
686 ResetEvent (channel->data_avail_event);
689 LeaveCriticalSection (&channel->mutex);
691 /* We have no way to indicate any errors form the actual
692 * write() call in the writer thread. Should we have?
694 *bytes_written = count - left;
695 return (*bytes_written > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
699 static gboolean
700 g_io_win32_prepare (GSource *source,
701 gint *timeout)
703 GIOWin32Watch *watch = (GIOWin32Watch *)source;
704 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
705 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
706 int event_mask;
708 *timeout = -1;
710 if (channel->debug)
711 g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel);
713 switch (channel->type)
715 case G_IO_WIN32_WINDOWS_MESSAGES:
716 if (channel->debug)
717 g_print (" MSG");
718 break;
720 case G_IO_WIN32_CONSOLE:
721 if (channel->debug)
722 g_print (" CON");
723 break;
725 case G_IO_WIN32_FILE_DESC:
726 if (channel->debug)
727 g_print (" FD thread=%#x buffer_condition:{%s}"
728 "\n watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}",
729 channel->thread_id, condition_to_string (buffer_condition),
730 condition_to_string (watch->pollfd.events),
731 condition_to_string (watch->pollfd.revents),
732 condition_to_string (channel->revents));
734 EnterCriticalSection (&channel->mutex);
735 if (channel->running)
737 if (channel->direction == 0 && channel->wrp == channel->rdp)
739 if (channel->debug)
740 g_print ("\n setting revents=0");
741 channel->revents = 0;
744 else
746 if (channel->direction == 1
747 && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
749 if (channel->debug)
750 g_print ("\n setting revents=0");
751 channel->revents = 0;
754 LeaveCriticalSection (&channel->mutex);
755 break;
757 case G_IO_WIN32_SOCKET:
758 if (channel->debug)
759 g_print (" SOCK");
760 event_mask = 0;
761 if (watch->condition & G_IO_IN)
762 event_mask |= (FD_READ | FD_ACCEPT);
763 if (watch->condition & G_IO_OUT)
764 event_mask |= (FD_WRITE | FD_CONNECT);
765 event_mask |= FD_CLOSE;
767 if (channel->event_mask != event_mask)
769 if (channel->debug)
770 g_print ("\n WSAEventSelect(%d,%p,{%s})",
771 channel->fd, (HANDLE) watch->pollfd.fd,
772 event_mask_to_string (event_mask));
773 if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd,
774 event_mask) == SOCKET_ERROR)
775 if (channel->debug)
777 gchar *emsg = g_win32_error_message (WSAGetLastError ());
779 g_print (" failed: %s", emsg);
780 g_free (emsg);
782 channel->event_mask = event_mask;
784 if (channel->debug)
785 g_print ("\n setting last_events=0");
786 channel->last_events = 0;
788 if ((event_mask & FD_WRITE) &&
789 channel->ever_writable &&
790 !channel->write_would_have_blocked)
792 if (channel->debug)
793 g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
794 WSASetEvent ((WSAEVENT) watch->pollfd.fd);
797 break;
799 default:
800 g_assert_not_reached ();
801 g_abort ();
803 if (channel->debug)
804 g_print ("\n");
806 return ((watch->condition & buffer_condition) == watch->condition);
809 static gboolean
810 g_io_win32_check (GSource *source)
812 MSG msg;
813 GIOWin32Watch *watch = (GIOWin32Watch *)source;
814 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
815 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
816 WSANETWORKEVENTS events;
818 if (channel->debug)
819 g_print ("g_io_win32_check: source=%p channel=%p", source, channel);
821 switch (channel->type)
823 case G_IO_WIN32_WINDOWS_MESSAGES:
824 if (channel->debug)
825 g_print (" MSG\n");
826 return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
828 case G_IO_WIN32_FILE_DESC:
829 if (channel->debug)
830 g_print (" FD thread=%#x buffer_condition=%s\n"
831 " watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
832 channel->thread_id, condition_to_string (buffer_condition),
833 condition_to_string (watch->pollfd.events),
834 condition_to_string (watch->pollfd.revents),
835 condition_to_string (channel->revents));
837 watch->pollfd.revents = (watch->pollfd.events & channel->revents);
839 return ((watch->pollfd.revents | buffer_condition) & watch->condition);
841 case G_IO_WIN32_CONSOLE:
842 if (channel->debug)
843 g_print (" CON\n");
844 if (watch->channel->is_writeable)
845 return TRUE;
846 else if (watch->channel->is_readable)
848 INPUT_RECORD buffer;
849 DWORD n;
850 if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) &&
851 n == 1)
853 /* _kbhit() does quite complex processing to find out
854 * whether at least one of the key events pending corresponds
855 * to a "real" character that can be read.
857 if (_kbhit ())
858 return TRUE;
860 /* Discard all other kinds of events */
861 ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n);
864 return FALSE;
866 case G_IO_WIN32_SOCKET:
867 if (channel->debug)
868 g_print (" SOCK");
869 if (channel->last_events & FD_WRITE)
871 if (channel->debug)
872 g_print (" sock=%d event=%p last_events has FD_WRITE",
873 channel->fd, (HANDLE) watch->pollfd.fd);
875 else
877 WSAEnumNetworkEvents (channel->fd, 0, &events);
879 if (channel->debug)
880 g_print ("\n revents={%s} condition={%s}"
881 "\n WSAEnumNetworkEvents(%d,0) sets events={%s}",
882 condition_to_string (watch->pollfd.revents),
883 condition_to_string (watch->condition),
884 channel->fd,
885 event_mask_to_string (events.lNetworkEvents));
887 if (watch->pollfd.revents != 0 &&
888 events.lNetworkEvents == 0 &&
889 !(channel->event_mask & FD_WRITE))
891 channel->event_mask = 0;
892 if (channel->debug)
893 g_print ("\n WSAEventSelect(%d,%p,{})",
894 channel->fd, (HANDLE) watch->pollfd.fd);
895 WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0);
896 if (channel->debug)
897 g_print (" ResetEvent(%p)",
898 (HANDLE) watch->pollfd.fd);
899 ResetEvent ((HANDLE) watch->pollfd.fd);
901 else if (events.lNetworkEvents & FD_WRITE)
902 channel->ever_writable = TRUE;
903 channel->last_events = events.lNetworkEvents;
906 watch->pollfd.revents = 0;
907 if (channel->last_events & (FD_READ | FD_ACCEPT))
908 watch->pollfd.revents |= G_IO_IN;
910 if (channel->last_events & FD_WRITE)
911 watch->pollfd.revents |= G_IO_OUT;
912 else
914 /* We have called WSAEnumNetworkEvents() above but it didn't
915 * set FD_WRITE.
917 if (events.lNetworkEvents & FD_CONNECT)
919 if (events.iErrorCode[FD_CONNECT_BIT] == 0)
920 watch->pollfd.revents |= G_IO_OUT;
921 else
922 watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR);
924 if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
925 watch->pollfd.revents |= G_IO_HUP;
928 /* Regardless of WSAEnumNetworkEvents() result, if watching for
929 * writability, and if we have ever got a FD_WRITE event, and
930 * unless last write would have blocked, set G_IO_OUT. But never
931 * set both G_IO_OUT and G_IO_HUP.
933 if (!(watch->pollfd.revents & G_IO_HUP) &&
934 channel->ever_writable &&
935 !channel->write_would_have_blocked &&
936 (channel->event_mask & FD_WRITE))
937 watch->pollfd.revents |= G_IO_OUT;
939 if (channel->debug)
940 g_print ("\n revents={%s} retval={%s}\n",
941 condition_to_string (watch->pollfd.revents),
942 condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
944 return ((watch->pollfd.revents | buffer_condition) & watch->condition);
946 default:
947 g_assert_not_reached ();
948 g_abort ();
952 static gboolean
953 g_io_win32_dispatch (GSource *source,
954 GSourceFunc callback,
955 gpointer user_data)
957 GIOFunc func = (GIOFunc)callback;
958 GIOWin32Watch *watch = (GIOWin32Watch *)source;
959 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
960 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
962 if (!func)
964 g_warning ("IO Watch dispatched without callback\n"
965 "You must call g_source_connect().");
966 return FALSE;
969 if (channel->debug)
970 g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
971 condition_to_string (watch->pollfd.revents),
972 condition_to_string (watch->condition),
973 condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
975 return (*func) (watch->channel,
976 (watch->pollfd.revents | buffer_condition) & watch->condition,
977 user_data);
980 static void
981 g_io_win32_finalize (GSource *source)
983 GIOWin32Watch *watch = (GIOWin32Watch *)source;
984 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
986 if (channel->debug)
987 g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel);
989 switch (channel->type)
991 case G_IO_WIN32_WINDOWS_MESSAGES:
992 if (channel->debug)
993 g_print (" MSG");
994 break;
996 case G_IO_WIN32_CONSOLE:
997 if (channel->debug)
998 g_print (" CON");
999 break;
1001 case G_IO_WIN32_FILE_DESC:
1002 if (channel->debug)
1003 g_print (" FD thread=%#x", channel->thread_id);
1004 break;
1006 case G_IO_WIN32_SOCKET:
1007 if (channel->debug)
1008 g_print (" SOCK sock=%d", channel->fd);
1009 break;
1011 default:
1012 g_assert_not_reached ();
1013 g_abort ();
1015 if (channel->debug)
1016 g_print ("\n");
1017 g_io_channel_unref (watch->channel);
1020 GSourceFuncs g_io_watch_funcs = {
1021 g_io_win32_prepare,
1022 g_io_win32_check,
1023 g_io_win32_dispatch,
1024 g_io_win32_finalize
1027 static GIOStatus
1028 g_io_win32_msg_read (GIOChannel *channel,
1029 gchar *buf,
1030 gsize count,
1031 gsize *bytes_read,
1032 GError **err)
1034 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1035 MSG msg; /* In case of alignment problems */
1037 *bytes_read = 0;
1039 if (count < sizeof (MSG))
1041 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1042 "Incorrect message size"); /* Informative enough error message? */
1043 return G_IO_STATUS_ERROR;
1046 if (win32_channel->debug)
1047 g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n",
1048 channel, win32_channel->hwnd);
1049 if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
1050 return G_IO_STATUS_AGAIN;
1052 memmove (buf, &msg, sizeof (MSG));
1053 *bytes_read = sizeof (MSG);
1055 return G_IO_STATUS_NORMAL;
1058 static GIOStatus
1059 g_io_win32_msg_write (GIOChannel *channel,
1060 const gchar *buf,
1061 gsize count,
1062 gsize *bytes_written,
1063 GError **err)
1065 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1066 MSG msg;
1068 *bytes_written = 0;
1070 if (count != sizeof (MSG))
1072 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1073 "Incorrect message size"); /* Informative enough error message? */
1074 return G_IO_STATUS_ERROR;
1077 /* In case of alignment problems */
1078 memmove (&msg, buf, sizeof (MSG));
1079 if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
1081 gchar *emsg = g_win32_error_message (GetLastError ());
1083 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg);
1084 g_free (emsg);
1086 return G_IO_STATUS_ERROR;
1089 *bytes_written = sizeof (MSG);
1091 return G_IO_STATUS_NORMAL;
1094 static GIOStatus
1095 g_io_win32_msg_close (GIOChannel *channel,
1096 GError **err)
1098 /* Nothing to be done. Or should we set hwnd to some invalid value? */
1100 return G_IO_STATUS_NORMAL;
1103 static void
1104 g_io_win32_free (GIOChannel *channel)
1106 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1108 if (win32_channel->debug)
1109 g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd);
1111 DeleteCriticalSection (&win32_channel->mutex);
1113 if (win32_channel->data_avail_event)
1114 if (!CloseHandle (win32_channel->data_avail_event))
1115 if (win32_channel->debug)
1117 gchar *emsg = g_win32_error_message (GetLastError ());
1119 g_print (" CloseHandle(%p) failed: %s\n",
1120 win32_channel->data_avail_event, emsg);
1121 g_free (emsg);
1124 g_free (win32_channel->buffer);
1126 if (win32_channel->space_avail_event)
1127 if (!CloseHandle (win32_channel->space_avail_event))
1128 if (win32_channel->debug)
1130 gchar *emsg = g_win32_error_message (GetLastError ());
1132 g_print (" CloseHandle(%p) failed: %s\n",
1133 win32_channel->space_avail_event, emsg);
1134 g_free (emsg);
1137 if (win32_channel->type == G_IO_WIN32_SOCKET &&
1138 win32_channel->fd != -1)
1139 if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR)
1140 if (win32_channel->debug)
1142 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1144 g_print (" WSAEventSelect(%d,NULL,{}) failed: %s\n",
1145 win32_channel->fd, emsg);
1146 g_free (emsg);
1149 if (win32_channel->event)
1150 if (!WSACloseEvent (win32_channel->event))
1151 if (win32_channel->debug)
1153 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1155 g_print (" WSACloseEvent(%p) failed: %s\n",
1156 win32_channel->event, emsg);
1157 g_free (emsg);
1160 g_free (win32_channel);
1163 static GSource *
1164 g_io_win32_msg_create_watch (GIOChannel *channel,
1165 GIOCondition condition)
1167 GIOWin32Watch *watch;
1168 GSource *source;
1170 source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1171 g_source_set_name (source, "GIOChannel (Win32)");
1172 watch = (GIOWin32Watch *)source;
1174 watch->channel = channel;
1175 g_io_channel_ref (channel);
1177 watch->condition = condition;
1179 watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE;
1180 watch->pollfd.events = condition;
1182 g_source_add_poll (source, &watch->pollfd);
1184 return source;
1187 static GIOStatus
1188 g_io_win32_fd_and_console_read (GIOChannel *channel,
1189 gchar *buf,
1190 gsize count,
1191 gsize *bytes_read,
1192 GError **err)
1194 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1195 gint result;
1197 if (win32_channel->debug)
1198 g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
1199 win32_channel->fd, count);
1201 if (win32_channel->thread_id)
1203 return buffer_read (win32_channel, buf, count, bytes_read, err);
1206 result = read (win32_channel->fd, buf, count);
1208 if (win32_channel->debug)
1209 g_print ("g_io_win32_fd_read: read() => %d\n", result);
1211 if (result < 0)
1213 *bytes_read = 0;
1215 switch (errno)
1217 #ifdef EAGAIN
1218 case EAGAIN:
1219 return G_IO_STATUS_AGAIN;
1220 #endif
1221 default:
1222 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1223 g_io_channel_error_from_errno (errno),
1224 g_strerror (errno));
1225 return G_IO_STATUS_ERROR;
1229 *bytes_read = result;
1231 return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
1234 static GIOStatus
1235 g_io_win32_fd_and_console_write (GIOChannel *channel,
1236 const gchar *buf,
1237 gsize count,
1238 gsize *bytes_written,
1239 GError **err)
1241 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1242 gint result;
1244 if (win32_channel->thread_id)
1246 return buffer_write (win32_channel, buf, count, bytes_written, err);
1249 result = write (win32_channel->fd, buf, count);
1250 if (win32_channel->debug)
1251 g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
1252 win32_channel->fd, count, result);
1254 if (result < 0)
1256 *bytes_written = 0;
1258 switch (errno)
1260 #ifdef EAGAIN
1261 case EAGAIN:
1262 return G_IO_STATUS_AGAIN;
1263 #endif
1264 default:
1265 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1266 g_io_channel_error_from_errno (errno),
1267 g_strerror (errno));
1268 return G_IO_STATUS_ERROR;
1272 *bytes_written = result;
1274 return G_IO_STATUS_NORMAL;
1277 static GIOStatus
1278 g_io_win32_fd_seek (GIOChannel *channel,
1279 gint64 offset,
1280 GSeekType type,
1281 GError **err)
1283 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1284 int whence;
1285 off_t tmp_offset;
1286 off_t result;
1288 switch (type)
1290 case G_SEEK_SET:
1291 whence = SEEK_SET;
1292 break;
1293 case G_SEEK_CUR:
1294 whence = SEEK_CUR;
1295 break;
1296 case G_SEEK_END:
1297 whence = SEEK_END;
1298 break;
1299 default:
1300 whence = -1; /* Keep the compiler quiet */
1301 g_assert_not_reached ();
1302 g_abort ();
1305 tmp_offset = offset;
1306 if (tmp_offset != offset)
1308 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1309 g_io_channel_error_from_errno (EINVAL),
1310 g_strerror (EINVAL));
1311 return G_IO_STATUS_ERROR;
1314 result = lseek (win32_channel->fd, tmp_offset, whence);
1316 if (result < 0)
1318 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1319 g_io_channel_error_from_errno (errno),
1320 g_strerror (errno));
1321 return G_IO_STATUS_ERROR;
1324 return G_IO_STATUS_NORMAL;
1327 static GIOStatus
1328 g_io_win32_fd_close (GIOChannel *channel,
1329 GError **err)
1331 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
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)
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);
1350 else
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;
1360 LeaveCriticalSection (&win32_channel->mutex);
1362 /* FIXME error detection? */
1364 return G_IO_STATUS_NORMAL;
1367 static GSource *
1368 g_io_win32_fd_create_watch (GIOChannel *channel,
1369 GIOCondition condition)
1371 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1372 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1373 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1375 watch->channel = channel;
1376 g_io_channel_ref (channel);
1378 watch->condition = condition;
1380 if (win32_channel->data_avail_event == NULL)
1381 create_events (win32_channel);
1383 watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
1384 watch->pollfd.events = condition;
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);
1391 EnterCriticalSection (&win32_channel->mutex);
1392 if (win32_channel->thread_id == 0)
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);
1400 g_source_add_poll (source, &watch->pollfd);
1401 LeaveCriticalSection (&win32_channel->mutex);
1403 return source;
1406 static GIOStatus
1407 g_io_win32_console_close (GIOChannel *channel,
1408 GError **err)
1410 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1412 if (close (win32_channel->fd) < 0)
1414 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1415 g_io_channel_error_from_errno (errno),
1416 g_strerror (errno));
1417 return G_IO_STATUS_ERROR;
1420 return G_IO_STATUS_NORMAL;
1423 static GSource *
1424 g_io_win32_console_create_watch (GIOChannel *channel,
1425 GIOCondition condition)
1427 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1428 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1429 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1431 watch->channel = channel;
1432 g_io_channel_ref (channel);
1434 watch->condition = condition;
1436 watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
1437 watch->pollfd.events = condition;
1439 g_source_add_poll (source, &watch->pollfd);
1441 return source;
1444 static GIOStatus
1445 g_io_win32_sock_read (GIOChannel *channel,
1446 gchar *buf,
1447 gsize count,
1448 gsize *bytes_read,
1449 GError **err)
1451 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1452 gint result;
1453 GIOChannelError error;
1454 int winsock_error;
1456 if (win32_channel->debug)
1457 g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1458 channel, win32_channel->fd, count);
1460 result = recv (win32_channel->fd, buf, count, 0);
1461 if (result == SOCKET_ERROR)
1462 winsock_error = WSAGetLastError ();
1464 if (win32_channel->debug)
1465 g_print (" recv=%d", result);
1467 if (result == SOCKET_ERROR)
1469 gchar *emsg = g_win32_error_message (winsock_error);
1471 if (win32_channel->debug)
1472 g_print (" %s\n", emsg);
1474 *bytes_read = 0;
1476 switch (winsock_error)
1478 case WSAEINVAL:
1479 error = G_IO_CHANNEL_ERROR_INVAL;
1480 break;
1481 case WSAEWOULDBLOCK:
1482 g_free (emsg);
1483 return G_IO_STATUS_AGAIN;
1484 default:
1485 error = G_IO_CHANNEL_ERROR_FAILED;
1486 break;
1488 g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1489 g_free (emsg);
1491 return G_IO_STATUS_ERROR;
1493 else
1495 if (win32_channel->debug)
1496 g_print ("\n");
1497 *bytes_read = result;
1498 if (result == 0)
1499 return G_IO_STATUS_EOF;
1500 else
1501 return G_IO_STATUS_NORMAL;
1505 static GIOStatus
1506 g_io_win32_sock_write (GIOChannel *channel,
1507 const gchar *buf,
1508 gsize count,
1509 gsize *bytes_written,
1510 GError **err)
1512 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1513 gint result;
1514 GIOChannelError error;
1515 int winsock_error;
1517 if (win32_channel->debug)
1518 g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1519 channel, win32_channel->fd, count);
1521 result = send (win32_channel->fd, buf, count, 0);
1522 if (result == SOCKET_ERROR)
1523 winsock_error = WSAGetLastError ();
1525 if (win32_channel->debug)
1526 g_print (" send=%d", result);
1528 if (result == SOCKET_ERROR)
1530 gchar *emsg = g_win32_error_message (winsock_error);
1532 if (win32_channel->debug)
1533 g_print (" %s\n", emsg);
1535 *bytes_written = 0;
1537 switch (winsock_error)
1539 case WSAEINVAL:
1540 error = G_IO_CHANNEL_ERROR_INVAL;
1541 break;
1542 case WSAEWOULDBLOCK:
1543 win32_channel->write_would_have_blocked = TRUE;
1544 win32_channel->last_events = 0;
1545 g_free (emsg);
1546 return G_IO_STATUS_AGAIN;
1547 default:
1548 error = G_IO_CHANNEL_ERROR_FAILED;
1549 break;
1551 g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1552 g_free (emsg);
1554 return G_IO_STATUS_ERROR;
1556 else
1558 if (win32_channel->debug)
1559 g_print ("\n");
1560 *bytes_written = result;
1561 win32_channel->write_would_have_blocked = FALSE;
1563 return G_IO_STATUS_NORMAL;
1567 static GIOStatus
1568 g_io_win32_sock_close (GIOChannel *channel,
1569 GError **err)
1571 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1573 if (win32_channel->fd != -1)
1575 if (win32_channel->debug)
1576 g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
1577 channel, win32_channel->fd);
1579 closesocket (win32_channel->fd);
1580 win32_channel->fd = -1;
1583 /* FIXME error detection? */
1585 return G_IO_STATUS_NORMAL;
1588 static GSource *
1589 g_io_win32_sock_create_watch (GIOChannel *channel,
1590 GIOCondition condition)
1592 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1593 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1594 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1596 watch->channel = channel;
1597 g_io_channel_ref (channel);
1599 watch->condition = condition;
1601 if (win32_channel->event == 0)
1602 win32_channel->event = WSACreateEvent ();
1604 watch->pollfd.fd = (gintptr) win32_channel->event;
1605 watch->pollfd.events = condition;
1607 if (win32_channel->debug)
1608 g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
1609 channel, win32_channel->fd, (HANDLE) watch->pollfd.fd,
1610 condition_to_string (watch->condition));
1612 g_source_add_poll (source, &watch->pollfd);
1614 return source;
1617 GIOChannel *
1618 g_io_channel_new_file (const gchar *filename,
1619 const gchar *mode,
1620 GError **error)
1622 int fid, flags, pmode;
1623 GIOChannel *channel;
1625 enum { /* Cheesy hack */
1626 MODE_R = 1 << 0,
1627 MODE_W = 1 << 1,
1628 MODE_A = 1 << 2,
1629 MODE_PLUS = 1 << 3,
1631 int mode_num;
1633 g_return_val_if_fail (filename != NULL, NULL);
1634 g_return_val_if_fail (mode != NULL, NULL);
1635 g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
1637 switch (mode[0])
1639 case 'r':
1640 mode_num = MODE_R;
1641 break;
1642 case 'w':
1643 mode_num = MODE_W;
1644 break;
1645 case 'a':
1646 mode_num = MODE_A;
1647 break;
1648 default:
1649 g_warning ("Invalid GIOFileMode %s.", mode);
1650 return NULL;
1653 switch (mode[1])
1655 case '\0':
1656 break;
1657 case '+':
1658 if (mode[2] == '\0')
1660 mode_num |= MODE_PLUS;
1661 break;
1663 /* Fall through */
1664 default:
1665 g_warning ("Invalid GIOFileMode %s.", mode);
1666 return NULL;
1669 switch (mode_num)
1671 case MODE_R:
1672 flags = O_RDONLY;
1673 pmode = _S_IREAD;
1674 break;
1675 case MODE_W:
1676 flags = O_WRONLY | O_TRUNC | O_CREAT;
1677 pmode = _S_IWRITE;
1678 break;
1679 case MODE_A:
1680 flags = O_WRONLY | O_APPEND | O_CREAT;
1681 pmode = _S_IWRITE;
1682 break;
1683 case MODE_R | MODE_PLUS:
1684 flags = O_RDWR;
1685 pmode = _S_IREAD | _S_IWRITE;
1686 break;
1687 case MODE_W | MODE_PLUS:
1688 flags = O_RDWR | O_TRUNC | O_CREAT;
1689 pmode = _S_IREAD | _S_IWRITE;
1690 break;
1691 case MODE_A | MODE_PLUS:
1692 flags = O_RDWR | O_APPEND | O_CREAT;
1693 pmode = _S_IREAD | _S_IWRITE;
1694 break;
1695 default:
1696 g_assert_not_reached ();
1697 g_abort ();
1700 /* always open 'untranslated' */
1701 fid = g_open (filename, flags | _O_BINARY, pmode);
1703 if (g_io_win32_get_debug_flag ())
1705 g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename);
1706 g_win32_print_access_mode (flags|_O_BINARY);
1707 g_print (",%#o)=%d\n", pmode, fid);
1710 if (fid < 0)
1712 g_set_error_literal (error, G_FILE_ERROR,
1713 g_file_error_from_errno (errno),
1714 g_strerror (errno));
1715 return (GIOChannel *)NULL;
1718 channel = g_io_channel_win32_new_fd (fid);
1720 /* XXX: move this to g_io_channel_win32_new_fd () */
1721 channel->close_on_unref = TRUE;
1722 channel->is_seekable = TRUE;
1724 /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
1725 * correspond to actual readability/writeability. Set to FALSE those
1726 * that mode doesn't allow
1728 switch (mode_num)
1730 case MODE_R:
1731 channel->is_writeable = FALSE;
1732 break;
1733 case MODE_W:
1734 case MODE_A:
1735 channel->is_readable = FALSE;
1736 break;
1737 case MODE_R | MODE_PLUS:
1738 case MODE_W | MODE_PLUS:
1739 case MODE_A | MODE_PLUS:
1740 break;
1741 default:
1742 g_assert_not_reached ();
1743 g_abort ();
1746 return channel;
1749 static GIOStatus
1750 g_io_win32_unimpl_set_flags (GIOChannel *channel,
1751 GIOFlags flags,
1752 GError **err)
1754 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1756 if (win32_channel->debug)
1758 g_print ("g_io_win32_unimpl_set_flags: ");
1759 g_win32_print_gioflags (flags);
1760 g_print ("\n");
1763 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1764 G_IO_CHANNEL_ERROR_FAILED,
1765 "Not implemented on Win32");
1767 return G_IO_STATUS_ERROR;
1770 static GIOFlags
1771 g_io_win32_fd_get_flags_internal (GIOChannel *channel,
1772 struct _stati64 *st)
1774 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1775 gchar c;
1776 DWORD count;
1778 if (st->st_mode & _S_IFIFO)
1780 channel->is_readable =
1781 (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) != 0) || GetLastError () == ERROR_BROKEN_PIPE;
1782 channel->is_writeable =
1783 (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1784 channel->is_seekable = FALSE;
1786 else
1788 channel->is_readable =
1789 (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1790 channel->is_writeable =
1791 (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1792 channel->is_seekable = TRUE;
1795 /* XXX: G_IO_FLAG_APPEND */
1796 /* XXX: G_IO_FLAG_NONBLOCK */
1798 return 0;
1801 static GIOFlags
1802 g_io_win32_fd_get_flags (GIOChannel *channel)
1804 struct _stati64 st;
1805 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1807 g_return_val_if_fail (win32_channel != NULL, 0);
1808 g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0);
1810 if (0 == _fstati64 (win32_channel->fd, &st))
1811 return g_io_win32_fd_get_flags_internal (channel, &st);
1812 else
1813 return 0;
1816 static GIOFlags
1817 g_io_win32_console_get_flags_internal (GIOChannel *channel)
1819 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1820 HANDLE handle = (HANDLE) _get_osfhandle (win32_channel->fd);
1821 gchar c;
1822 DWORD count;
1823 INPUT_RECORD record;
1825 channel->is_readable = PeekConsoleInput (handle, &record, 1, &count);
1826 channel->is_writeable = WriteFile (handle, &c, 0, &count, NULL);
1827 channel->is_seekable = FALSE;
1829 return 0;
1832 static GIOFlags
1833 g_io_win32_console_get_flags (GIOChannel *channel)
1835 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1837 g_return_val_if_fail (win32_channel != NULL, 0);
1838 g_return_val_if_fail (win32_channel->type == G_IO_WIN32_CONSOLE, 0);
1840 return g_io_win32_console_get_flags_internal (channel);
1843 static GIOFlags
1844 g_io_win32_msg_get_flags (GIOChannel *channel)
1846 return 0;
1849 static GIOStatus
1850 g_io_win32_sock_set_flags (GIOChannel *channel,
1851 GIOFlags flags,
1852 GError **err)
1854 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1855 u_long arg;
1857 if (win32_channel->debug)
1859 g_print ("g_io_win32_sock_set_flags: ");
1860 g_win32_print_gioflags (flags);
1861 g_print ("\n");
1864 if (flags & G_IO_FLAG_NONBLOCK)
1866 arg = 1;
1867 if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
1869 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1871 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1872 G_IO_CHANNEL_ERROR_FAILED,
1873 emsg);
1874 g_free (emsg);
1876 return G_IO_STATUS_ERROR;
1879 else
1881 arg = 0;
1882 if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
1884 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1886 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1887 G_IO_CHANNEL_ERROR_FAILED,
1888 emsg);
1889 g_free (emsg);
1891 return G_IO_STATUS_ERROR;
1895 return G_IO_STATUS_NORMAL;
1898 static GIOFlags
1899 g_io_win32_sock_get_flags (GIOChannel *channel)
1901 /* Could we do something here? */
1902 return 0;
1905 static GIOFuncs win32_channel_msg_funcs = {
1906 g_io_win32_msg_read,
1907 g_io_win32_msg_write,
1908 NULL,
1909 g_io_win32_msg_close,
1910 g_io_win32_msg_create_watch,
1911 g_io_win32_free,
1912 g_io_win32_unimpl_set_flags,
1913 g_io_win32_msg_get_flags,
1916 static GIOFuncs win32_channel_fd_funcs = {
1917 g_io_win32_fd_and_console_read,
1918 g_io_win32_fd_and_console_write,
1919 g_io_win32_fd_seek,
1920 g_io_win32_fd_close,
1921 g_io_win32_fd_create_watch,
1922 g_io_win32_free,
1923 g_io_win32_unimpl_set_flags,
1924 g_io_win32_fd_get_flags,
1927 static GIOFuncs win32_channel_console_funcs = {
1928 g_io_win32_fd_and_console_read,
1929 g_io_win32_fd_and_console_write,
1930 NULL,
1931 g_io_win32_console_close,
1932 g_io_win32_console_create_watch,
1933 g_io_win32_free,
1934 g_io_win32_unimpl_set_flags,
1935 g_io_win32_console_get_flags,
1938 static GIOFuncs win32_channel_sock_funcs = {
1939 g_io_win32_sock_read,
1940 g_io_win32_sock_write,
1941 NULL,
1942 g_io_win32_sock_close,
1943 g_io_win32_sock_create_watch,
1944 g_io_win32_free,
1945 g_io_win32_sock_set_flags,
1946 g_io_win32_sock_get_flags,
1950 * g_io_channel_win32_new_messages:
1951 * @hwnd: a window handle.
1953 * Creates a new #GIOChannel given a window handle on Windows.
1955 * This function creates a #GIOChannel that can be used to poll for
1956 * Windows messages for the window in question.
1958 * Returns: a new #GIOChannel.
1960 GIOChannel *
1961 #if GLIB_SIZEOF_VOID_P == 8
1962 g_io_channel_win32_new_messages (gsize hwnd)
1963 #else
1964 g_io_channel_win32_new_messages (guint hwnd)
1965 #endif
1967 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
1968 GIOChannel *channel = (GIOChannel *)win32_channel;
1970 g_io_channel_init (channel);
1971 g_io_channel_win32_init (win32_channel);
1972 if (win32_channel->debug)
1973 g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n",
1974 channel, (HWND) hwnd);
1975 channel->funcs = &win32_channel_msg_funcs;
1976 win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
1977 win32_channel->hwnd = (HWND) hwnd;
1979 /* XXX: check this. */
1980 channel->is_readable = IsWindow (win32_channel->hwnd);
1981 channel->is_writeable = IsWindow (win32_channel->hwnd);
1983 channel->is_seekable = FALSE;
1985 return channel;
1988 static GIOChannel *
1989 g_io_channel_win32_new_fd_internal (gint fd,
1990 struct _stati64 *st)
1992 GIOWin32Channel *win32_channel;
1993 GIOChannel *channel;
1995 win32_channel = g_new (GIOWin32Channel, 1);
1996 channel = (GIOChannel *)win32_channel;
1998 g_io_channel_init (channel);
1999 g_io_channel_win32_init (win32_channel);
2001 win32_channel->fd = fd;
2003 if (win32_channel->debug)
2004 g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n",
2005 channel, fd);
2007 if (st->st_mode & _S_IFCHR) /* console */
2009 channel->funcs = &win32_channel_console_funcs;
2010 win32_channel->type = G_IO_WIN32_CONSOLE;
2011 g_io_win32_console_get_flags_internal (channel);
2013 else
2015 channel->funcs = &win32_channel_fd_funcs;
2016 win32_channel->type = G_IO_WIN32_FILE_DESC;
2017 g_io_win32_fd_get_flags_internal (channel, st);
2020 return channel;
2024 * g_io_channel_win32_new_fd:
2025 * @fd: a C library file descriptor.
2027 * Creates a new #GIOChannel given a file descriptor on Windows. This
2028 * works for file descriptors from the C runtime.
2030 * This function works for file descriptors as returned by the open(),
2031 * creat(), pipe() and fileno() calls in the Microsoft C runtime. In
2032 * order to meaningfully use this function your code should use the
2033 * same C runtime as GLib uses, which is msvcrt.dll. Note that in
2034 * current Microsoft compilers it is near impossible to convince it to
2035 * build code that would use msvcrt.dll. The last Microsoft compiler
2036 * version that supported using msvcrt.dll as the C runtime was version
2037 * 6. The GNU compiler and toolchain for Windows, also known as Mingw,
2038 * fully supports msvcrt.dll.
2040 * If you have created a #GIOChannel for a file descriptor and started
2041 * watching (polling) it, you shouldn't call read() on the file
2042 * descriptor. This is because adding polling for a file descriptor is
2043 * implemented in GLib on Windows by starting a thread that sits
2044 * blocked in a read() from the file descriptor most of the time. All
2045 * reads from the file descriptor should be done by this internal GLib
2046 * thread. Your code should call only g_io_channel_read().
2048 * This function is available only in GLib on Windows.
2050 * Returns: a new #GIOChannel.
2052 GIOChannel *
2053 g_io_channel_win32_new_fd (gint fd)
2055 struct _stati64 st;
2057 if (_fstati64 (fd, &st) == -1)
2059 g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd);
2060 return NULL;
2063 return g_io_channel_win32_new_fd_internal (fd, &st);
2066 gint
2067 g_io_channel_win32_get_fd (GIOChannel *channel)
2069 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2071 return win32_channel->fd;
2075 * g_io_channel_win32_new_socket:
2076 * @socket: a Winsock socket
2078 * Creates a new #GIOChannel given a socket on Windows.
2080 * This function works for sockets created by Winsock. It's available
2081 * only in GLib on Windows.
2083 * Polling a #GSource created to watch a channel for a socket puts the
2084 * socket in non-blocking mode. This is a side-effect of the
2085 * implementation and unavoidable.
2087 * Returns: a new #GIOChannel
2089 GIOChannel *
2090 g_io_channel_win32_new_socket (int socket)
2092 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
2093 GIOChannel *channel = (GIOChannel *)win32_channel;
2095 g_io_channel_init (channel);
2096 g_io_channel_win32_init (win32_channel);
2097 if (win32_channel->debug)
2098 g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
2099 channel, socket);
2100 channel->funcs = &win32_channel_sock_funcs;
2101 win32_channel->type = G_IO_WIN32_SOCKET;
2102 win32_channel->fd = socket;
2104 channel->is_readable = TRUE;
2105 channel->is_writeable = TRUE;
2106 channel->is_seekable = FALSE;
2108 return channel;
2111 GIOChannel *
2112 g_io_channel_unix_new (gint fd)
2114 gboolean is_fd, is_socket;
2115 struct _stati64 st;
2116 int optval, optlen;
2118 is_fd = (_fstati64 (fd, &st) == 0);
2120 optlen = sizeof (optval);
2121 is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
2123 if (is_fd && is_socket)
2124 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);
2126 if (is_fd)
2127 return g_io_channel_win32_new_fd_internal (fd, &st);
2129 if (is_socket)
2130 return g_io_channel_win32_new_socket(fd);
2132 g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd);
2134 return NULL;
2137 gint
2138 g_io_channel_unix_get_fd (GIOChannel *channel)
2140 return g_io_channel_win32_get_fd (channel);
2143 void
2144 g_io_channel_win32_set_debug (GIOChannel *channel,
2145 gboolean flag)
2147 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2149 win32_channel->debug = flag;
2152 gint
2153 g_io_channel_win32_poll (GPollFD *fds,
2154 gint n_fds,
2155 gint timeout)
2157 g_return_val_if_fail (n_fds >= 0, 0);
2159 return g_poll (fds, n_fds, timeout);
2162 void
2163 g_io_channel_win32_make_pollfd (GIOChannel *channel,
2164 GIOCondition condition,
2165 GPollFD *fd)
2167 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2169 switch (win32_channel->type)
2171 case G_IO_WIN32_FILE_DESC:
2172 if (win32_channel->data_avail_event == NULL)
2173 create_events (win32_channel);
2175 fd->fd = (gintptr) win32_channel->data_avail_event;
2177 if (win32_channel->thread_id == 0)
2179 /* Is it meaningful for a file descriptor to be polled for
2180 * both IN and OUT? For what kind of file descriptor would
2181 * that be? Doesn't seem to make sense, in practise the file
2182 * descriptors handled here are always read or write ends of
2183 * pipes surely, and thus unidirectional.
2185 if (condition & G_IO_IN)
2186 create_thread (win32_channel, condition, read_thread);
2187 else if (condition & G_IO_OUT)
2188 create_thread (win32_channel, condition, write_thread);
2190 break;
2192 case G_IO_WIN32_CONSOLE:
2193 fd->fd = _get_osfhandle (win32_channel->fd);
2194 break;
2196 case G_IO_WIN32_SOCKET:
2197 fd->fd = (gintptr) WSACreateEvent ();
2198 break;
2200 case G_IO_WIN32_WINDOWS_MESSAGES:
2201 fd->fd = G_WIN32_MSG_HANDLE;
2202 break;
2204 default:
2205 g_assert_not_reached ();
2206 g_abort ();
2209 fd->events = condition;
2212 #ifndef _WIN64
2214 /* Binary compatibility */
2215 GIOChannel *
2216 g_io_channel_win32_new_stream_socket (int socket)
2218 return g_io_channel_win32_new_socket (socket);
2221 #endif
2223 #ifdef G_OS_WIN32
2225 /* Binary compatibility versions. Not for newly compiled code. */
2227 _GLIB_EXTERN GIOChannel *g_io_channel_new_file_utf8 (const gchar *filename,
2228 const gchar *mode,
2229 GError **error);
2231 GIOChannel *
2232 g_io_channel_new_file_utf8 (const gchar *filename,
2233 const gchar *mode,
2234 GError **error)
2236 return g_io_channel_new_file (filename, mode, error);
2239 #endif