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, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
27 * file for a list of people on the GLib Team. See the ChangeLog
28 * files for a list of changes. These files are distributed with
29 * GLib at ftp://ftp.gtk.org/pub/gtk/.
33 * Bugs that are related to the code in this file:
35 * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition
36 * http://bugzilla.gnome.org/show_bug.cgi?id=137968
38 * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely
39 * http://bugzilla.gnome.org/show_bug.cgi?id=324234
41 * Bug 331214 - g_io_channel async socket io stalls
42 * http://bugzilla.gnome.org/show_bug.cgi?id=331214
44 * Bug 338943 - Multiple watches on the same socket
45 * http://bugzilla.gnome.org/show_bug.cgi?id=338943
47 * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless
48 * http://bugzilla.gnome.org/show_bug.cgi?id=357674
50 * Bug 425156 - GIOChannel deadlocks on a win32 socket
51 * http://bugzilla.gnome.org/show_bug.cgi?id=425156
53 * Bug 468910 - giofunc condition=0
54 * http://bugzilla.gnome.org/show_bug.cgi?id=468910
56 * Bug 500246 - Bug fixes for giowin32
57 * http://bugzilla.gnome.org/show_bug.cgi?id=500246
59 * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows
60 * http://bugzilla.gnome.org/show_bug.cgi?id=548278
62 * Bug 548536 - giowin32 problem when adding and removing watches
63 * http://bugzilla.gnome.org/show_bug.cgi?id=548536
65 * When fixing bugs related to the code in this file, either the above
66 * bugs or others, make sure that the test programs attached to the
67 * above bugs continue to work.
88 typedef struct _GIOWin32Channel GIOWin32Channel
;
89 typedef struct _GIOWin32Watch GIOWin32Watch
;
91 #define BUFFER_SIZE 4096
94 G_IO_WIN32_WINDOWS_MESSAGES
, /* Windows messages */
96 G_IO_WIN32_FILE_DESC
, /* Unix-like file descriptors from
97 * _open() or _pipe(), except for
98 * console IO. Separate thread to read
102 G_IO_WIN32_CONSOLE
, /* Console IO (usually stdin, stdout, stderr) */
104 G_IO_WIN32_SOCKET
/* Sockets. No separate thread. */
105 } GIOWin32ChannelType
;
107 struct _GIOWin32Channel
{
109 gint fd
; /* Either a Unix-like file handle as provided
110 * by the Microsoft C runtime, or a SOCKET
111 * as provided by WinSock.
113 GIOWin32ChannelType type
;
117 /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */
118 HWND hwnd
; /* Handle of window, or NULL */
120 /* Fields used by G_IO_WIN32_FILE_DESC channels. */
121 CRITICAL_SECTION mutex
;
123 int direction
; /* 0 means we read from it,
124 * 1 means we write to it.
127 gboolean running
; /* Is reader or writer thread
128 * running. FALSE if EOF has been
129 * reached by the reader thread.
132 gboolean needs_close
; /* If the channel has been closed while
133 * the reader thread was still running.
136 guint thread_id
; /* If non-NULL the channel has or has
137 * had a reader or writer thread.
139 HANDLE data_avail_event
;
143 /* Data is kept in a circular buffer. To be able to distinguish between
144 * empty and full buffers, we cannot fill it completely, but have to
145 * leave a one character gap.
147 * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
150 * Full: (wrp + 1) % BUFFER_SIZE == rdp
153 guchar
*buffer
; /* (Circular) buffer */
154 gint wrp
, rdp
; /* Buffer indices for writing and reading */
155 HANDLE space_avail_event
;
157 /* Fields used by G_IO_WIN32_SOCKET channels */
161 gboolean write_would_have_blocked
;
162 gboolean ever_writable
;
165 struct _GIOWin32Watch
{
169 GIOCondition condition
;
173 g_win32_print_access_mode (int flags
)
175 g_print ("%s%s%s%s%s%s%s%s%s%s",
176 ((flags
& 0x3) == _O_RDWR
? "O_RDWR" :
177 ((flags
& 0x3) == _O_RDONLY
? "O_RDONLY" :
178 ((flags
& 0x3) == _O_WRONLY
? "O_WRONLY" : "0"))),
179 (flags
& _O_APPEND
? "|O_APPEND" : ""),
180 (flags
& _O_RANDOM
? "|O_RANDOM" : ""),
181 (flags
& _O_SEQUENTIAL
? "|O_SEQUENTIAL" : ""),
182 (flags
& _O_TEMPORARY
? "|O_TEMPORARY" : ""),
183 (flags
& _O_CREAT
? "|O_CREAT" : ""),
184 (flags
& _O_TRUNC
? "|O_TRUNC" : ""),
185 (flags
& _O_EXCL
? "|O_EXCL" : ""),
186 (flags
& _O_TEXT
? "|O_TEXT" : ""),
187 (flags
& _O_BINARY
? "|O_BINARY" : ""));
191 g_win32_print_gioflags (GIOFlags flags
)
195 if (flags
& G_IO_FLAG_APPEND
)
196 bar
= "|", g_print ("APPEND");
197 if (flags
& G_IO_FLAG_NONBLOCK
)
198 g_print ("%sNONBLOCK", bar
), bar
= "|";
199 if (flags
& G_IO_FLAG_IS_READABLE
)
200 g_print ("%sREADABLE", bar
), bar
= "|";
201 if (flags
& G_IO_FLAG_IS_WRITABLE
)
202 g_print ("%sWRITABLE", bar
), bar
= "|";
203 if (flags
& G_IO_FLAG_IS_SEEKABLE
)
204 g_print ("%sSEEKABLE", bar
), bar
= "|";
208 event_mask_to_string (int mask
)
211 int checked_bits
= 0;
217 #define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
227 BIT (ROUTING_INTERFACE_CHANGE
);
228 BIT (ADDRESS_LIST_CHANGE
);
232 if ((mask
& ~checked_bits
) != 0)
233 bufp
+= sprintf (bufp
, "|%#x", mask
& ~checked_bits
);
235 return g_quark_to_string (g_quark_from_string (buf
));
239 condition_to_string (GIOCondition condition
)
242 int checked_bits
= 0;
248 #define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
259 if ((condition
& ~checked_bits
) != 0)
260 bufp
+= sprintf (bufp
, "|%#x", condition
& ~checked_bits
);
262 return g_quark_to_string (g_quark_from_string (buf
));
266 g_io_win32_get_debug_flag (void)
268 return (getenv ("G_IO_WIN32_DEBUG") != NULL
);
272 g_io_channel_win32_init (GIOWin32Channel
*channel
)
274 channel
->debug
= g_io_win32_get_debug_flag ();
276 InitializeCriticalSection (&channel
->mutex
);
277 channel
->running
= FALSE
;
278 channel
->needs_close
= FALSE
;
279 channel
->thread_id
= 0;
280 channel
->data_avail_event
= NULL
;
281 channel
->revents
= 0;
282 channel
->buffer
= NULL
;
283 channel
->space_avail_event
= NULL
;
285 channel
->event_mask
= 0;
286 channel
->last_events
= 0;
287 channel
->event
= NULL
;
288 channel
->write_would_have_blocked
= FALSE
;
289 channel
->ever_writable
= FALSE
;
293 create_events (GIOWin32Channel
*channel
)
295 SECURITY_ATTRIBUTES sec_attrs
;
297 sec_attrs
.nLength
= sizeof (SECURITY_ATTRIBUTES
);
298 sec_attrs
.lpSecurityDescriptor
= NULL
;
299 sec_attrs
.bInheritHandle
= FALSE
;
301 /* The data available event is manual reset, the space available event
302 * is automatic reset.
304 if (!(channel
->data_avail_event
= CreateEvent (&sec_attrs
, TRUE
, FALSE
, NULL
))
305 || !(channel
->space_avail_event
= CreateEvent (&sec_attrs
, FALSE
, FALSE
, NULL
)))
307 gchar
*emsg
= g_win32_error_message (GetLastError ());
309 g_error ("Error creating event: %s", emsg
);
314 static unsigned __stdcall
315 read_thread (void *parameter
)
317 GIOWin32Channel
*channel
= parameter
;
321 g_io_channel_ref ((GIOChannel
*)channel
);
324 g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
327 channel
->data_avail_event
,
328 channel
->space_avail_event
);
330 channel
->direction
= 0;
331 channel
->buffer
= g_malloc (BUFFER_SIZE
);
332 channel
->rdp
= channel
->wrp
= 0;
333 channel
->running
= TRUE
;
335 SetEvent (channel
->space_avail_event
);
337 EnterCriticalSection (&channel
->mutex
);
338 while (channel
->running
)
341 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
342 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
343 if ((channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
347 g_print ("read_thread %#x: resetting space_avail\n",
349 ResetEvent (channel
->space_avail_event
);
351 g_print ("read_thread %#x: waiting for space\n",
353 LeaveCriticalSection (&channel
->mutex
);
354 WaitForSingleObject (channel
->space_avail_event
, INFINITE
);
355 EnterCriticalSection (&channel
->mutex
);
357 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
358 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
361 buffer
= channel
->buffer
+ channel
->wrp
;
363 /* Always leave at least one byte unused gap to be able to
364 * distinguish between the full and empty condition...
366 nbytes
= MIN ((channel
->rdp
+ BUFFER_SIZE
- channel
->wrp
- 1) % BUFFER_SIZE
,
367 BUFFER_SIZE
- channel
->wrp
);
370 g_print ("read_thread %#x: calling read() for %d bytes\n",
371 channel
->thread_id
, nbytes
);
373 LeaveCriticalSection (&channel
->mutex
);
375 nbytes
= read (channel
->fd
, buffer
, nbytes
);
377 EnterCriticalSection (&channel
->mutex
);
379 channel
->revents
= G_IO_IN
;
381 channel
->revents
|= G_IO_HUP
;
383 channel
->revents
|= G_IO_ERR
;
386 g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
387 channel
->thread_id
, nbytes
, channel
->rdp
, channel
->wrp
);
392 channel
->wrp
= (channel
->wrp
+ nbytes
) % BUFFER_SIZE
;
394 g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
395 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
396 SetEvent (channel
->data_avail_event
);
399 channel
->running
= FALSE
;
400 if (channel
->needs_close
)
403 g_print ("read_thread %#x: channel fd %d needs closing\n",
404 channel
->thread_id
, channel
->fd
);
410 g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
411 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
412 SetEvent (channel
->data_avail_event
);
413 LeaveCriticalSection (&channel
->mutex
);
415 g_io_channel_unref ((GIOChannel
*)channel
);
417 /* No need to call _endthreadex(), the actual thread starter routine
418 * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
419 * _endthreadex() for us.
425 static unsigned __stdcall
426 write_thread (void *parameter
)
428 GIOWin32Channel
*channel
= parameter
;
432 g_io_channel_ref ((GIOChannel
*)channel
);
435 g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
438 channel
->data_avail_event
,
439 channel
->space_avail_event
);
441 channel
->direction
= 1;
442 channel
->buffer
= g_malloc (BUFFER_SIZE
);
443 channel
->rdp
= channel
->wrp
= 0;
444 channel
->running
= TRUE
;
446 SetEvent (channel
->space_avail_event
);
448 /* We use the same event objects as for a reader thread, but with
449 * reversed meaning. So, space_avail is used if data is available
450 * for writing, and data_avail is used if space is available in the
454 EnterCriticalSection (&channel
->mutex
);
455 while (channel
->running
|| channel
->rdp
!= channel
->wrp
)
458 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
459 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
460 if (channel
->wrp
== channel
->rdp
)
462 /* Buffer is empty. */
464 g_print ("write_thread %#x: resetting space_avail\n",
466 ResetEvent (channel
->space_avail_event
);
468 g_print ("write_thread %#x: waiting for data\n",
470 channel
->revents
= G_IO_OUT
;
471 SetEvent (channel
->data_avail_event
);
472 LeaveCriticalSection (&channel
->mutex
);
473 WaitForSingleObject (channel
->space_avail_event
, INFINITE
);
475 EnterCriticalSection (&channel
->mutex
);
476 if (channel
->rdp
== channel
->wrp
)
480 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
481 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
484 buffer
= channel
->buffer
+ channel
->rdp
;
485 if (channel
->rdp
< channel
->wrp
)
486 nbytes
= channel
->wrp
- channel
->rdp
;
488 nbytes
= BUFFER_SIZE
- channel
->rdp
;
491 g_print ("write_thread %#x: calling write() for %d bytes\n",
492 channel
->thread_id
, nbytes
);
494 LeaveCriticalSection (&channel
->mutex
);
495 nbytes
= write (channel
->fd
, buffer
, nbytes
);
496 EnterCriticalSection (&channel
->mutex
);
499 g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
500 channel
->thread_id
, channel
->fd
, nbytes
, channel
->rdp
, channel
->wrp
);
502 channel
->revents
= 0;
504 channel
->revents
|= G_IO_OUT
;
505 else if (nbytes
<= 0)
506 channel
->revents
|= G_IO_ERR
;
508 channel
->rdp
= (channel
->rdp
+ nbytes
) % BUFFER_SIZE
;
514 g_print ("write_thread: setting data_avail for thread %#x\n",
516 SetEvent (channel
->data_avail_event
);
519 channel
->running
= FALSE
;
520 if (channel
->needs_close
)
523 g_print ("write_thread %#x: channel fd %d needs closing\n",
524 channel
->thread_id
, channel
->fd
);
529 LeaveCriticalSection (&channel
->mutex
);
531 g_io_channel_unref ((GIOChannel
*)channel
);
537 create_thread (GIOWin32Channel
*channel
,
538 GIOCondition condition
,
539 unsigned (__stdcall
*thread
) (void *parameter
))
541 HANDLE thread_handle
;
543 thread_handle
= (HANDLE
) _beginthreadex (NULL
, 0, thread
, channel
, 0,
544 &channel
->thread_id
);
545 if (thread_handle
== 0)
546 g_warning ("Error creating thread: %s.",
548 else if (!CloseHandle (thread_handle
))
550 gchar
*emsg
= g_win32_error_message (GetLastError ());
552 g_warning ("Error closing thread handle: %s.", emsg
);
556 WaitForSingleObject (channel
->space_avail_event
, INFINITE
);
560 buffer_read (GIOWin32Channel
*channel
,
569 EnterCriticalSection (&channel
->mutex
);
571 g_print ("reading from thread %#x %" G_GSIZE_FORMAT
" bytes, rdp=%d, wrp=%d\n",
572 channel
->thread_id
, count
, channel
->rdp
, channel
->wrp
);
574 if (channel
->wrp
== channel
->rdp
)
576 LeaveCriticalSection (&channel
->mutex
);
578 g_print ("waiting for data from thread %#x\n", channel
->thread_id
);
579 WaitForSingleObject (channel
->data_avail_event
, INFINITE
);
581 g_print ("done waiting for data from thread %#x\n", channel
->thread_id
);
582 EnterCriticalSection (&channel
->mutex
);
583 if (channel
->wrp
== channel
->rdp
&& !channel
->running
)
586 g_print ("wrp==rdp, !running\n");
587 LeaveCriticalSection (&channel
->mutex
);
589 return G_IO_STATUS_EOF
;
593 if (channel
->rdp
< channel
->wrp
)
594 nbytes
= channel
->wrp
- channel
->rdp
;
596 nbytes
= BUFFER_SIZE
- channel
->rdp
;
597 LeaveCriticalSection (&channel
->mutex
);
598 nbytes
= MIN (left
, nbytes
);
600 g_print ("moving %d bytes from thread %#x\n",
601 nbytes
, channel
->thread_id
);
602 memcpy (dest
, channel
->buffer
+ channel
->rdp
, nbytes
);
605 EnterCriticalSection (&channel
->mutex
);
606 channel
->rdp
= (channel
->rdp
+ nbytes
) % BUFFER_SIZE
;
608 g_print ("setting space_avail for thread %#x\n", channel
->thread_id
);
609 SetEvent (channel
->space_avail_event
);
611 g_print ("for thread %#x: rdp=%d, wrp=%d\n",
612 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
613 if (channel
->running
&& channel
->wrp
== channel
->rdp
)
616 g_print ("resetting data_avail of thread %#x\n",
618 ResetEvent (channel
->data_avail_event
);
620 LeaveCriticalSection (&channel
->mutex
);
622 /* We have no way to indicate any errors form the actual
623 * read() or recv() call in the reader thread. Should we have?
625 *bytes_read
= count
- left
;
626 return (*bytes_read
> 0) ? G_IO_STATUS_NORMAL
: G_IO_STATUS_EOF
;
631 buffer_write (GIOWin32Channel
*channel
,
634 gsize
*bytes_written
,
640 EnterCriticalSection (&channel
->mutex
);
642 g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT
" bytes, rdp=%d, wrp=%d\n",
643 channel
->thread_id
, count
, channel
->rdp
, channel
->wrp
);
645 if ((channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
649 g_print ("buffer_write: tid %#x: resetting data_avail\n",
651 ResetEvent (channel
->data_avail_event
);
653 g_print ("buffer_write: tid %#x: waiting for space\n",
655 LeaveCriticalSection (&channel
->mutex
);
656 WaitForSingleObject (channel
->data_avail_event
, INFINITE
);
657 EnterCriticalSection (&channel
->mutex
);
659 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
660 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
663 nbytes
= MIN ((channel
->rdp
+ BUFFER_SIZE
- channel
->wrp
- 1) % BUFFER_SIZE
,
664 BUFFER_SIZE
- channel
->wrp
);
666 LeaveCriticalSection (&channel
->mutex
);
667 nbytes
= MIN (left
, nbytes
);
669 g_print ("buffer_write: tid %#x: writing %d bytes\n",
670 channel
->thread_id
, nbytes
);
671 memcpy (channel
->buffer
+ channel
->wrp
, dest
, nbytes
);
674 EnterCriticalSection (&channel
->mutex
);
676 channel
->wrp
= (channel
->wrp
+ nbytes
) % BUFFER_SIZE
;
678 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
679 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
680 SetEvent (channel
->space_avail_event
);
682 if ((channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
686 g_print ("buffer_write: tid %#x: resetting data_avail\n",
688 ResetEvent (channel
->data_avail_event
);
691 LeaveCriticalSection (&channel
->mutex
);
693 /* We have no way to indicate any errors form the actual
694 * write() call in the writer thread. Should we have?
696 *bytes_written
= count
- left
;
697 return (*bytes_written
> 0) ? G_IO_STATUS_NORMAL
: G_IO_STATUS_EOF
;
702 g_io_win32_prepare (GSource
*source
,
705 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
706 GIOCondition buffer_condition
= g_io_channel_get_buffer_condition (watch
->channel
);
707 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
713 g_print ("g_io_win32_prepare: source=%p channel=%p", source
, channel
);
715 switch (channel
->type
)
717 case G_IO_WIN32_WINDOWS_MESSAGES
:
722 case G_IO_WIN32_CONSOLE
:
727 case G_IO_WIN32_FILE_DESC
:
729 g_print (" FD thread=%#x buffer_condition:{%s}"
730 "\n watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}",
731 channel
->thread_id
, condition_to_string (buffer_condition
),
732 condition_to_string (watch
->pollfd
.events
),
733 condition_to_string (watch
->pollfd
.revents
),
734 condition_to_string (channel
->revents
));
736 EnterCriticalSection (&channel
->mutex
);
737 if (channel
->running
)
739 if (channel
->direction
== 0 && channel
->wrp
== channel
->rdp
)
742 g_print ("\n setting revents=0");
743 channel
->revents
= 0;
748 if (channel
->direction
== 1
749 && (channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
752 g_print ("\n setting revents=0");
753 channel
->revents
= 0;
756 LeaveCriticalSection (&channel
->mutex
);
759 case G_IO_WIN32_SOCKET
:
763 if (watch
->condition
& G_IO_IN
)
764 event_mask
|= (FD_READ
| FD_ACCEPT
);
765 if (watch
->condition
& G_IO_OUT
)
766 event_mask
|= (FD_WRITE
| FD_CONNECT
);
767 event_mask
|= FD_CLOSE
;
769 if (channel
->event_mask
!= event_mask
)
772 g_print ("\n WSAEventSelect(%d,%p,{%s})",
773 channel
->fd
, (HANDLE
) watch
->pollfd
.fd
,
774 event_mask_to_string (event_mask
));
775 if (WSAEventSelect (channel
->fd
, (HANDLE
) watch
->pollfd
.fd
,
776 event_mask
) == SOCKET_ERROR
)
779 gchar
*emsg
= g_win32_error_message (WSAGetLastError ());
781 g_print (" failed: %s", emsg
);
784 channel
->event_mask
= event_mask
;
787 g_print ("\n setting last_events=0");
788 channel
->last_events
= 0;
790 if ((event_mask
& FD_WRITE
) &&
791 channel
->ever_writable
&&
792 !channel
->write_would_have_blocked
)
795 g_print (" WSASetEvent(%p)", (WSAEVENT
) watch
->pollfd
.fd
);
796 WSASetEvent ((WSAEVENT
) watch
->pollfd
.fd
);
802 g_assert_not_reached ();
808 return ((watch
->condition
& buffer_condition
) == watch
->condition
);
812 g_io_win32_check (GSource
*source
)
815 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
816 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
817 GIOCondition buffer_condition
= g_io_channel_get_buffer_condition (watch
->channel
);
818 WSANETWORKEVENTS events
;
821 g_print ("g_io_win32_check: source=%p channel=%p", source
, channel
);
823 switch (channel
->type
)
825 case G_IO_WIN32_WINDOWS_MESSAGES
:
828 return (PeekMessage (&msg
, channel
->hwnd
, 0, 0, PM_NOREMOVE
));
830 case G_IO_WIN32_FILE_DESC
:
832 g_print (" FD thread=%#x buffer_condition=%s\n"
833 " watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
834 channel
->thread_id
, condition_to_string (buffer_condition
),
835 condition_to_string (watch
->pollfd
.events
),
836 condition_to_string (watch
->pollfd
.revents
),
837 condition_to_string (channel
->revents
));
839 watch
->pollfd
.revents
= (watch
->pollfd
.events
& channel
->revents
);
841 return ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
);
843 case G_IO_WIN32_CONSOLE
:
846 if (watch
->channel
->is_writeable
)
848 else if (watch
->channel
->is_readable
)
852 if (PeekConsoleInput ((HANDLE
) watch
->pollfd
.fd
, &buffer
, 1, &n
) &&
855 /* _kbhit() does quite complex processing to find out
856 * whether at least one of the key events pending corresponds
857 * to a "real" character that can be read.
862 /* Discard all other kinds of events */
863 ReadConsoleInput ((HANDLE
) watch
->pollfd
.fd
, &buffer
, 1, &n
);
868 case G_IO_WIN32_SOCKET
:
871 if (channel
->last_events
& FD_WRITE
)
874 g_print (" sock=%d event=%p last_events has FD_WRITE",
875 channel
->fd
, (HANDLE
) watch
->pollfd
.fd
);
879 WSAEnumNetworkEvents (channel
->fd
, 0, &events
);
882 g_print ("\n revents={%s} condition={%s}"
883 "\n WSAEnumNetworkEvents(%d,0) sets events={%s}",
884 condition_to_string (watch
->pollfd
.revents
),
885 condition_to_string (watch
->condition
),
887 event_mask_to_string (events
.lNetworkEvents
));
889 if (watch
->pollfd
.revents
!= 0 &&
890 events
.lNetworkEvents
== 0 &&
891 !(channel
->event_mask
& FD_WRITE
))
893 channel
->event_mask
= 0;
895 g_print ("\n WSAEventSelect(%d,%p,{})",
896 channel
->fd
, (HANDLE
) watch
->pollfd
.fd
);
897 WSAEventSelect (channel
->fd
, (HANDLE
) watch
->pollfd
.fd
, 0);
899 g_print (" ResetEvent(%p)",
900 (HANDLE
) watch
->pollfd
.fd
);
901 ResetEvent ((HANDLE
) watch
->pollfd
.fd
);
903 else if (events
.lNetworkEvents
& FD_WRITE
)
904 channel
->ever_writable
= TRUE
;
905 channel
->last_events
= events
.lNetworkEvents
;
908 watch
->pollfd
.revents
= 0;
909 if (channel
->last_events
& (FD_READ
| FD_ACCEPT
))
910 watch
->pollfd
.revents
|= G_IO_IN
;
912 if (channel
->last_events
& FD_WRITE
)
913 watch
->pollfd
.revents
|= G_IO_OUT
;
916 /* We have called WSAEnumNetworkEvents() above but it didn't
919 if (events
.lNetworkEvents
& FD_CONNECT
)
921 if (events
.iErrorCode
[FD_CONNECT_BIT
] == 0)
922 watch
->pollfd
.revents
|= G_IO_OUT
;
924 watch
->pollfd
.revents
|= (G_IO_HUP
| G_IO_ERR
);
926 if (watch
->pollfd
.revents
== 0 && (channel
->last_events
& (FD_CLOSE
)))
927 watch
->pollfd
.revents
|= G_IO_HUP
;
930 /* Regardless of WSAEnumNetworkEvents() result, if watching for
931 * writability, and if we have ever got a FD_WRITE event, and
932 * unless last write would have blocked, set G_IO_OUT. But never
933 * set both G_IO_OUT and G_IO_HUP.
935 if (!(watch
->pollfd
.revents
& G_IO_HUP
) &&
936 channel
->ever_writable
&&
937 !channel
->write_would_have_blocked
&&
938 (channel
->event_mask
& FD_WRITE
))
939 watch
->pollfd
.revents
|= G_IO_OUT
;
942 g_print ("\n revents={%s} retval={%s}\n",
943 condition_to_string (watch
->pollfd
.revents
),
944 condition_to_string ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
));
946 return ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
);
949 g_assert_not_reached ();
955 g_io_win32_dispatch (GSource
*source
,
956 GSourceFunc callback
,
959 GIOFunc func
= (GIOFunc
)callback
;
960 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
961 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
962 GIOCondition buffer_condition
= g_io_channel_get_buffer_condition (watch
->channel
);
966 g_warning ("IO Watch dispatched without callback\n"
967 "You must call g_source_connect().");
972 g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
973 condition_to_string (watch
->pollfd
.revents
),
974 condition_to_string (watch
->condition
),
975 condition_to_string ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
));
977 return (*func
) (watch
->channel
,
978 (watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
,
983 g_io_win32_finalize (GSource
*source
)
985 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
986 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
989 g_print ("g_io_win32_finalize: source=%p channel=%p", source
, channel
);
991 switch (channel
->type
)
993 case G_IO_WIN32_WINDOWS_MESSAGES
:
998 case G_IO_WIN32_CONSOLE
:
1003 case G_IO_WIN32_FILE_DESC
:
1005 g_print (" FD thread=%#x", channel
->thread_id
);
1008 case G_IO_WIN32_SOCKET
:
1010 g_print (" SOCK sock=%d", channel
->fd
);
1014 g_assert_not_reached ();
1019 g_io_channel_unref (watch
->channel
);
1022 GSourceFuncs g_io_watch_funcs
= {
1025 g_io_win32_dispatch
,
1030 g_io_win32_msg_read (GIOChannel
*channel
,
1036 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1037 MSG msg
; /* In case of alignment problems */
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
;
1059 g_io_win32_msg_write (GIOChannel
*channel
,
1062 gsize
*bytes_written
,
1065 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1068 if (count
!= sizeof (MSG
))
1070 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
, G_IO_CHANNEL_ERROR_INVAL
,
1071 "Incorrect message size"); /* Informative enough error message? */
1072 return G_IO_STATUS_ERROR
;
1075 /* In case of alignment problems */
1076 memmove (&msg
, buf
, sizeof (MSG
));
1077 if (!PostMessage (win32_channel
->hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
))
1079 gchar
*emsg
= g_win32_error_message (GetLastError ());
1081 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
, G_IO_CHANNEL_ERROR_FAILED
, emsg
);
1084 return G_IO_STATUS_ERROR
;
1087 *bytes_written
= sizeof (MSG
);
1089 return G_IO_STATUS_NORMAL
;
1093 g_io_win32_msg_close (GIOChannel
*channel
,
1096 /* Nothing to be done. Or should we set hwnd to some invalid value? */
1098 return G_IO_STATUS_NORMAL
;
1102 g_io_win32_free (GIOChannel
*channel
)
1104 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1106 if (win32_channel
->debug
)
1107 g_print ("g_io_win32_free channel=%p fd=%d\n", channel
, win32_channel
->fd
);
1109 DeleteCriticalSection (&win32_channel
->mutex
);
1111 if (win32_channel
->data_avail_event
)
1112 if (!CloseHandle (win32_channel
->data_avail_event
))
1113 if (win32_channel
->debug
)
1115 gchar
*emsg
= g_win32_error_message (GetLastError ());
1117 g_print (" CloseHandle(%p) failed: %s\n",
1118 win32_channel
->data_avail_event
, emsg
);
1122 g_free (win32_channel
->buffer
);
1124 if (win32_channel
->space_avail_event
)
1125 if (!CloseHandle (win32_channel
->space_avail_event
))
1126 if (win32_channel
->debug
)
1128 gchar
*emsg
= g_win32_error_message (GetLastError ());
1130 g_print (" CloseHandle(%p) failed: %s\n",
1131 win32_channel
->space_avail_event
, emsg
);
1135 if (win32_channel
->type
== G_IO_WIN32_SOCKET
&&
1136 win32_channel
->fd
!= -1)
1137 if (WSAEventSelect (win32_channel
->fd
, NULL
, 0) == SOCKET_ERROR
)
1138 if (win32_channel
->debug
)
1140 gchar
*emsg
= g_win32_error_message (WSAGetLastError ());
1142 g_print (" WSAEventSelect(%d,NULL,{}) failed: %s\n",
1143 win32_channel
->fd
, emsg
);
1147 if (win32_channel
->event
)
1148 if (!WSACloseEvent (win32_channel
->event
))
1149 if (win32_channel
->debug
)
1151 gchar
*emsg
= g_win32_error_message (WSAGetLastError ());
1153 g_print (" WSACloseEvent(%p) failed: %s\n",
1154 win32_channel
->event
, emsg
);
1158 g_free (win32_channel
);
1162 g_io_win32_msg_create_watch (GIOChannel
*channel
,
1163 GIOCondition condition
)
1165 GIOWin32Watch
*watch
;
1168 source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1169 g_source_set_name (source
, "GIOChannel (Win32)");
1170 watch
= (GIOWin32Watch
*)source
;
1172 watch
->channel
= channel
;
1173 g_io_channel_ref (channel
);
1175 watch
->condition
= condition
;
1177 watch
->pollfd
.fd
= (gintptr
) G_WIN32_MSG_HANDLE
;
1178 watch
->pollfd
.events
= condition
;
1180 g_source_add_poll (source
, &watch
->pollfd
);
1186 g_io_win32_fd_and_console_read (GIOChannel
*channel
,
1192 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1195 if (win32_channel
->debug
)
1196 g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT
"\n",
1197 win32_channel
->fd
, count
);
1199 if (win32_channel
->thread_id
)
1201 return buffer_read (win32_channel
, buf
, count
, bytes_read
, err
);
1204 result
= read (win32_channel
->fd
, buf
, count
);
1206 if (win32_channel
->debug
)
1207 g_print ("g_io_win32_fd_read: read() => %d\n", result
);
1217 return G_IO_STATUS_AGAIN
;
1220 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1221 g_io_channel_error_from_errno (errno
),
1222 g_strerror (errno
));
1223 return G_IO_STATUS_ERROR
;
1227 *bytes_read
= result
;
1229 return (result
> 0) ? G_IO_STATUS_NORMAL
: G_IO_STATUS_EOF
;
1233 g_io_win32_fd_and_console_write (GIOChannel
*channel
,
1236 gsize
*bytes_written
,
1239 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1242 if (win32_channel
->thread_id
)
1244 return buffer_write (win32_channel
, buf
, count
, bytes_written
, err
);
1247 result
= write (win32_channel
->fd
, buf
, count
);
1248 if (win32_channel
->debug
)
1249 g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT
" => %d\n",
1250 win32_channel
->fd
, count
, result
);
1260 return G_IO_STATUS_AGAIN
;
1263 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1264 g_io_channel_error_from_errno (errno
),
1265 g_strerror (errno
));
1266 return G_IO_STATUS_ERROR
;
1270 *bytes_written
= result
;
1272 return G_IO_STATUS_NORMAL
;
1276 g_io_win32_fd_seek (GIOChannel
*channel
,
1281 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1298 whence
= -1; /* Keep the compiler quiet */
1299 g_assert_not_reached ();
1303 tmp_offset
= offset
;
1304 if (tmp_offset
!= offset
)
1306 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1307 g_io_channel_error_from_errno (EINVAL
),
1308 g_strerror (EINVAL
));
1309 return G_IO_STATUS_ERROR
;
1312 result
= lseek (win32_channel
->fd
, tmp_offset
, whence
);
1316 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1317 g_io_channel_error_from_errno (errno
),
1318 g_strerror (errno
));
1319 return G_IO_STATUS_ERROR
;
1322 return G_IO_STATUS_NORMAL
;
1326 g_io_win32_fd_close (GIOChannel
*channel
,
1329 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1331 if (win32_channel
->debug
)
1332 g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
1333 win32_channel
->thread_id
,
1335 EnterCriticalSection (&win32_channel
->mutex
);
1336 if (win32_channel
->running
)
1338 if (win32_channel
->debug
)
1339 g_print ("thread %#x: running, marking fd %d for later close\n",
1340 win32_channel
->thread_id
, win32_channel
->fd
);
1341 win32_channel
->running
= FALSE
;
1342 win32_channel
->needs_close
= TRUE
;
1343 if (win32_channel
->direction
== 0)
1344 SetEvent (win32_channel
->data_avail_event
);
1346 SetEvent (win32_channel
->space_avail_event
);
1350 if (win32_channel
->debug
)
1351 g_print ("closing fd %d\n", win32_channel
->fd
);
1352 close (win32_channel
->fd
);
1353 if (win32_channel
->debug
)
1354 g_print ("closed fd %d, setting to -1\n",
1356 win32_channel
->fd
= -1;
1358 LeaveCriticalSection (&win32_channel
->mutex
);
1360 /* FIXME error detection? */
1362 return G_IO_STATUS_NORMAL
;
1366 g_io_win32_fd_create_watch (GIOChannel
*channel
,
1367 GIOCondition condition
)
1369 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1370 GSource
*source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1371 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
1373 watch
->channel
= channel
;
1374 g_io_channel_ref (channel
);
1376 watch
->condition
= condition
;
1378 if (win32_channel
->data_avail_event
== NULL
)
1379 create_events (win32_channel
);
1381 watch
->pollfd
.fd
= (gintptr
) win32_channel
->data_avail_event
;
1382 watch
->pollfd
.events
= condition
;
1384 if (win32_channel
->debug
)
1385 g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
1386 channel
, win32_channel
->fd
,
1387 condition_to_string (condition
), (HANDLE
) watch
->pollfd
.fd
);
1389 EnterCriticalSection (&win32_channel
->mutex
);
1390 if (win32_channel
->thread_id
== 0)
1392 if (condition
& G_IO_IN
)
1393 create_thread (win32_channel
, condition
, read_thread
);
1394 else if (condition
& G_IO_OUT
)
1395 create_thread (win32_channel
, condition
, write_thread
);
1398 g_source_add_poll (source
, &watch
->pollfd
);
1399 LeaveCriticalSection (&win32_channel
->mutex
);
1405 g_io_win32_console_close (GIOChannel
*channel
,
1408 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1410 if (close (win32_channel
->fd
) < 0)
1412 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1413 g_io_channel_error_from_errno (errno
),
1414 g_strerror (errno
));
1415 return G_IO_STATUS_ERROR
;
1418 return G_IO_STATUS_NORMAL
;
1422 g_io_win32_console_create_watch (GIOChannel
*channel
,
1423 GIOCondition condition
)
1425 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1426 GSource
*source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1427 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
1429 watch
->channel
= channel
;
1430 g_io_channel_ref (channel
);
1432 watch
->condition
= condition
;
1434 watch
->pollfd
.fd
= _get_osfhandle (win32_channel
->fd
);
1435 watch
->pollfd
.events
= condition
;
1437 g_source_add_poll (source
, &watch
->pollfd
);
1443 g_io_win32_sock_read (GIOChannel
*channel
,
1449 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1451 GIOChannelError error
;
1454 if (win32_channel
->debug
)
1455 g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT
,
1456 channel
, win32_channel
->fd
, count
);
1458 result
= recv (win32_channel
->fd
, buf
, count
, 0);
1459 if (result
== SOCKET_ERROR
)
1460 winsock_error
= WSAGetLastError ();
1462 if (win32_channel
->debug
)
1463 g_print (" recv=%d", result
);
1465 if (result
== SOCKET_ERROR
)
1467 gchar
*emsg
= g_win32_error_message (winsock_error
);
1469 if (win32_channel
->debug
)
1470 g_print (" %s\n", emsg
);
1474 switch (winsock_error
)
1477 error
= G_IO_CHANNEL_ERROR_INVAL
;
1479 case WSAEWOULDBLOCK
:
1481 return G_IO_STATUS_AGAIN
;
1483 error
= G_IO_CHANNEL_ERROR_FAILED
;
1486 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
, error
, emsg
);
1489 return G_IO_STATUS_ERROR
;
1493 if (win32_channel
->debug
)
1495 *bytes_read
= result
;
1497 return G_IO_STATUS_EOF
;
1499 return G_IO_STATUS_NORMAL
;
1504 g_io_win32_sock_write (GIOChannel
*channel
,
1507 gsize
*bytes_written
,
1510 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1512 GIOChannelError error
;
1515 if (win32_channel
->debug
)
1516 g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT
,
1517 channel
, win32_channel
->fd
, count
);
1519 result
= send (win32_channel
->fd
, buf
, count
, 0);
1520 if (result
== SOCKET_ERROR
)
1521 winsock_error
= WSAGetLastError ();
1523 if (win32_channel
->debug
)
1524 g_print (" send=%d", result
);
1526 if (result
== SOCKET_ERROR
)
1528 gchar
*emsg
= g_win32_error_message (winsock_error
);
1530 if (win32_channel
->debug
)
1531 g_print (" %s\n", emsg
);
1535 switch (winsock_error
)
1538 error
= G_IO_CHANNEL_ERROR_INVAL
;
1540 case WSAEWOULDBLOCK
:
1541 win32_channel
->write_would_have_blocked
= TRUE
;
1542 win32_channel
->last_events
= 0;
1544 return G_IO_STATUS_AGAIN
;
1546 error
= G_IO_CHANNEL_ERROR_FAILED
;
1549 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
, error
, emsg
);
1552 return G_IO_STATUS_ERROR
;
1556 if (win32_channel
->debug
)
1558 *bytes_written
= result
;
1559 win32_channel
->write_would_have_blocked
= FALSE
;
1561 return G_IO_STATUS_NORMAL
;
1566 g_io_win32_sock_close (GIOChannel
*channel
,
1569 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1571 if (win32_channel
->fd
!= -1)
1573 if (win32_channel
->debug
)
1574 g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
1575 channel
, win32_channel
->fd
);
1577 closesocket (win32_channel
->fd
);
1578 win32_channel
->fd
= -1;
1581 /* FIXME error detection? */
1583 return G_IO_STATUS_NORMAL
;
1587 g_io_win32_sock_create_watch (GIOChannel
*channel
,
1588 GIOCondition condition
)
1590 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1591 GSource
*source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1592 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
1594 watch
->channel
= channel
;
1595 g_io_channel_ref (channel
);
1597 watch
->condition
= condition
;
1599 if (win32_channel
->event
== 0)
1600 win32_channel
->event
= WSACreateEvent ();
1602 watch
->pollfd
.fd
= (gintptr
) win32_channel
->event
;
1603 watch
->pollfd
.events
= condition
;
1605 if (win32_channel
->debug
)
1606 g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
1607 channel
, win32_channel
->fd
, (HANDLE
) watch
->pollfd
.fd
,
1608 condition_to_string (watch
->condition
));
1610 g_source_add_poll (source
, &watch
->pollfd
);
1616 g_io_channel_new_file (const gchar
*filename
,
1620 int fid
, flags
, pmode
;
1621 GIOChannel
*channel
;
1623 enum { /* Cheesy hack */
1630 g_return_val_if_fail (filename
!= NULL
, NULL
);
1631 g_return_val_if_fail (mode
!= NULL
, NULL
);
1632 g_return_val_if_fail ((error
== NULL
) || (*error
== NULL
), NULL
);
1646 g_warning ("Invalid GIOFileMode %s.", mode
);
1655 if (mode
[2] == '\0')
1657 mode_num
|= MODE_PLUS
;
1662 g_warning ("Invalid GIOFileMode %s.", mode
);
1673 flags
= O_WRONLY
| O_TRUNC
| O_CREAT
;
1677 flags
= O_WRONLY
| O_APPEND
| O_CREAT
;
1680 case MODE_R
| MODE_PLUS
:
1682 pmode
= _S_IREAD
| _S_IWRITE
;
1684 case MODE_W
| MODE_PLUS
:
1685 flags
= O_RDWR
| O_TRUNC
| O_CREAT
;
1686 pmode
= _S_IREAD
| _S_IWRITE
;
1688 case MODE_A
| MODE_PLUS
:
1689 flags
= O_RDWR
| O_APPEND
| O_CREAT
;
1690 pmode
= _S_IREAD
| _S_IWRITE
;
1693 g_assert_not_reached ();
1697 /* always open 'untranslated' */
1698 fid
= g_open (filename
, flags
| _O_BINARY
, pmode
);
1700 if (g_io_win32_get_debug_flag ())
1702 g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename
);
1703 g_win32_print_access_mode (flags
|_O_BINARY
);
1704 g_print (",%#o)=%d\n", pmode
, fid
);
1709 g_set_error_literal (error
, G_FILE_ERROR
,
1710 g_file_error_from_errno (errno
),
1711 g_strerror (errno
));
1712 return (GIOChannel
*)NULL
;
1715 channel
= g_io_channel_win32_new_fd (fid
);
1717 /* XXX: move this to g_io_channel_win32_new_fd () */
1718 channel
->close_on_unref
= TRUE
;
1719 channel
->is_seekable
= TRUE
;
1721 /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
1722 * correspond to actual readability/writeability. Set to FALSE those
1723 * that mode doesn't allow
1728 channel
->is_writeable
= FALSE
;
1732 channel
->is_readable
= FALSE
;
1734 case MODE_R
| MODE_PLUS
:
1735 case MODE_W
| MODE_PLUS
:
1736 case MODE_A
| MODE_PLUS
:
1739 g_assert_not_reached ();
1746 #if !defined (_WIN64)
1748 #undef g_io_channel_new_file
1750 /* Binary compatibility version. Not for newly compiled code. */
1753 g_io_channel_new_file (const gchar
*filename
,
1757 gchar
*utf8_filename
= g_locale_to_utf8 (filename
, -1, NULL
, NULL
, error
);
1760 if (utf8_filename
== NULL
)
1763 retval
= g_io_channel_new_file_utf8 (utf8_filename
, mode
, error
);
1765 g_free (utf8_filename
);
1773 g_io_win32_unimpl_set_flags (GIOChannel
*channel
,
1777 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1779 if (win32_channel
->debug
)
1781 g_print ("g_io_win32_unimpl_set_flags: ");
1782 g_win32_print_gioflags (flags
);
1786 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1787 G_IO_CHANNEL_ERROR_FAILED
,
1788 "Not implemented on Win32");
1790 return G_IO_STATUS_ERROR
;
1794 g_io_win32_fd_get_flags_internal (GIOChannel
*channel
,
1795 struct _stati64
*st
)
1797 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*) channel
;
1801 if (st
->st_mode
& _S_IFIFO
)
1803 channel
->is_readable
=
1804 (PeekNamedPipe ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
, NULL
) != 0) || GetLastError () == ERROR_BROKEN_PIPE
;
1805 channel
->is_writeable
=
1806 (WriteFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1807 channel
->is_seekable
= FALSE
;
1811 channel
->is_readable
=
1812 (ReadFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1813 channel
->is_writeable
=
1814 (WriteFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1815 channel
->is_seekable
= TRUE
;
1818 /* XXX: G_IO_FLAG_APPEND */
1819 /* XXX: G_IO_FLAG_NONBLOCK */
1825 g_io_win32_fd_get_flags (GIOChannel
*channel
)
1828 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1830 g_return_val_if_fail (win32_channel
!= NULL
, 0);
1831 g_return_val_if_fail (win32_channel
->type
== G_IO_WIN32_FILE_DESC
, 0);
1833 if (0 == _fstati64 (win32_channel
->fd
, &st
))
1834 return g_io_win32_fd_get_flags_internal (channel
, &st
);
1840 g_io_win32_console_get_flags_internal (GIOChannel
*channel
)
1842 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*) channel
;
1843 HANDLE handle
= (HANDLE
) _get_osfhandle (win32_channel
->fd
);
1846 INPUT_RECORD record
;
1848 channel
->is_readable
= PeekConsoleInput (handle
, &record
, 1, &count
);
1849 channel
->is_writeable
= WriteFile (handle
, &c
, 0, &count
, NULL
);
1850 channel
->is_seekable
= FALSE
;
1856 g_io_win32_console_get_flags (GIOChannel
*channel
)
1858 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1860 g_return_val_if_fail (win32_channel
!= NULL
, 0);
1861 g_return_val_if_fail (win32_channel
->type
== G_IO_WIN32_CONSOLE
, 0);
1863 return g_io_win32_console_get_flags_internal (channel
);
1867 g_io_win32_msg_get_flags (GIOChannel
*channel
)
1873 g_io_win32_sock_set_flags (GIOChannel
*channel
,
1877 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1880 if (win32_channel
->debug
)
1882 g_print ("g_io_win32_sock_set_flags: ");
1883 g_win32_print_gioflags (flags
);
1887 if (flags
& G_IO_FLAG_NONBLOCK
)
1890 if (ioctlsocket (win32_channel
->fd
, FIONBIO
, &arg
) == SOCKET_ERROR
)
1892 gchar
*emsg
= g_win32_error_message (WSAGetLastError ());
1894 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1895 G_IO_CHANNEL_ERROR_FAILED
,
1899 return G_IO_STATUS_ERROR
;
1905 if (ioctlsocket (win32_channel
->fd
, FIONBIO
, &arg
) == SOCKET_ERROR
)
1907 gchar
*emsg
= g_win32_error_message (WSAGetLastError ());
1909 g_set_error_literal (err
, G_IO_CHANNEL_ERROR
,
1910 G_IO_CHANNEL_ERROR_FAILED
,
1914 return G_IO_STATUS_ERROR
;
1918 return G_IO_STATUS_NORMAL
;
1922 g_io_win32_sock_get_flags (GIOChannel
*channel
)
1924 /* Could we do something here? */
1928 static GIOFuncs win32_channel_msg_funcs
= {
1929 g_io_win32_msg_read
,
1930 g_io_win32_msg_write
,
1932 g_io_win32_msg_close
,
1933 g_io_win32_msg_create_watch
,
1935 g_io_win32_unimpl_set_flags
,
1936 g_io_win32_msg_get_flags
,
1939 static GIOFuncs win32_channel_fd_funcs
= {
1940 g_io_win32_fd_and_console_read
,
1941 g_io_win32_fd_and_console_write
,
1943 g_io_win32_fd_close
,
1944 g_io_win32_fd_create_watch
,
1946 g_io_win32_unimpl_set_flags
,
1947 g_io_win32_fd_get_flags
,
1950 static GIOFuncs win32_channel_console_funcs
= {
1951 g_io_win32_fd_and_console_read
,
1952 g_io_win32_fd_and_console_write
,
1954 g_io_win32_console_close
,
1955 g_io_win32_console_create_watch
,
1957 g_io_win32_unimpl_set_flags
,
1958 g_io_win32_console_get_flags
,
1961 static GIOFuncs win32_channel_sock_funcs
= {
1962 g_io_win32_sock_read
,
1963 g_io_win32_sock_write
,
1965 g_io_win32_sock_close
,
1966 g_io_win32_sock_create_watch
,
1968 g_io_win32_sock_set_flags
,
1969 g_io_win32_sock_get_flags
,
1973 * g_io_channel_win32_new_messages:
1974 * @hwnd: a window handle.
1975 * @Returns: a new #GIOChannel.
1977 * Creates a new #GIOChannel given a window handle on Windows.
1979 * This function creates a #GIOChannel that can be used to poll for
1980 * Windows messages for the window in question.
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.
2048 * @Returns: a new #GIOChannel.
2050 * Creates a new #GIOChannel given a file descriptor on Windows. This
2051 * works for file descriptors from the C runtime.
2053 * This function works for file descriptors as returned by the open(),
2054 * creat(), pipe() and fileno() calls in the Microsoft C runtime. In
2055 * order to meaningfully use this function your code should use the
2056 * same C runtime as GLib uses, which is msvcrt.dll. Note that in
2057 * current Microsoft compilers it is near impossible to convince it to
2058 * build code that would use msvcrt.dll. The last Microsoft compiler
2059 * version that supported using msvcrt.dll as the C runtime was version
2060 * 6. The GNU compiler and toolchain for Windows, also known as Mingw,
2061 * fully supports msvcrt.dll.
2063 * If you have created a #GIOChannel for a file descriptor and started
2064 * watching (polling) it, you shouldn't call read() on the file
2065 * descriptor. This is because adding polling for a file descriptor is
2066 * implemented in GLib on Windows by starting a thread that sits
2067 * blocked in a read() from the file descriptor most of the time. All
2068 * reads from the file descriptor should be done by this internal GLib
2069 * thread. Your code should call only g_io_channel_read().
2071 * This function is available only in GLib on Windows.
2074 g_io_channel_win32_new_fd (gint fd
)
2078 if (_fstati64 (fd
, &st
) == -1)
2080 g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd
);
2084 return g_io_channel_win32_new_fd_internal (fd
, &st
);
2088 g_io_channel_win32_get_fd (GIOChannel
*channel
)
2090 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
2092 return win32_channel
->fd
;
2096 * g_io_channel_win32_new_socket:
2097 * @socket: a Winsock socket
2098 * @Returns: a new #GIOChannel
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.
2110 g_io_channel_win32_new_socket (int socket
)
2112 GIOWin32Channel
*win32_channel
= g_new (GIOWin32Channel
, 1);
2113 GIOChannel
*channel
= (GIOChannel
*)win32_channel
;
2115 g_io_channel_init (channel
);
2116 g_io_channel_win32_init (win32_channel
);
2117 if (win32_channel
->debug
)
2118 g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
2120 channel
->funcs
= &win32_channel_sock_funcs
;
2121 win32_channel
->type
= G_IO_WIN32_SOCKET
;
2122 win32_channel
->fd
= socket
;
2124 channel
->is_readable
= TRUE
;
2125 channel
->is_writeable
= TRUE
;
2126 channel
->is_seekable
= FALSE
;
2132 g_io_channel_unix_new (gint fd
)
2134 gboolean is_fd
, is_socket
;
2138 is_fd
= (_fstati64 (fd
, &st
) == 0);
2140 optlen
= sizeof (optval
);
2141 is_socket
= (getsockopt (fd
, SOL_SOCKET
, SO_TYPE
, (char *) &optval
, &optlen
) != SOCKET_ERROR
);
2143 if (is_fd
&& is_socket
)
2144 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
);
2147 return g_io_channel_win32_new_fd_internal (fd
, &st
);
2150 return g_io_channel_win32_new_socket(fd
);
2152 g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd
);
2158 g_io_channel_unix_get_fd (GIOChannel
*channel
)
2160 return g_io_channel_win32_get_fd (channel
);
2164 g_io_channel_win32_set_debug (GIOChannel
*channel
,
2167 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
2169 win32_channel
->debug
= flag
;
2173 g_io_channel_win32_poll (GPollFD
*fds
,
2177 g_return_val_if_fail (n_fds
>= 0, 0);
2179 return g_poll (fds
, n_fds
, timeout
);
2183 g_io_channel_win32_make_pollfd (GIOChannel
*channel
,
2184 GIOCondition condition
,
2187 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
2189 switch (win32_channel
->type
)
2191 case G_IO_WIN32_FILE_DESC
:
2192 if (win32_channel
->data_avail_event
== NULL
)
2193 create_events (win32_channel
);
2195 fd
->fd
= (gintptr
) win32_channel
->data_avail_event
;
2197 if (win32_channel
->thread_id
== 0)
2199 /* Is it meaningful for a file descriptor to be polled for
2200 * both IN and OUT? For what kind of file descriptor would
2201 * that be? Doesn't seem to make sense, in practise the file
2202 * descriptors handled here are always read or write ends of
2203 * pipes surely, and thus unidirectional.
2205 if (condition
& G_IO_IN
)
2206 create_thread (win32_channel
, condition
, read_thread
);
2207 else if (condition
& G_IO_OUT
)
2208 create_thread (win32_channel
, condition
, write_thread
);
2212 case G_IO_WIN32_CONSOLE
:
2213 fd
->fd
= _get_osfhandle (win32_channel
->fd
);
2216 case G_IO_WIN32_SOCKET
:
2217 fd
->fd
= (gintptr
) WSACreateEvent ();
2220 case G_IO_WIN32_WINDOWS_MESSAGES
:
2221 fd
->fd
= G_WIN32_MSG_HANDLE
;
2225 g_assert_not_reached ();
2229 fd
->events
= condition
;
2234 /* Binary compatibility */
2236 g_io_channel_win32_new_stream_socket (int socket
)
2238 return g_io_channel_win32_new_socket (socket
);