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.
86 typedef struct _GIOWin32Channel GIOWin32Channel;
87 typedef struct _GIOWin32Watch GIOWin32Watch;
89 #define BUFFER_SIZE 4096
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
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 {
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;
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;
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).
148 * Full: (wrp + 1) % BUFFER_SIZE == rdp
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 */
159 gboolean write_would_have_blocked;
160 gboolean ever_writable;
163 struct _GIOWin32Watch {
167 GIOCondition condition;
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" : ""));
189 g_win32_print_gioflags (GIOFlags flags)
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 = "|";
206 event_mask_to_string (int mask)
209 int checked_bits = 0;
215 #define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
225 BIT (ROUTING_INTERFACE_CHANGE);
226 BIT (ADDRESS_LIST_CHANGE);
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));
237 condition_to_string (GIOCondition condition)
240 int checked_bits = 0;
246 #define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
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));
264 g_io_win32_get_debug_flag (void)
266 return (getenv ("G_IO_WIN32_DEBUG") != NULL);
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;
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);
312 static unsigned __stdcall
313 read_thread (void *parameter)
315 GIOWin32Channel *channel = parameter;
319 g_io_channel_ref ((GIOChannel *)channel);
322 g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
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)
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)
345 g_print ("read_thread %#x: resetting space_avail\n",
347 ResetEvent (channel->space_avail_event);
349 g_print ("read_thread %#x: waiting for space\n",
351 LeaveCriticalSection (&channel->mutex);
352 WaitForSingleObject (channel->space_avail_event, INFINITE);
353 EnterCriticalSection (&channel->mutex);
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);
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;
379 channel->revents |= G_IO_HUP;
381 channel->revents |= G_IO_ERR;
384 g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
385 channel->thread_id, nbytes, channel->rdp, channel->wrp);
390 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
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)
401 g_print ("read_thread %#x: channel fd %d needs closing\n",
402 channel->thread_id, channel->fd);
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.
423 static unsigned __stdcall
424 write_thread (void *parameter)
426 GIOWin32Channel *channel = parameter;
430 g_io_channel_ref ((GIOChannel *)channel);
433 g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
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
452 EnterCriticalSection (&channel->mutex);
453 while (channel->running || channel->rdp != channel->wrp)
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. */
462 g_print ("write_thread %#x: resetting space_avail\n",
464 ResetEvent (channel->space_avail_event);
466 g_print ("write_thread %#x: waiting for data\n",
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)
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;
486 nbytes = BUFFER_SIZE - channel->rdp;
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);
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;
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;
512 g_print ("write_thread: setting data_avail for thread %#x\n",
514 SetEvent (channel->data_avail_event);
517 channel->running = FALSE;
518 if (channel->needs_close)
521 g_print ("write_thread %#x: channel fd %d needs closing\n",
522 channel->thread_id, channel->fd);
527 LeaveCriticalSection (&channel->mutex);
529 g_io_channel_unref ((GIOChannel *)channel);
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.",
546 else if (!CloseHandle (thread_handle))
548 gchar *emsg = g_win32_error_message (GetLastError ());
550 g_warning ("Error closing thread handle: %s.", emsg);
554 WaitForSingleObject (channel->space_avail_event, INFINITE);
558 buffer_read (GIOWin32Channel *channel,
567 EnterCriticalSection (&channel->mutex);
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);
576 g_print ("waiting for data from thread %#x\n", channel->thread_id);
577 WaitForSingleObject (channel->data_avail_event, INFINITE);
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)
584 g_print ("wrp==rdp, !running\n");
585 LeaveCriticalSection (&channel->mutex);
587 return G_IO_STATUS_EOF;
591 if (channel->rdp < channel->wrp)
592 nbytes = channel->wrp - channel->rdp;
594 nbytes = BUFFER_SIZE - channel->rdp;
595 LeaveCriticalSection (&channel->mutex);
596 nbytes = MIN (left, nbytes);
598 g_print ("moving %d bytes from thread %#x\n",
599 nbytes, channel->thread_id);
600 memcpy (dest, channel->buffer + channel->rdp, nbytes);
603 EnterCriticalSection (&channel->mutex);
604 channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
606 g_print ("setting space_avail for thread %#x\n", channel->thread_id);
607 SetEvent (channel->space_avail_event);
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)
614 g_print ("resetting data_avail of thread %#x\n",
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;
629 buffer_write (GIOWin32Channel *channel,
632 gsize *bytes_written,
638 EnterCriticalSection (&channel->mutex);
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)
647 g_print ("buffer_write: tid %#x: resetting data_avail\n",
649 ResetEvent (channel->data_avail_event);
651 g_print ("buffer_write: tid %#x: waiting for space\n",
653 LeaveCriticalSection (&channel->mutex);
654 WaitForSingleObject (channel->data_avail_event, INFINITE);
655 EnterCriticalSection (&channel->mutex);
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);
667 g_print ("buffer_write: tid %#x: writing %d bytes\n",
668 channel->thread_id, nbytes);
669 memcpy (channel->buffer + channel->wrp, dest, nbytes);
672 EnterCriticalSection (&channel->mutex);
674 channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
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)
684 g_print ("buffer_write: tid %#x: resetting data_avail\n",
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;
700 g_io_win32_prepare (GSource *source,
703 GIOWin32Watch *watch = (GIOWin32Watch *)source;
704 GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
705 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
711 g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel);
713 switch (channel->type)
715 case G_IO_WIN32_WINDOWS_MESSAGES:
720 case G_IO_WIN32_CONSOLE:
725 case G_IO_WIN32_FILE_DESC:
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)
740 g_print ("\n setting revents=0");
741 channel->revents = 0;
746 if (channel->direction == 1
747 && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
750 g_print ("\n setting revents=0");
751 channel->revents = 0;
754 LeaveCriticalSection (&channel->mutex);
757 case G_IO_WIN32_SOCKET:
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)
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)
777 gchar *emsg = g_win32_error_message (WSAGetLastError ());
779 g_print (" failed: %s", emsg);
782 channel->event_mask = event_mask;
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)
793 g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
794 WSASetEvent ((WSAEVENT) watch->pollfd.fd);
800 g_assert_not_reached ();
806 return ((watch->condition & buffer_condition) == watch->condition);
810 g_io_win32_check (GSource *source)
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;
819 g_print ("g_io_win32_check: source=%p channel=%p", source, channel);
821 switch (channel->type)
823 case G_IO_WIN32_WINDOWS_MESSAGES:
826 return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
828 case G_IO_WIN32_FILE_DESC:
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:
844 if (watch->channel->is_writeable)
846 else if (watch->channel->is_readable)
850 if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) &&
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.
860 /* Discard all other kinds of events */
861 ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n);
866 case G_IO_WIN32_SOCKET:
869 if (channel->last_events & FD_WRITE)
872 g_print (" sock=%d event=%p last_events has FD_WRITE",
873 channel->fd, (HANDLE) watch->pollfd.fd);
877 WSAEnumNetworkEvents (channel->fd, 0, &events);
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),
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;
893 g_print ("\n WSAEventSelect(%d,%p,{})",
894 channel->fd, (HANDLE) watch->pollfd.fd);
895 WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0);
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;
914 /* We have called WSAEnumNetworkEvents() above but it didn't
917 if (events.lNetworkEvents & FD_CONNECT)
919 if (events.iErrorCode[FD_CONNECT_BIT] == 0)
920 watch->pollfd.revents |= G_IO_OUT;
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;
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);
947 g_assert_not_reached ();
953 g_io_win32_dispatch (GSource *source,
954 GSourceFunc callback,
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);
964 g_warning ("IO Watch dispatched without callback\n"
965 "You must call g_source_connect().");
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,
981 g_io_win32_finalize (GSource *source)
983 GIOWin32Watch *watch = (GIOWin32Watch *)source;
984 GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
987 g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel);
989 switch (channel->type)
991 case G_IO_WIN32_WINDOWS_MESSAGES:
996 case G_IO_WIN32_CONSOLE:
1001 case G_IO_WIN32_FILE_DESC:
1003 g_print (" FD thread=%#x", channel->thread_id);
1006 case G_IO_WIN32_SOCKET:
1008 g_print (" SOCK sock=%d", channel->fd);
1012 g_assert_not_reached ();
1017 g_io_channel_unref (watch->channel);
1020 GSourceFuncs g_io_watch_funcs = {
1023 g_io_win32_dispatch,
1028 g_io_win32_msg_read (GIOChannel *channel,
1034 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1035 MSG msg; /* In case of alignment problems */
1037 if (count < sizeof (MSG))
1039 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1040 "Incorrect message size"); /* Informative enough error message? */
1041 return G_IO_STATUS_ERROR;
1044 if (win32_channel->debug)
1045 g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n",
1046 channel, win32_channel->hwnd);
1047 if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
1048 return G_IO_STATUS_AGAIN;
1050 memmove (buf, &msg, sizeof (MSG));
1051 *bytes_read = sizeof (MSG);
1053 return G_IO_STATUS_NORMAL;
1057 g_io_win32_msg_write (GIOChannel *channel,
1060 gsize *bytes_written,
1063 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1066 if (count != sizeof (MSG))
1068 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
1069 "Incorrect message size"); /* Informative enough error message? */
1070 return G_IO_STATUS_ERROR;
1073 /* In case of alignment problems */
1074 memmove (&msg, buf, sizeof (MSG));
1075 if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
1077 gchar *emsg = g_win32_error_message (GetLastError ());
1079 g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg);
1082 return G_IO_STATUS_ERROR;
1085 *bytes_written = sizeof (MSG);
1087 return G_IO_STATUS_NORMAL;
1091 g_io_win32_msg_close (GIOChannel *channel,
1094 /* Nothing to be done. Or should we set hwnd to some invalid value? */
1096 return G_IO_STATUS_NORMAL;
1100 g_io_win32_free (GIOChannel *channel)
1102 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1104 if (win32_channel->debug)
1105 g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd);
1107 DeleteCriticalSection (&win32_channel->mutex);
1109 if (win32_channel->data_avail_event)
1110 if (!CloseHandle (win32_channel->data_avail_event))
1111 if (win32_channel->debug)
1113 gchar *emsg = g_win32_error_message (GetLastError ());
1115 g_print (" CloseHandle(%p) failed: %s\n",
1116 win32_channel->data_avail_event, emsg);
1120 g_free (win32_channel->buffer);
1122 if (win32_channel->space_avail_event)
1123 if (!CloseHandle (win32_channel->space_avail_event))
1124 if (win32_channel->debug)
1126 gchar *emsg = g_win32_error_message (GetLastError ());
1128 g_print (" CloseHandle(%p) failed: %s\n",
1129 win32_channel->space_avail_event, emsg);
1133 if (win32_channel->type == G_IO_WIN32_SOCKET &&
1134 win32_channel->fd != -1)
1135 if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR)
1136 if (win32_channel->debug)
1138 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1140 g_print (" WSAEventSelect(%d,NULL,{}) failed: %s\n",
1141 win32_channel->fd, emsg);
1145 if (win32_channel->event)
1146 if (!WSACloseEvent (win32_channel->event))
1147 if (win32_channel->debug)
1149 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1151 g_print (" WSACloseEvent(%p) failed: %s\n",
1152 win32_channel->event, emsg);
1156 g_free (win32_channel);
1160 g_io_win32_msg_create_watch (GIOChannel *channel,
1161 GIOCondition condition)
1163 GIOWin32Watch *watch;
1166 source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1167 g_source_set_name (source, "GIOChannel (Win32)");
1168 watch = (GIOWin32Watch *)source;
1170 watch->channel = channel;
1171 g_io_channel_ref (channel);
1173 watch->condition = condition;
1175 watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE;
1176 watch->pollfd.events = condition;
1178 g_source_add_poll (source, &watch->pollfd);
1184 g_io_win32_fd_and_console_read (GIOChannel *channel,
1190 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1193 if (win32_channel->debug)
1194 g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
1195 win32_channel->fd, count);
1197 if (win32_channel->thread_id)
1199 return buffer_read (win32_channel, buf, count, bytes_read, err);
1202 result = read (win32_channel->fd, buf, count);
1204 if (win32_channel->debug)
1205 g_print ("g_io_win32_fd_read: read() => %d\n", result);
1215 return G_IO_STATUS_AGAIN;
1218 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1219 g_io_channel_error_from_errno (errno),
1220 g_strerror (errno));
1221 return G_IO_STATUS_ERROR;
1225 *bytes_read = result;
1227 return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
1231 g_io_win32_fd_and_console_write (GIOChannel *channel,
1234 gsize *bytes_written,
1237 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1240 if (win32_channel->thread_id)
1242 return buffer_write (win32_channel, buf, count, bytes_written, err);
1245 result = write (win32_channel->fd, buf, count);
1246 if (win32_channel->debug)
1247 g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
1248 win32_channel->fd, count, result);
1258 return G_IO_STATUS_AGAIN;
1261 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1262 g_io_channel_error_from_errno (errno),
1263 g_strerror (errno));
1264 return G_IO_STATUS_ERROR;
1268 *bytes_written = result;
1270 return G_IO_STATUS_NORMAL;
1274 g_io_win32_fd_seek (GIOChannel *channel,
1279 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1296 whence = -1; /* Keep the compiler quiet */
1297 g_assert_not_reached ();
1301 tmp_offset = offset;
1302 if (tmp_offset != offset)
1304 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1305 g_io_channel_error_from_errno (EINVAL),
1306 g_strerror (EINVAL));
1307 return G_IO_STATUS_ERROR;
1310 result = lseek (win32_channel->fd, tmp_offset, whence);
1314 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1315 g_io_channel_error_from_errno (errno),
1316 g_strerror (errno));
1317 return G_IO_STATUS_ERROR;
1320 return G_IO_STATUS_NORMAL;
1324 g_io_win32_fd_close (GIOChannel *channel,
1327 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1329 if (win32_channel->debug)
1330 g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
1331 win32_channel->thread_id,
1333 EnterCriticalSection (&win32_channel->mutex);
1334 if (win32_channel->running)
1336 if (win32_channel->debug)
1337 g_print ("thread %#x: running, marking fd %d for later close\n",
1338 win32_channel->thread_id, win32_channel->fd);
1339 win32_channel->running = FALSE;
1340 win32_channel->needs_close = TRUE;
1341 if (win32_channel->direction == 0)
1342 SetEvent (win32_channel->data_avail_event);
1344 SetEvent (win32_channel->space_avail_event);
1348 if (win32_channel->debug)
1349 g_print ("closing fd %d\n", win32_channel->fd);
1350 close (win32_channel->fd);
1351 if (win32_channel->debug)
1352 g_print ("closed fd %d, setting to -1\n",
1354 win32_channel->fd = -1;
1356 LeaveCriticalSection (&win32_channel->mutex);
1358 /* FIXME error detection? */
1360 return G_IO_STATUS_NORMAL;
1364 g_io_win32_fd_create_watch (GIOChannel *channel,
1365 GIOCondition condition)
1367 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1368 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1369 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1371 watch->channel = channel;
1372 g_io_channel_ref (channel);
1374 watch->condition = condition;
1376 if (win32_channel->data_avail_event == NULL)
1377 create_events (win32_channel);
1379 watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
1380 watch->pollfd.events = condition;
1382 if (win32_channel->debug)
1383 g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
1384 channel, win32_channel->fd,
1385 condition_to_string (condition), (HANDLE) watch->pollfd.fd);
1387 EnterCriticalSection (&win32_channel->mutex);
1388 if (win32_channel->thread_id == 0)
1390 if (condition & G_IO_IN)
1391 create_thread (win32_channel, condition, read_thread);
1392 else if (condition & G_IO_OUT)
1393 create_thread (win32_channel, condition, write_thread);
1396 g_source_add_poll (source, &watch->pollfd);
1397 LeaveCriticalSection (&win32_channel->mutex);
1403 g_io_win32_console_close (GIOChannel *channel,
1406 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1408 if (close (win32_channel->fd) < 0)
1410 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1411 g_io_channel_error_from_errno (errno),
1412 g_strerror (errno));
1413 return G_IO_STATUS_ERROR;
1416 return G_IO_STATUS_NORMAL;
1420 g_io_win32_console_create_watch (GIOChannel *channel,
1421 GIOCondition condition)
1423 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1424 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1425 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1427 watch->channel = channel;
1428 g_io_channel_ref (channel);
1430 watch->condition = condition;
1432 watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
1433 watch->pollfd.events = condition;
1435 g_source_add_poll (source, &watch->pollfd);
1441 g_io_win32_sock_read (GIOChannel *channel,
1447 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1449 GIOChannelError error;
1452 if (win32_channel->debug)
1453 g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1454 channel, win32_channel->fd, count);
1456 result = recv (win32_channel->fd, buf, count, 0);
1457 if (result == SOCKET_ERROR)
1458 winsock_error = WSAGetLastError ();
1460 if (win32_channel->debug)
1461 g_print (" recv=%d", result);
1463 if (result == SOCKET_ERROR)
1465 gchar *emsg = g_win32_error_message (winsock_error);
1467 if (win32_channel->debug)
1468 g_print (" %s\n", emsg);
1472 switch (winsock_error)
1475 error = G_IO_CHANNEL_ERROR_INVAL;
1477 case WSAEWOULDBLOCK:
1479 return G_IO_STATUS_AGAIN;
1481 error = G_IO_CHANNEL_ERROR_FAILED;
1484 g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1487 return G_IO_STATUS_ERROR;
1491 if (win32_channel->debug)
1493 *bytes_read = result;
1495 return G_IO_STATUS_EOF;
1497 return G_IO_STATUS_NORMAL;
1502 g_io_win32_sock_write (GIOChannel *channel,
1505 gsize *bytes_written,
1508 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1510 GIOChannelError error;
1513 if (win32_channel->debug)
1514 g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
1515 channel, win32_channel->fd, count);
1517 result = send (win32_channel->fd, buf, count, 0);
1518 if (result == SOCKET_ERROR)
1519 winsock_error = WSAGetLastError ();
1521 if (win32_channel->debug)
1522 g_print (" send=%d", result);
1524 if (result == SOCKET_ERROR)
1526 gchar *emsg = g_win32_error_message (winsock_error);
1528 if (win32_channel->debug)
1529 g_print (" %s\n", emsg);
1533 switch (winsock_error)
1536 error = G_IO_CHANNEL_ERROR_INVAL;
1538 case WSAEWOULDBLOCK:
1539 win32_channel->write_would_have_blocked = TRUE;
1540 win32_channel->last_events = 0;
1542 return G_IO_STATUS_AGAIN;
1544 error = G_IO_CHANNEL_ERROR_FAILED;
1547 g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
1550 return G_IO_STATUS_ERROR;
1554 if (win32_channel->debug)
1556 *bytes_written = result;
1557 win32_channel->write_would_have_blocked = FALSE;
1559 return G_IO_STATUS_NORMAL;
1564 g_io_win32_sock_close (GIOChannel *channel,
1567 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1569 if (win32_channel->fd != -1)
1571 if (win32_channel->debug)
1572 g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
1573 channel, win32_channel->fd);
1575 closesocket (win32_channel->fd);
1576 win32_channel->fd = -1;
1579 /* FIXME error detection? */
1581 return G_IO_STATUS_NORMAL;
1585 g_io_win32_sock_create_watch (GIOChannel *channel,
1586 GIOCondition condition)
1588 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1589 GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
1590 GIOWin32Watch *watch = (GIOWin32Watch *)source;
1592 watch->channel = channel;
1593 g_io_channel_ref (channel);
1595 watch->condition = condition;
1597 if (win32_channel->event == 0)
1598 win32_channel->event = WSACreateEvent ();
1600 watch->pollfd.fd = (gintptr) win32_channel->event;
1601 watch->pollfd.events = condition;
1603 if (win32_channel->debug)
1604 g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
1605 channel, win32_channel->fd, (HANDLE) watch->pollfd.fd,
1606 condition_to_string (watch->condition));
1608 g_source_add_poll (source, &watch->pollfd);
1614 g_io_channel_new_file (const gchar *filename,
1618 int fid, flags, pmode;
1619 GIOChannel *channel;
1621 enum { /* Cheesy hack */
1629 g_return_val_if_fail (filename != NULL, NULL);
1630 g_return_val_if_fail (mode != NULL, NULL);
1631 g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
1645 g_warning ("Invalid GIOFileMode %s.", mode);
1654 if (mode[2] == '\0')
1656 mode_num |= MODE_PLUS;
1661 g_warning ("Invalid GIOFileMode %s.", mode);
1672 flags = O_WRONLY | O_TRUNC | O_CREAT;
1676 flags = O_WRONLY | O_APPEND | O_CREAT;
1679 case MODE_R | MODE_PLUS:
1681 pmode = _S_IREAD | _S_IWRITE;
1683 case MODE_W | MODE_PLUS:
1684 flags = O_RDWR | O_TRUNC | O_CREAT;
1685 pmode = _S_IREAD | _S_IWRITE;
1687 case MODE_A | MODE_PLUS:
1688 flags = O_RDWR | O_APPEND | O_CREAT;
1689 pmode = _S_IREAD | _S_IWRITE;
1692 g_assert_not_reached ();
1696 /* always open 'untranslated' */
1697 fid = g_open (filename, flags | _O_BINARY, pmode);
1699 if (g_io_win32_get_debug_flag ())
1701 g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename);
1702 g_win32_print_access_mode (flags|_O_BINARY);
1703 g_print (",%#o)=%d\n", pmode, fid);
1708 g_set_error_literal (error, G_FILE_ERROR,
1709 g_file_error_from_errno (errno),
1710 g_strerror (errno));
1711 return (GIOChannel *)NULL;
1714 channel = g_io_channel_win32_new_fd (fid);
1716 /* XXX: move this to g_io_channel_win32_new_fd () */
1717 channel->close_on_unref = TRUE;
1718 channel->is_seekable = TRUE;
1720 /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
1721 * correspond to actual readability/writeability. Set to FALSE those
1722 * that mode doesn't allow
1727 channel->is_writeable = FALSE;
1731 channel->is_readable = FALSE;
1733 case MODE_R | MODE_PLUS:
1734 case MODE_W | MODE_PLUS:
1735 case MODE_A | MODE_PLUS:
1738 g_assert_not_reached ();
1745 #if !defined (_WIN64)
1747 #undef g_io_channel_new_file
1749 /* Binary compatibility version. Not for newly compiled code. */
1752 g_io_channel_new_file (const gchar *filename,
1756 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
1759 if (utf8_filename == NULL)
1762 retval = g_io_channel_new_file_utf8 (utf8_filename, mode, error);
1764 g_free (utf8_filename);
1772 g_io_win32_unimpl_set_flags (GIOChannel *channel,
1776 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1778 if (win32_channel->debug)
1780 g_print ("g_io_win32_unimpl_set_flags: ");
1781 g_win32_print_gioflags (flags);
1785 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1786 G_IO_CHANNEL_ERROR_FAILED,
1787 "Not implemented on Win32");
1789 return G_IO_STATUS_ERROR;
1793 g_io_win32_fd_get_flags_internal (GIOChannel *channel,
1794 struct _stati64 *st)
1796 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1800 if (st->st_mode & _S_IFIFO)
1802 channel->is_readable =
1803 (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) != 0) || GetLastError () == ERROR_BROKEN_PIPE;
1804 channel->is_writeable =
1805 (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1806 channel->is_seekable = FALSE;
1810 channel->is_readable =
1811 (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1812 channel->is_writeable =
1813 (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
1814 channel->is_seekable = TRUE;
1817 /* XXX: G_IO_FLAG_APPEND */
1818 /* XXX: G_IO_FLAG_NONBLOCK */
1824 g_io_win32_fd_get_flags (GIOChannel *channel)
1827 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1829 g_return_val_if_fail (win32_channel != NULL, 0);
1830 g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0);
1832 if (0 == _fstati64 (win32_channel->fd, &st))
1833 return g_io_win32_fd_get_flags_internal (channel, &st);
1839 g_io_win32_console_get_flags_internal (GIOChannel *channel)
1841 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1842 HANDLE handle = (HANDLE) _get_osfhandle (win32_channel->fd);
1845 INPUT_RECORD record;
1847 channel->is_readable = PeekConsoleInput (handle, &record, 1, &count);
1848 channel->is_writeable = WriteFile (handle, &c, 0, &count, NULL);
1849 channel->is_seekable = FALSE;
1855 g_io_win32_console_get_flags (GIOChannel *channel)
1857 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1859 g_return_val_if_fail (win32_channel != NULL, 0);
1860 g_return_val_if_fail (win32_channel->type == G_IO_WIN32_CONSOLE, 0);
1862 return g_io_win32_console_get_flags_internal (channel);
1866 g_io_win32_msg_get_flags (GIOChannel *channel)
1872 g_io_win32_sock_set_flags (GIOChannel *channel,
1876 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1879 if (win32_channel->debug)
1881 g_print ("g_io_win32_sock_set_flags: ");
1882 g_win32_print_gioflags (flags);
1886 if (flags & G_IO_FLAG_NONBLOCK)
1889 if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
1891 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1893 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1894 G_IO_CHANNEL_ERROR_FAILED,
1898 return G_IO_STATUS_ERROR;
1904 if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
1906 gchar *emsg = g_win32_error_message (WSAGetLastError ());
1908 g_set_error_literal (err, G_IO_CHANNEL_ERROR,
1909 G_IO_CHANNEL_ERROR_FAILED,
1913 return G_IO_STATUS_ERROR;
1917 return G_IO_STATUS_NORMAL;
1921 g_io_win32_sock_get_flags (GIOChannel *channel)
1923 /* Could we do something here? */
1927 static GIOFuncs win32_channel_msg_funcs = {
1928 g_io_win32_msg_read,
1929 g_io_win32_msg_write,
1931 g_io_win32_msg_close,
1932 g_io_win32_msg_create_watch,
1934 g_io_win32_unimpl_set_flags,
1935 g_io_win32_msg_get_flags,
1938 static GIOFuncs win32_channel_fd_funcs = {
1939 g_io_win32_fd_and_console_read,
1940 g_io_win32_fd_and_console_write,
1942 g_io_win32_fd_close,
1943 g_io_win32_fd_create_watch,
1945 g_io_win32_unimpl_set_flags,
1946 g_io_win32_fd_get_flags,
1949 static GIOFuncs win32_channel_console_funcs = {
1950 g_io_win32_fd_and_console_read,
1951 g_io_win32_fd_and_console_write,
1953 g_io_win32_console_close,
1954 g_io_win32_console_create_watch,
1956 g_io_win32_unimpl_set_flags,
1957 g_io_win32_console_get_flags,
1960 static GIOFuncs win32_channel_sock_funcs = {
1961 g_io_win32_sock_read,
1962 g_io_win32_sock_write,
1964 g_io_win32_sock_close,
1965 g_io_win32_sock_create_watch,
1967 g_io_win32_sock_set_flags,
1968 g_io_win32_sock_get_flags,
1972 * g_io_channel_win32_new_messages:
1973 * @hwnd: a window handle.
1975 * Creates a new #GIOChannel given a window handle on Windows.
1977 * This function creates a #GIOChannel that can be used to poll for
1978 * Windows messages for the window in question.
1980 * Returns: a new #GIOChannel.
1983 #if GLIB_SIZEOF_VOID_P == 8
1984 g_io_channel_win32_new_messages (gsize hwnd)
1986 g_io_channel_win32_new_messages (guint hwnd)
1989 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
1990 GIOChannel *channel = (GIOChannel *)win32_channel;
1992 g_io_channel_init (channel);
1993 g_io_channel_win32_init (win32_channel);
1994 if (win32_channel->debug)
1995 g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n",
1996 channel, (HWND) hwnd);
1997 channel->funcs = &win32_channel_msg_funcs;
1998 win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
1999 win32_channel->hwnd = (HWND) hwnd;
2001 /* XXX: check this. */
2002 channel->is_readable = IsWindow (win32_channel->hwnd);
2003 channel->is_writeable = IsWindow (win32_channel->hwnd);
2005 channel->is_seekable = FALSE;
2011 g_io_channel_win32_new_fd_internal (gint fd,
2012 struct _stati64 *st)
2014 GIOWin32Channel *win32_channel;
2015 GIOChannel *channel;
2017 win32_channel = g_new (GIOWin32Channel, 1);
2018 channel = (GIOChannel *)win32_channel;
2020 g_io_channel_init (channel);
2021 g_io_channel_win32_init (win32_channel);
2023 win32_channel->fd = fd;
2025 if (win32_channel->debug)
2026 g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n",
2029 if (st->st_mode & _S_IFCHR) /* console */
2031 channel->funcs = &win32_channel_console_funcs;
2032 win32_channel->type = G_IO_WIN32_CONSOLE;
2033 g_io_win32_console_get_flags_internal (channel);
2037 channel->funcs = &win32_channel_fd_funcs;
2038 win32_channel->type = G_IO_WIN32_FILE_DESC;
2039 g_io_win32_fd_get_flags_internal (channel, st);
2046 * g_io_channel_win32_new_fd:
2047 * @fd: a C library file descriptor.
2049 * Creates a new #GIOChannel given a file descriptor on Windows. This
2050 * works for file descriptors from the C runtime.
2052 * This function works for file descriptors as returned by the open(),
2053 * creat(), pipe() and fileno() calls in the Microsoft C runtime. In
2054 * order to meaningfully use this function your code should use the
2055 * same C runtime as GLib uses, which is msvcrt.dll. Note that in
2056 * current Microsoft compilers it is near impossible to convince it to
2057 * build code that would use msvcrt.dll. The last Microsoft compiler
2058 * version that supported using msvcrt.dll as the C runtime was version
2059 * 6. The GNU compiler and toolchain for Windows, also known as Mingw,
2060 * fully supports msvcrt.dll.
2062 * If you have created a #GIOChannel for a file descriptor and started
2063 * watching (polling) it, you shouldn't call read() on the file
2064 * descriptor. This is because adding polling for a file descriptor is
2065 * implemented in GLib on Windows by starting a thread that sits
2066 * blocked in a read() from the file descriptor most of the time. All
2067 * reads from the file descriptor should be done by this internal GLib
2068 * thread. Your code should call only g_io_channel_read().
2070 * This function is available only in GLib on Windows.
2072 * Returns: a new #GIOChannel.
2075 g_io_channel_win32_new_fd (gint fd)
2079 if (_fstati64 (fd, &st) == -1)
2081 g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd);
2085 return g_io_channel_win32_new_fd_internal (fd, &st);
2089 g_io_channel_win32_get_fd (GIOChannel *channel)
2091 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2093 return win32_channel->fd;
2097 * g_io_channel_win32_new_socket:
2098 * @socket: a Winsock socket
2100 * Creates a new #GIOChannel given a socket on Windows.
2102 * This function works for sockets created by Winsock. It's available
2103 * only in GLib on Windows.
2105 * Polling a #GSource created to watch a channel for a socket puts the
2106 * socket in non-blocking mode. This is a side-effect of the
2107 * implementation and unavoidable.
2109 * Returns: a new #GIOChannel
2112 g_io_channel_win32_new_socket (int socket)
2114 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
2115 GIOChannel *channel = (GIOChannel *)win32_channel;
2117 g_io_channel_init (channel);
2118 g_io_channel_win32_init (win32_channel);
2119 if (win32_channel->debug)
2120 g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
2122 channel->funcs = &win32_channel_sock_funcs;
2123 win32_channel->type = G_IO_WIN32_SOCKET;
2124 win32_channel->fd = socket;
2126 channel->is_readable = TRUE;
2127 channel->is_writeable = TRUE;
2128 channel->is_seekable = FALSE;
2134 g_io_channel_unix_new (gint fd)
2136 gboolean is_fd, is_socket;
2140 is_fd = (_fstati64 (fd, &st) == 0);
2142 optlen = sizeof (optval);
2143 is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
2145 if (is_fd && is_socket)
2146 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);
2149 return g_io_channel_win32_new_fd_internal (fd, &st);
2152 return g_io_channel_win32_new_socket(fd);
2154 g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd);
2160 g_io_channel_unix_get_fd (GIOChannel *channel)
2162 return g_io_channel_win32_get_fd (channel);
2166 g_io_channel_win32_set_debug (GIOChannel *channel,
2169 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2171 win32_channel->debug = flag;
2175 g_io_channel_win32_poll (GPollFD *fds,
2179 g_return_val_if_fail (n_fds >= 0, 0);
2181 return g_poll (fds, n_fds, timeout);
2185 g_io_channel_win32_make_pollfd (GIOChannel *channel,
2186 GIOCondition condition,
2189 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
2191 switch (win32_channel->type)
2193 case G_IO_WIN32_FILE_DESC:
2194 if (win32_channel->data_avail_event == NULL)
2195 create_events (win32_channel);
2197 fd->fd = (gintptr) win32_channel->data_avail_event;
2199 if (win32_channel->thread_id == 0)
2201 /* Is it meaningful for a file descriptor to be polled for
2202 * both IN and OUT? For what kind of file descriptor would
2203 * that be? Doesn't seem to make sense, in practise the file
2204 * descriptors handled here are always read or write ends of
2205 * pipes surely, and thus unidirectional.
2207 if (condition & G_IO_IN)
2208 create_thread (win32_channel, condition, read_thread);
2209 else if (condition & G_IO_OUT)
2210 create_thread (win32_channel, condition, write_thread);
2214 case G_IO_WIN32_CONSOLE:
2215 fd->fd = _get_osfhandle (win32_channel->fd);
2218 case G_IO_WIN32_SOCKET:
2219 fd->fd = (gintptr) WSACreateEvent ();
2222 case G_IO_WIN32_WINDOWS_MESSAGES:
2223 fd->fd = G_WIN32_MSG_HANDLE;
2227 g_assert_not_reached ();
2231 fd->events = condition;
2236 /* Binary compatibility */
2238 g_io_channel_win32_new_stream_socket (int socket)
2240 return g_io_channel_win32_new_socket (socket);