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/.
50 typedef struct _GIOWin32Channel GIOWin32Channel
;
51 typedef struct _GIOWin32Watch GIOWin32Watch
;
53 #define BUFFER_SIZE 4096
56 G_IO_WIN32_WINDOWS_MESSAGES
, /* Windows messages */
57 G_IO_WIN32_FILE_DESC
, /* Unix-like file descriptors from
58 * _open() or _pipe(). Read with read().
59 * Have to create separate thread to read.
61 G_IO_WIN32_SOCKET
/* Sockets. No separate thread */
62 } GIOWin32ChannelType
;
64 struct _GIOWin32Channel
{
66 gint fd
; /* Either a Unix-like file handle as provided
67 * by the Microsoft C runtime, or a SOCKET
68 * as provided by WinSock.
70 GIOWin32ChannelType type
;
74 /* This is used by G_IO_WIN32_WINDOWS_MESSAGES channels */
75 HWND hwnd
; /* handle of window, or NULL */
77 /* Following fields are used by fd channels. */
78 CRITICAL_SECTION mutex
;
80 int direction
; /* 0 means we read from it,
81 * 1 means we write to it.
84 gboolean running
; /* Is reader thread running. FALSE if
85 * EOF has been reached.
87 gboolean needs_close
; /* If the channel has been closed while
88 * the reader thread was still running.
90 guint thread_id
; /* If non-NULL has a reader thread, or has
92 HANDLE data_avail_event
;
96 /* Following fields used by fd channels for input */
98 /* Data is kept in a circular buffer. To be able to distinguish between
99 * empty and full buffer, we cannot fill it completely, but have to
100 * leave a one character gap.
102 * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
105 * Full: (wrp + 1) % BUFFER_SIZE == rdp
108 guchar
*buffer
; /* (Circular) buffer */
109 gint wrp
, rdp
; /* Buffer indices for writing and reading */
110 HANDLE space_avail_event
;
112 /* Following fields used by socket channels */
116 gboolean write_would_have_blocked
;
119 #define LOCK(mutex) EnterCriticalSection (&mutex)
120 #define UNLOCK(mutex) LeaveCriticalSection (&mutex)
122 struct _GIOWin32Watch
{
126 GIOCondition condition
;
130 g_win32_print_access_mode (int flags
)
132 g_print ("%s%s%s%s%s%s%s%s%s%s",
133 ((flags
& 0x3) == _O_RDWR
? "O_RDWR" :
134 ((flags
& 0x3) == _O_RDONLY
? "O_RDONLY" :
135 ((flags
& 0x3) == _O_WRONLY
? "O_WRONLY" : "0"))),
136 (flags
& _O_APPEND
? "|O_APPEND" : ""),
137 (flags
& _O_RANDOM
? "|O_RANDOM" : ""),
138 (flags
& _O_SEQUENTIAL
? "|O_SEQUENTIAL" : ""),
139 (flags
& _O_TEMPORARY
? "|O_TEMPORARY" : ""),
140 (flags
& _O_CREAT
? "|O_CREAT" : ""),
141 (flags
& _O_TRUNC
? "|O_TRUNC" : ""),
142 (flags
& _O_EXCL
? "|O_EXCL" : ""),
143 (flags
& _O_TEXT
? "|O_TEXT" : ""),
144 (flags
& _O_BINARY
? "|O_BINARY" : ""));
148 g_win32_print_gioflags (GIOFlags flags
)
152 if (flags
& G_IO_FLAG_APPEND
)
153 bar
= "|", g_print ("APPEND");
154 if (flags
& G_IO_FLAG_NONBLOCK
)
155 g_print ("%sNONBLOCK", bar
), bar
= "|";
156 if (flags
& G_IO_FLAG_IS_READABLE
)
157 g_print ("%sREADABLE", bar
), bar
= "|";
158 if (flags
& G_IO_FLAG_IS_WRITEABLE
)
159 g_print ("%sWRITEABLE", bar
), bar
= "|";
160 if (flags
& G_IO_FLAG_IS_SEEKABLE
)
161 g_print ("%sSEEKABLE", bar
), bar
= "|";
165 event_mask_to_string (int mask
)
168 int checked_bits
= 0;
174 #define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
184 BIT (ROUTING_INTERFACE_CHANGE
);
185 BIT (ADDRESS_LIST_CHANGE
);
189 if ((mask
& ~checked_bits
) != 0)
190 bufp
+= sprintf (bufp
, "|%#x", mask
& ~checked_bits
);
192 return g_quark_to_string (g_quark_from_string (buf
));
196 condition_to_string (GIOCondition condition
)
199 int checked_bits
= 0;
205 #define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
216 if ((condition
& ~checked_bits
) != 0)
217 bufp
+= sprintf (bufp
, "|%#x", condition
& ~checked_bits
);
219 return g_quark_to_string (g_quark_from_string (buf
));
223 g_io_win32_get_debug_flag (void)
225 return (getenv ("G_IO_WIN32_DEBUG") != NULL
);
229 winsock_error_message (int number
)
231 static char unk
[100];
235 return "Interrupted function call";
237 return "Permission denied";
239 return "Bad address";
241 return "Invalid argument";
243 return "Too many open sockets";
245 return "Resource temporarily unavailable";
247 return "Operation now in progress";
249 return "Operation already in progress";
251 return "Socket operation on nonsocket";
252 case WSAEDESTADDRREQ
:
253 return "Destination address required";
255 return "Message too long";
257 return "Protocol wrong type for socket";
259 return "Bad protocol option";
260 case WSAEPROTONOSUPPORT
:
261 return "Protocol not supported";
262 case WSAESOCKTNOSUPPORT
:
263 return "Socket type not supported";
265 return "Operation not supported on transport endpoint";
266 case WSAEPFNOSUPPORT
:
267 return "Protocol family not supported";
268 case WSAEAFNOSUPPORT
:
269 return "Address family not supported by protocol family";
271 return "Address already in use";
272 case WSAEADDRNOTAVAIL
:
273 return "Address not available";
275 return "Network interface is not configured";
277 return "Network is unreachable";
279 return "Network dropped connection on reset";
280 case WSAECONNABORTED
:
281 return "Software caused connection abort";
283 return "Connection reset by peer";
285 return "No buffer space available";
287 return "Socket is already connected";
289 return "Socket is not connected";
291 return "Can't send after socket shutdown";
293 return "Connection timed out";
294 case WSAECONNREFUSED
:
295 return "Connection refused";
297 return "Host is down";
298 case WSAEHOSTUNREACH
:
299 return "Host is unreachable";
301 return "Too many processes";
303 return "Network subsystem is unavailable";
304 case WSAVERNOTSUPPORTED
:
305 return "Winsock.dll version out of range";
306 case WSANOTINITIALISED
:
307 return "Successful WSAStartup not yet performed";
309 return "Graceful shutdown in progress";
310 case WSATYPE_NOT_FOUND
:
311 return "Class type not found";
312 case WSAHOST_NOT_FOUND
:
313 return "Host not found";
315 return "Nonauthoritative host not found";
317 return "This is a nonrecoverable error";
319 return "Valid name, no data record of requested type";
320 case WSA_INVALID_HANDLE
:
321 return "Specified event object handle is invalid";
322 case WSA_INVALID_PARAMETER
:
323 return "One or more parameters are invalid";
324 case WSA_IO_INCOMPLETE
:
325 return "Overlapped I/O event object not in signaled state";
326 case WSA_NOT_ENOUGH_MEMORY
:
327 return "Insufficient memory available";
328 case WSA_OPERATION_ABORTED
:
329 return "Overlapped operation aborted";
330 case WSAEINVALIDPROCTABLE
:
331 return "Invalid procedure table from service provider";
332 case WSAEINVALIDPROVIDER
:
333 return "Invalid service provider version number";
334 case WSAEPROVIDERFAILEDINIT
:
335 return "Unable to initialize a service provider";
336 case WSASYSCALLFAILURE
:
337 return "System call failure";
339 sprintf (unk
, "Unknown WinSock error %d", number
);
345 g_io_channel_win32_init (GIOWin32Channel
*channel
)
347 channel
->debug
= g_io_win32_get_debug_flag ();
348 channel
->buffer
= NULL
;
349 channel
->running
= FALSE
;
350 channel
->needs_close
= FALSE
;
351 channel
->thread_id
= 0;
352 channel
->data_avail_event
= NULL
;
353 channel
->revents
= 0;
354 channel
->space_avail_event
= NULL
;
355 channel
->event_mask
= 0;
356 channel
->last_events
= 0;
358 channel
->write_would_have_blocked
= FALSE
;
359 InitializeCriticalSection (&channel
->mutex
);
363 create_events (GIOWin32Channel
*channel
)
365 SECURITY_ATTRIBUTES sec_attrs
;
367 sec_attrs
.nLength
= sizeof (SECURITY_ATTRIBUTES
);
368 sec_attrs
.lpSecurityDescriptor
= NULL
;
369 sec_attrs
.bInheritHandle
= FALSE
;
371 /* The data available event is manual reset, the space available event
372 * is automatic reset.
374 if (!(channel
->data_avail_event
= CreateEvent (&sec_attrs
, TRUE
, FALSE
, NULL
))
375 || !(channel
->space_avail_event
= CreateEvent (&sec_attrs
, FALSE
, FALSE
, NULL
)))
377 gchar
*emsg
= g_win32_error_message (GetLastError ());
378 g_error ("Error creating event: %s", emsg
);
383 static unsigned __stdcall
384 read_thread (void *parameter
)
386 GIOWin32Channel
*channel
= parameter
;
390 g_io_channel_ref ((GIOChannel
*)channel
);
393 g_print ("read_thread %#x: start fd=%d, data_avail=%#x space_avail=%#x\n",
396 (guint
) channel
->data_avail_event
,
397 (guint
) channel
->space_avail_event
);
399 channel
->direction
= 0;
400 channel
->buffer
= g_malloc (BUFFER_SIZE
);
401 channel
->rdp
= channel
->wrp
= 0;
402 channel
->running
= TRUE
;
404 SetEvent (channel
->space_avail_event
);
406 LOCK (channel
->mutex
);
407 while (channel
->running
)
410 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
411 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
412 if ((channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
416 g_print ("read_thread %#x: resetting space_avail\n",
418 ResetEvent (channel
->space_avail_event
);
420 g_print ("read_thread %#x: waiting for space\n",
422 UNLOCK (channel
->mutex
);
423 WaitForSingleObject (channel
->space_avail_event
, INFINITE
);
424 LOCK (channel
->mutex
);
426 g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
427 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
430 buffer
= channel
->buffer
+ channel
->wrp
;
432 /* Always leave at least one byte unused gap to be able to
433 * distinguish between the full and empty condition...
435 nbytes
= MIN ((channel
->rdp
+ BUFFER_SIZE
- channel
->wrp
- 1) % BUFFER_SIZE
,
436 BUFFER_SIZE
- channel
->wrp
);
439 g_print ("read_thread %#x: calling read() for %d bytes\n",
440 channel
->thread_id
, nbytes
);
442 UNLOCK (channel
->mutex
);
444 nbytes
= read (channel
->fd
, buffer
, nbytes
);
446 LOCK (channel
->mutex
);
448 channel
->revents
= G_IO_IN
;
450 channel
->revents
|= G_IO_HUP
;
452 channel
->revents
|= G_IO_ERR
;
455 g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
456 channel
->thread_id
, nbytes
, channel
->rdp
, channel
->wrp
);
461 channel
->wrp
= (channel
->wrp
+ nbytes
) % BUFFER_SIZE
;
463 g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
464 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
465 SetEvent (channel
->data_avail_event
);
468 channel
->running
= FALSE
;
469 if (channel
->needs_close
)
472 g_print ("read_thread %#x: channel fd %d needs closing\n",
473 channel
->thread_id
, channel
->fd
);
479 g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
480 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
481 SetEvent (channel
->data_avail_event
);
482 UNLOCK (channel
->mutex
);
484 g_io_channel_unref ((GIOChannel
*)channel
);
486 /* No need to call _endthreadex(), the actual thread starter routine
487 * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
488 * _endthreadex() for us.
494 static unsigned __stdcall
495 write_thread (void *parameter
)
497 GIOWin32Channel
*channel
= parameter
;
501 g_io_channel_ref ((GIOChannel
*)channel
);
504 g_print ("write_thread %#x: start fd=%d, data_avail=%#x space_avail=%#x\n",
507 (guint
) channel
->data_avail_event
,
508 (guint
) channel
->space_avail_event
);
510 channel
->direction
= 1;
511 channel
->buffer
= g_malloc (BUFFER_SIZE
);
512 channel
->rdp
= channel
->wrp
= 0;
513 channel
->running
= TRUE
;
515 SetEvent (channel
->space_avail_event
);
517 /* We use the same event objects as for a reader thread, but with
518 * reversed meaning. So, space_avail is used if data is available
519 * for writing, and data_avail is used if space is available in the
523 LOCK (channel
->mutex
);
524 while (channel
->running
|| channel
->rdp
!= channel
->wrp
)
527 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
528 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
529 if (channel
->wrp
== channel
->rdp
)
531 /* Buffer is empty. */
533 g_print ("write_thread %#x: resetting space_avail\n",
535 ResetEvent (channel
->space_avail_event
);
537 g_print ("write_thread %#x: waiting for data\n",
539 channel
->revents
= G_IO_OUT
;
540 SetEvent (channel
->data_avail_event
);
541 UNLOCK (channel
->mutex
);
542 WaitForSingleObject (channel
->space_avail_event
, INFINITE
);
544 LOCK (channel
->mutex
);
545 if (channel
->rdp
== channel
->wrp
)
549 g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
550 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
553 buffer
= channel
->buffer
+ channel
->rdp
;
554 if (channel
->rdp
< channel
->wrp
)
555 nbytes
= channel
->wrp
- channel
->rdp
;
557 nbytes
= BUFFER_SIZE
- channel
->rdp
;
560 g_print ("write_thread %#x: calling write() for %d bytes\n",
561 channel
->thread_id
, nbytes
);
563 UNLOCK (channel
->mutex
);
564 nbytes
= write (channel
->fd
, buffer
, nbytes
);
565 LOCK (channel
->mutex
);
568 g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
569 channel
->thread_id
, channel
->fd
, nbytes
, channel
->rdp
, channel
->wrp
);
571 channel
->revents
= 0;
573 channel
->revents
|= G_IO_OUT
;
574 else if (nbytes
<= 0)
575 channel
->revents
|= G_IO_ERR
;
577 channel
->rdp
= (channel
->rdp
+ nbytes
) % BUFFER_SIZE
;
583 g_print ("write_thread: setting data_avail for thread %#x\n",
585 SetEvent (channel
->data_avail_event
);
588 channel
->running
= FALSE
;
589 if (channel
->needs_close
)
592 g_print ("write_thread %#x: channel fd %d needs closing\n",
593 channel
->thread_id
, channel
->fd
);
598 UNLOCK (channel
->mutex
);
600 g_io_channel_unref ((GIOChannel
*)channel
);
606 create_thread (GIOWin32Channel
*channel
,
607 GIOCondition condition
,
608 unsigned (__stdcall
*thread
) (void *parameter
))
610 HANDLE thread_handle
;
612 thread_handle
= (HANDLE
) _beginthreadex (NULL
, 0, thread
, channel
, 0,
613 &channel
->thread_id
);
614 if (thread_handle
== 0)
615 g_warning (G_STRLOC
": Error creating reader thread: %s",
617 else if (!CloseHandle (thread_handle
))
618 g_warning (G_STRLOC
": Error closing thread handle: %s\n",
619 g_win32_error_message (GetLastError ()));
621 WaitForSingleObject (channel
->space_avail_event
, INFINITE
);
625 buffer_read (GIOWin32Channel
*channel
,
634 LOCK (channel
->mutex
);
636 g_print ("reading from thread %#x %d bytes, rdp=%d, wrp=%d\n",
637 channel
->thread_id
, count
, channel
->rdp
, channel
->wrp
);
639 if (channel
->wrp
== channel
->rdp
)
641 UNLOCK (channel
->mutex
);
643 g_print ("waiting for data from thread %#x\n", channel
->thread_id
);
644 WaitForSingleObject (channel
->data_avail_event
, INFINITE
);
646 g_print ("done waiting for data from thread %#x\n", channel
->thread_id
);
647 LOCK (channel
->mutex
);
648 if (channel
->wrp
== channel
->rdp
&& !channel
->running
)
651 g_print ("wrp==rdp, !running\n");
652 UNLOCK (channel
->mutex
);
654 return G_IO_STATUS_EOF
;
658 if (channel
->rdp
< channel
->wrp
)
659 nbytes
= channel
->wrp
- channel
->rdp
;
661 nbytes
= BUFFER_SIZE
- channel
->rdp
;
662 UNLOCK (channel
->mutex
);
663 nbytes
= MIN (left
, nbytes
);
665 g_print ("moving %d bytes from thread %#x\n",
666 nbytes
, channel
->thread_id
);
667 memcpy (dest
, channel
->buffer
+ channel
->rdp
, nbytes
);
670 LOCK (channel
->mutex
);
671 channel
->rdp
= (channel
->rdp
+ nbytes
) % BUFFER_SIZE
;
673 g_print ("setting space_avail for thread %#x\n", channel
->thread_id
);
674 SetEvent (channel
->space_avail_event
);
676 g_print ("for thread %#x: rdp=%d, wrp=%d\n",
677 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
678 if (channel
->running
&& channel
->wrp
== channel
->rdp
)
681 g_print ("resetting data_avail of thread %#x\n",
683 ResetEvent (channel
->data_avail_event
);
685 UNLOCK (channel
->mutex
);
687 /* We have no way to indicate any errors form the actual
688 * read() or recv() call in the reader thread. Should we have?
690 *bytes_read
= count
- left
;
691 return (*bytes_read
> 0) ? G_IO_STATUS_NORMAL
: G_IO_STATUS_EOF
;
696 buffer_write (GIOWin32Channel
*channel
,
699 gsize
*bytes_written
,
705 LOCK (channel
->mutex
);
707 g_print ("buffer_write: writing to thread %#x %d bytes, rdp=%d, wrp=%d\n",
708 channel
->thread_id
, count
, channel
->rdp
, channel
->wrp
);
710 if ((channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
714 g_print ("buffer_write: tid %#x: resetting data_avail\n",
716 ResetEvent (channel
->data_avail_event
);
718 g_print ("buffer_write: tid %#x: waiting for space\n",
720 UNLOCK (channel
->mutex
);
721 WaitForSingleObject (channel
->data_avail_event
, INFINITE
);
722 LOCK (channel
->mutex
);
724 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
725 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
728 nbytes
= MIN ((channel
->rdp
+ BUFFER_SIZE
- channel
->wrp
- 1) % BUFFER_SIZE
,
729 BUFFER_SIZE
- channel
->wrp
);
731 UNLOCK (channel
->mutex
);
732 nbytes
= MIN (left
, nbytes
);
734 g_print ("buffer_write: tid %#x: writing %d bytes\n",
735 channel
->thread_id
, nbytes
);
736 memcpy (channel
->buffer
+ channel
->wrp
, dest
, nbytes
);
739 LOCK (channel
->mutex
);
741 channel
->wrp
= (channel
->wrp
+ nbytes
) % BUFFER_SIZE
;
743 g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
744 channel
->thread_id
, channel
->rdp
, channel
->wrp
);
745 SetEvent (channel
->space_avail_event
);
747 if ((channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
751 g_print ("buffer_write: tid %#x: resetting data_avail\n",
753 ResetEvent (channel
->data_avail_event
);
756 UNLOCK (channel
->mutex
);
758 /* We have no way to indicate any errors form the actual
759 * write() call in the writer thread. Should we have?
761 *bytes_written
= count
- left
;
762 return (*bytes_written
> 0) ? G_IO_STATUS_NORMAL
: G_IO_STATUS_EOF
;
767 g_io_win32_prepare (GSource
*source
,
770 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
771 GIOCondition buffer_condition
= g_io_channel_get_buffer_condition (watch
->channel
);
772 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
777 switch (channel
->type
)
779 case G_IO_WIN32_WINDOWS_MESSAGES
:
782 case G_IO_WIN32_FILE_DESC
:
784 g_print ("g_io_win32_prepare: for thread %#x buffer_condition:{%s}\n"
785 " watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}\n",
786 channel
->thread_id
, condition_to_string (buffer_condition
),
787 condition_to_string (watch
->pollfd
.events
),
788 condition_to_string (watch
->pollfd
.revents
),
789 condition_to_string (channel
->revents
));
791 LOCK (channel
->mutex
);
792 if (channel
->running
)
794 if (channel
->direction
== 0 && channel
->wrp
== channel
->rdp
)
797 g_print ("g_io_win32_prepare: for thread %#x, setting channel->revents = 0\n",
799 channel
->revents
= 0;
804 if (channel
->direction
== 1
805 && (channel
->wrp
+ 1) % BUFFER_SIZE
== channel
->rdp
)
808 g_print ("g_io_win32_prepare: for thread %#x, setting channel->revents = %i\n",
809 channel
->thread_id
, 0);
810 channel
->revents
= 0;
813 UNLOCK (channel
->mutex
);
816 case G_IO_WIN32_SOCKET
:
818 if (watch
->condition
& G_IO_IN
)
819 event_mask
|= (FD_READ
| FD_ACCEPT
);
820 if (watch
->condition
& G_IO_OUT
)
821 event_mask
|= (FD_WRITE
| FD_CONNECT
);
822 if (watch
->condition
& G_IO_HUP
)
823 event_mask
|= FD_CLOSE
;
825 if (channel
->event_mask
!= event_mask
/* || channel->event != watch->pollfd.fd*/)
828 g_print ("g_io_win32_prepare: WSAEventSelect(%d, %#x, {%s}\n",
829 channel
->fd
, watch
->pollfd
.fd
,
830 event_mask_to_string (event_mask
));
831 if (WSAEventSelect (channel
->fd
, (HANDLE
) watch
->pollfd
.fd
,
832 event_mask
) == SOCKET_ERROR
)
834 channel
->event_mask
= event_mask
;
836 channel
->event
= watch
->pollfd
.fd
;
838 channel
->last_events
= 0;
843 g_assert_not_reached ();
846 return ((watch
->condition
& buffer_condition
) == watch
->condition
);
850 g_io_win32_check (GSource
*source
)
853 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
854 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
855 GIOCondition buffer_condition
= g_io_channel_get_buffer_condition (watch
->channel
);
856 WSANETWORKEVENTS events
;
858 switch (channel
->type
)
860 case G_IO_WIN32_WINDOWS_MESSAGES
:
861 return (PeekMessage (&msg
, channel
->hwnd
, 0, 0, PM_NOREMOVE
));
863 case G_IO_WIN32_FILE_DESC
:
865 g_print ("g_io_win32_check: for thread %#x buffer_condition=%s\n"
866 " watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
867 channel
->thread_id
, condition_to_string (buffer_condition
),
868 condition_to_string (watch
->pollfd
.events
),
869 condition_to_string (watch
->pollfd
.revents
),
870 condition_to_string (channel
->revents
));
872 watch
->pollfd
.revents
= (watch
->pollfd
.events
& channel
->revents
);
874 return ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
);
876 case G_IO_WIN32_SOCKET
:
877 if (channel
->last_events
& FD_WRITE
)
880 g_print ("g_io_win32_check: sock=%d event=%#x last_events has FD_WRITE\n",
881 channel
->fd
, watch
->pollfd
.fd
);
885 WSAEnumNetworkEvents (channel
->fd
, 0, &events
);
888 g_print ("g_io_win32_check: WSAEnumNetworkEvents (%d, %#x) revents={%s} condition={%s} events={%s}\n",
889 channel
->fd
, watch
->pollfd
.fd
,
890 condition_to_string (watch
->pollfd
.revents
),
891 condition_to_string (watch
->condition
),
892 event_mask_to_string (events
.lNetworkEvents
));
894 if (watch
->pollfd
.revents
!= 0 &&
895 events
.lNetworkEvents
== 0 &&
896 !(channel
->event_mask
& FD_WRITE
))
898 channel
->event_mask
= 0;
900 g_print ("g_io_win32_check: WSAEventSelect(%d, %#x, {})\n",
901 channel
->fd
, watch
->pollfd
.fd
);
902 WSAEventSelect (channel
->fd
, (HANDLE
) watch
->pollfd
.fd
, 0);
904 g_print ("g_io_win32_check: ResetEvent(%#x)\n",
906 ResetEvent ((HANDLE
) watch
->pollfd
.fd
);
908 channel
->last_events
= events
.lNetworkEvents
;
910 watch
->pollfd
.revents
= 0;
911 if (channel
->last_events
& (FD_READ
| FD_ACCEPT
))
912 watch
->pollfd
.revents
|= G_IO_IN
;
913 if (channel
->last_events
& (FD_WRITE
| FD_CONNECT
))
914 watch
->pollfd
.revents
|= G_IO_OUT
;
915 if (watch
->pollfd
.revents
== 0 && (channel
->last_events
& (FD_CLOSE
)))
916 watch
->pollfd
.revents
|= G_IO_HUP
;
918 if (!channel
->write_would_have_blocked
&& (channel
->event_mask
& FD_WRITE
))
919 watch
->pollfd
.revents
|= G_IO_OUT
; /* This sucks but... */
921 return ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
);
924 g_assert_not_reached ();
930 g_io_win32_dispatch (GSource
*source
,
931 GSourceFunc callback
,
934 GIOFunc func
= (GIOFunc
)callback
;
935 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
936 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
937 GIOCondition buffer_condition
= g_io_channel_get_buffer_condition (watch
->channel
);
941 g_warning (G_STRLOC
": GIOWin32Watch dispatched without callback\n"
942 "You must call g_source_connect().");
947 g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
948 condition_to_string (watch
->pollfd
.revents
),
949 condition_to_string (watch
->condition
),
950 condition_to_string ((watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
));
952 return (*func
) (watch
->channel
,
953 (watch
->pollfd
.revents
| buffer_condition
) & watch
->condition
,
958 g_io_win32_finalize (GSource
*source
)
960 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
961 GIOWin32Channel
*channel
= (GIOWin32Channel
*)watch
->channel
;
963 switch (channel
->type
)
965 case G_IO_WIN32_WINDOWS_MESSAGES
:
968 case G_IO_WIN32_FILE_DESC
:
969 LOCK (channel
->mutex
);
971 g_print ("g_io_win32_finalize: channel with thread %#x\n",
973 UNLOCK (channel
->mutex
);
976 case G_IO_WIN32_SOCKET
:
978 g_print ("g_io_win32_finalize: channel is for sock=%d\n", channel
->fd
);
980 CloseHandle ((HANDLE
) watch
->pollfd
.fd
);
982 channel
->event_mask
= 0;
987 g_assert_not_reached ();
990 g_io_channel_unref (watch
->channel
);
993 GSourceFuncs g_io_watch_funcs
= {
1001 g_io_win32_msg_read (GIOChannel
*channel
,
1007 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1008 MSG msg
; /* In case of alignment problems */
1010 if (count
< sizeof (MSG
))
1012 g_set_error (err
, G_IO_CHANNEL_ERROR
, G_IO_CHANNEL_ERROR_INVAL
,
1013 "Incorrect message size"); /* Informative enough error message? */
1014 return G_IO_STATUS_ERROR
;
1017 if (win32_channel
->debug
)
1018 g_print ("g_io_win32_msg_read: for %#x\n",
1019 (guint
) win32_channel
->hwnd
);
1020 if (!PeekMessage (&msg
, win32_channel
->hwnd
, 0, 0, PM_REMOVE
))
1021 return G_IO_STATUS_AGAIN
;
1023 memmove (buf
, &msg
, sizeof (MSG
));
1024 *bytes_read
= sizeof (MSG
);
1026 return G_IO_STATUS_NORMAL
;
1030 g_io_win32_msg_write (GIOChannel
*channel
,
1033 gsize
*bytes_written
,
1036 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1039 if (count
!= sizeof (MSG
))
1041 g_set_error (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 /* In case of alignment problems */
1047 memmove (&msg
, buf
, sizeof (MSG
));
1048 if (!PostMessage (win32_channel
->hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
))
1050 gchar
*emsg
= g_win32_error_message (GetLastError ());
1051 g_set_error (err
, G_IO_CHANNEL_ERROR
, G_IO_CHANNEL_ERROR_FAILED
, emsg
);
1053 return G_IO_STATUS_ERROR
;
1056 *bytes_written
= sizeof (MSG
);
1058 return G_IO_STATUS_NORMAL
;
1062 g_io_win32_msg_close (GIOChannel
*channel
,
1065 /* Nothing to be done. Or should we set hwnd to some invalid value? */
1067 return G_IO_STATUS_NORMAL
;
1071 g_io_win32_free (GIOChannel
*channel
)
1073 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1075 if (win32_channel
->debug
)
1076 g_print ("g_io_win32_free channel fd=%d\n", win32_channel
->fd
);
1078 if (win32_channel
->data_avail_event
)
1079 CloseHandle (win32_channel
->data_avail_event
);
1080 if (win32_channel
->space_avail_event
)
1081 CloseHandle (win32_channel
->space_avail_event
);
1082 if (win32_channel
->type
== G_IO_WIN32_SOCKET
)
1083 WSAEventSelect (win32_channel
->fd
, NULL
, 0);
1084 DeleteCriticalSection (&win32_channel
->mutex
);
1086 g_free (win32_channel
->buffer
);
1087 g_free (win32_channel
);
1091 g_io_win32_msg_create_watch (GIOChannel
*channel
,
1092 GIOCondition condition
)
1094 GIOWin32Watch
*watch
;
1097 source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1098 watch
= (GIOWin32Watch
*)source
;
1100 watch
->channel
= channel
;
1101 g_io_channel_ref (channel
);
1103 watch
->condition
= condition
;
1105 watch
->pollfd
.fd
= G_WIN32_MSG_HANDLE
;
1106 watch
->pollfd
.events
= condition
;
1108 g_source_add_poll (source
, &watch
->pollfd
);
1114 g_io_win32_fd_read (GIOChannel
*channel
,
1120 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1123 if (win32_channel
->debug
)
1124 g_print ("g_io_win32_fd_read: fd=%d count=%d\n",
1125 win32_channel
->fd
, count
);
1127 if (win32_channel
->thread_id
)
1129 return buffer_read (win32_channel
, buf
, count
, bytes_read
, err
);
1132 result
= read (win32_channel
->fd
, buf
, count
);
1134 if (win32_channel
->debug
)
1135 g_print ("g_io_win32_fd_read: read() => %d\n", result
);
1145 return G_IO_STATUS_AGAIN
;
1148 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1149 g_io_channel_error_from_errno (errno
),
1150 g_strerror (errno
));
1151 return G_IO_STATUS_ERROR
;
1155 *bytes_read
= result
;
1157 return (result
> 0) ? G_IO_STATUS_NORMAL
: G_IO_STATUS_EOF
;
1161 g_io_win32_fd_write (GIOChannel
*channel
,
1164 gsize
*bytes_written
,
1167 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1170 if (win32_channel
->thread_id
)
1172 return buffer_write (win32_channel
, buf
, count
, bytes_written
, err
);
1175 result
= write (win32_channel
->fd
, buf
, count
);
1176 if (win32_channel
->debug
)
1177 g_print ("g_io_win32_fd_write: fd=%d count=%d => %d\n",
1178 win32_channel
->fd
, count
, result
);
1188 return G_IO_STATUS_AGAIN
;
1191 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1192 g_io_channel_error_from_errno (errno
),
1193 g_strerror (errno
));
1194 return G_IO_STATUS_ERROR
;
1198 *bytes_written
= result
;
1200 return G_IO_STATUS_NORMAL
;
1204 g_io_win32_fd_seek (GIOChannel
*channel
,
1209 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1226 whence
= -1; /* Keep the compiler quiet */
1227 g_assert_not_reached ();
1231 tmp_offset
= offset
;
1232 if (tmp_offset
!= offset
)
1234 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1235 g_io_channel_error_from_errno (EINVAL
),
1236 g_strerror (EINVAL
));
1237 return G_IO_STATUS_ERROR
;
1240 result
= lseek (win32_channel
->fd
, tmp_offset
, whence
);
1244 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1245 g_io_channel_error_from_errno (errno
),
1246 g_strerror (errno
));
1247 return G_IO_STATUS_ERROR
;
1250 return G_IO_STATUS_NORMAL
;
1254 g_io_win32_fd_close (GIOChannel
*channel
,
1257 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1259 if (win32_channel
->debug
)
1260 g_print ("thread %#x: closing fd %d\n",
1261 win32_channel
->thread_id
,
1263 LOCK (win32_channel
->mutex
);
1264 if (win32_channel
->running
)
1266 if (win32_channel
->debug
)
1267 g_print ("thread %#x: running, marking fd %d for later close\n",
1268 win32_channel
->thread_id
, win32_channel
->fd
);
1269 win32_channel
->running
= FALSE
;
1270 win32_channel
->needs_close
= TRUE
;
1271 if (win32_channel
->direction
== 0)
1272 SetEvent (win32_channel
->data_avail_event
);
1274 SetEvent (win32_channel
->space_avail_event
);
1278 if (win32_channel
->debug
)
1279 g_print ("closing fd %d\n", win32_channel
->fd
);
1280 close (win32_channel
->fd
);
1281 if (win32_channel
->debug
)
1282 g_print ("closed fd %d, setting to -1\n",
1284 win32_channel
->fd
= -1;
1286 UNLOCK (win32_channel
->mutex
);
1288 /* FIXME error detection? */
1290 return G_IO_STATUS_NORMAL
;
1294 g_io_win32_fd_create_watch (GIOChannel
*channel
,
1295 GIOCondition condition
)
1297 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1298 GSource
*source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1299 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
1301 watch
->channel
= channel
;
1302 g_io_channel_ref (channel
);
1304 watch
->condition
= condition
;
1306 if (win32_channel
->data_avail_event
== NULL
)
1307 create_events (win32_channel
);
1309 watch
->pollfd
.fd
= (gint
) win32_channel
->data_avail_event
;
1310 watch
->pollfd
.events
= condition
;
1312 if (win32_channel
->debug
)
1313 g_print ("g_io_win32_fd_create_watch: fd=%d condition={%s} handle=%#x\n",
1314 win32_channel
->fd
, condition_to_string (condition
), watch
->pollfd
.fd
);
1316 LOCK (win32_channel
->mutex
);
1317 if (win32_channel
->thread_id
== 0)
1319 if (condition
& G_IO_IN
)
1320 create_thread (win32_channel
, condition
, read_thread
);
1321 else if (condition
& G_IO_OUT
)
1322 create_thread (win32_channel
, condition
, write_thread
);
1325 g_source_add_poll (source
, &watch
->pollfd
);
1326 UNLOCK (win32_channel
->mutex
);
1332 g_io_win32_sock_read (GIOChannel
*channel
,
1338 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1340 GIOChannelError error
;
1343 if (win32_channel
->debug
)
1344 g_print ("g_io_win32_sock_read: sockfd=%d count=%d\n",
1345 win32_channel
->fd
, count
);
1347 result
= recv (win32_channel
->fd
, buf
, count
, 0);
1348 if (result
== SOCKET_ERROR
)
1349 winsock_error
= WSAGetLastError ();
1351 if (win32_channel
->debug
)
1352 g_print ("g_io_win32_sock_read: recv=%d %s\n",
1354 (result
== SOCKET_ERROR
? winsock_error_message (winsock_error
) : ""));
1356 if (result
== SOCKET_ERROR
)
1360 switch (winsock_error
)
1363 error
= G_IO_CHANNEL_ERROR_INVAL
;
1365 case WSAEWOULDBLOCK
:
1366 return G_IO_STATUS_AGAIN
;
1368 error
= G_IO_CHANNEL_ERROR_FAILED
;
1371 g_set_error (err
, G_IO_CHANNEL_ERROR
, error
,
1372 winsock_error_message (winsock_error
));
1373 return G_IO_STATUS_ERROR
;
1377 *bytes_read
= result
;
1379 return G_IO_STATUS_EOF
;
1381 return G_IO_STATUS_NORMAL
;
1386 g_io_win32_sock_write (GIOChannel
*channel
,
1389 gsize
*bytes_written
,
1392 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1394 GIOChannelError error
;
1397 if (win32_channel
->debug
)
1398 g_print ("g_io_win32_sock_write: sockfd=%d count=%d\n",
1399 win32_channel
->fd
, count
);
1401 result
= send (win32_channel
->fd
, buf
, count
, 0);
1402 if (result
== SOCKET_ERROR
)
1403 winsock_error
= WSAGetLastError ();
1405 if (win32_channel
->debug
)
1406 g_print ("g_io_win32_sock_write: send=%d %s\n",
1408 (result
== SOCKET_ERROR
? winsock_error_message (winsock_error
) : ""));
1410 if (result
== SOCKET_ERROR
)
1414 switch (winsock_error
)
1417 error
= G_IO_CHANNEL_ERROR_INVAL
;
1419 case WSAEWOULDBLOCK
:
1420 win32_channel
->write_would_have_blocked
= TRUE
;
1421 win32_channel
->last_events
= 0;
1422 return G_IO_STATUS_AGAIN
;
1424 error
= G_IO_CHANNEL_ERROR_FAILED
;
1427 g_set_error (err
, G_IO_CHANNEL_ERROR
, error
,
1428 winsock_error_message (winsock_error
));
1430 return G_IO_STATUS_ERROR
;
1434 *bytes_written
= result
;
1435 win32_channel
->write_would_have_blocked
= FALSE
;
1437 return G_IO_STATUS_NORMAL
;
1442 g_io_win32_sock_close (GIOChannel
*channel
,
1445 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1447 if (win32_channel
->fd
!= -1)
1449 if (win32_channel
->debug
)
1450 g_print ("g_io_win32_sock_close: closing socket %d\n",
1453 closesocket (win32_channel
->fd
);
1454 win32_channel
->fd
= -1;
1457 /* FIXME error detection? */
1459 return G_IO_STATUS_NORMAL
;
1463 g_io_win32_sock_create_watch (GIOChannel
*channel
,
1464 GIOCondition condition
)
1466 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1467 GSource
*source
= g_source_new (&g_io_watch_funcs
, sizeof (GIOWin32Watch
));
1468 GIOWin32Watch
*watch
= (GIOWin32Watch
*)source
;
1470 watch
->channel
= channel
;
1471 g_io_channel_ref (channel
);
1473 watch
->condition
= condition
;
1475 if (win32_channel
->event
== 0)
1476 win32_channel
->event
= (int) WSACreateEvent ();
1478 watch
->pollfd
.fd
= win32_channel
->event
;
1479 watch
->pollfd
.events
= condition
;
1481 if (win32_channel
->debug
)
1482 g_print ("g_io_win32_sock_create_watch: sock=%d handle=%#x condition={%s}\n",
1483 win32_channel
->fd
, watch
->pollfd
.fd
,
1484 condition_to_string (watch
->condition
));
1486 g_source_add_poll (source
, &watch
->pollfd
);
1492 g_io_channel_new_file (const gchar
*filename
,
1496 int fid
, flags
, pmode
;
1497 GIOChannel
*channel
;
1499 enum { /* Cheesy hack */
1506 g_return_val_if_fail (filename
!= NULL
, NULL
);
1507 g_return_val_if_fail (mode
!= NULL
, NULL
);
1508 g_return_val_if_fail ((error
== NULL
) || (*error
== NULL
), NULL
);
1522 g_warning ("Invalid GIOFileMode %s.\n", mode
);
1531 if (mode
[2] == '\0')
1533 mode_num
|= MODE_PLUS
;
1538 g_warning ("Invalid GIOFileMode %s.\n", mode
);
1549 flags
= O_WRONLY
| O_TRUNC
| O_CREAT
;
1553 flags
= O_WRONLY
| O_APPEND
| O_CREAT
;
1556 case MODE_R
| MODE_PLUS
:
1558 pmode
= _S_IREAD
| _S_IWRITE
;
1560 case MODE_W
| MODE_PLUS
:
1561 flags
= O_RDWR
| O_TRUNC
| O_CREAT
;
1562 pmode
= _S_IREAD
| _S_IWRITE
;
1564 case MODE_A
| MODE_PLUS
:
1565 flags
= O_RDWR
| O_APPEND
| O_CREAT
;
1566 pmode
= _S_IREAD
| _S_IWRITE
;
1569 g_assert_not_reached ();
1573 /* always open 'untranslated' */
1574 fid
= g_open (filename
, flags
| _O_BINARY
, pmode
);
1576 if (g_io_win32_get_debug_flag ())
1578 g_print ("g_io_channel_win32_new_file: open(\"%s\", ", filename
);
1579 g_win32_print_access_mode (flags
|_O_BINARY
);
1580 g_print (",%#o)=%d\n", pmode
, fid
);
1585 g_set_error (error
, G_FILE_ERROR
,
1586 g_file_error_from_errno (errno
),
1587 g_strerror (errno
));
1588 return (GIOChannel
*)NULL
;
1591 channel
= g_io_channel_win32_new_fd (fid
);
1593 /* XXX: move this to g_io_channel_win32_new_fd () */
1594 channel
->close_on_unref
= TRUE
;
1595 channel
->is_seekable
= TRUE
;
1597 /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
1598 * correspond to actual readability/writeability. Set to FALSE those
1599 * that mode doesn't allow
1604 channel
->is_writeable
= FALSE
;
1608 channel
->is_readable
= FALSE
;
1610 case MODE_R
| MODE_PLUS
:
1611 case MODE_W
| MODE_PLUS
:
1612 case MODE_A
| MODE_PLUS
:
1615 g_assert_not_reached ();
1624 #undef g_io_channel_new_file
1626 /* Binary compatibility version. Not for newly compiled code. */
1629 g_io_channel_new_file (const gchar
*filename
,
1633 gchar
*utf8_filename
= g_locale_to_utf8 (filename
, -1, NULL
, NULL
, error
);
1636 if (utf8_filename
== NULL
)
1639 retval
= g_io_channel_new_file_utf8 (utf8_filename
, mode
, error
);
1641 g_free (utf8_filename
);
1649 g_io_win32_unimpl_set_flags (GIOChannel
*channel
,
1653 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1655 if (win32_channel
->debug
)
1657 g_print ("g_io_win32_unimpl_set_flags: ");
1658 g_win32_print_gioflags (flags
);
1662 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1663 G_IO_CHANNEL_ERROR_FAILED
,
1664 "Not implemented on Win32");
1666 return G_IO_STATUS_ERROR
;
1670 g_io_win32_fd_get_flags_internal (GIOChannel
*channel
,
1673 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*) channel
;
1677 if (st
->st_mode
& _S_IFIFO
)
1679 channel
->is_readable
=
1680 (PeekNamedPipe ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
, NULL
) != 0) || GetLastError () == ERROR_BROKEN_PIPE
;
1681 channel
->is_writeable
=
1682 (WriteFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1683 channel
->is_seekable
= FALSE
;
1685 else if (st
->st_mode
& _S_IFCHR
)
1687 /* XXX Seems there is no way to find out the readability of file
1688 * handles to device files (consoles, mostly) without doing a
1689 * blocking read. So punt, say it's readable.
1691 channel
->is_readable
= TRUE
;
1693 channel
->is_writeable
=
1694 (WriteFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1696 /* XXX What about devices that actually *are* seekable? But
1697 * those would probably not be handled using the C runtime
1698 * anyway, but using Windows-specific code.
1700 channel
->is_seekable
= FALSE
;
1704 channel
->is_readable
=
1705 (ReadFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1706 channel
->is_writeable
=
1707 (WriteFile ((HANDLE
) _get_osfhandle (win32_channel
->fd
), &c
, 0, &count
, NULL
) != 0);
1708 channel
->is_seekable
= TRUE
;
1711 /* XXX: G_IO_FLAG_APPEND */
1712 /* XXX: G_IO_FLAG_NONBLOCK */
1718 g_io_win32_fd_get_flags (GIOChannel
*channel
)
1721 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1723 g_return_val_if_fail (win32_channel
!= NULL
, 0);
1724 g_return_val_if_fail (win32_channel
->type
== G_IO_WIN32_FILE_DESC
, 0);
1726 if (0 == fstat (win32_channel
->fd
, &st
))
1727 return g_io_win32_fd_get_flags_internal (channel
, &st
);
1733 g_io_win32_msg_get_flags (GIOChannel
*channel
)
1739 g_io_win32_sock_set_flags (GIOChannel
*channel
,
1743 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1746 if (win32_channel
->debug
)
1748 g_print ("g_io_win32_sock_set_flags: ");
1749 g_win32_print_gioflags (flags
);
1753 if (flags
& G_IO_FLAG_NONBLOCK
)
1756 if (ioctlsocket (win32_channel
->fd
, FIONBIO
, &arg
) == SOCKET_ERROR
)
1758 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1759 G_IO_CHANNEL_ERROR_FAILED
,
1760 winsock_error_message (WSAGetLastError ()));
1761 return G_IO_STATUS_ERROR
;
1767 if (ioctlsocket (win32_channel
->fd
, FIONBIO
, &arg
) == SOCKET_ERROR
)
1769 g_set_error (err
, G_IO_CHANNEL_ERROR
,
1770 G_IO_CHANNEL_ERROR_FAILED
,
1771 winsock_error_message (WSAGetLastError ()));
1772 return G_IO_STATUS_ERROR
;
1776 return G_IO_STATUS_NORMAL
;
1780 g_io_win32_sock_get_flags (GIOChannel
*channel
)
1782 /* Could we do something here? */
1786 static GIOFuncs win32_channel_msg_funcs
= {
1787 g_io_win32_msg_read
,
1788 g_io_win32_msg_write
,
1790 g_io_win32_msg_close
,
1791 g_io_win32_msg_create_watch
,
1793 g_io_win32_unimpl_set_flags
,
1794 g_io_win32_msg_get_flags
,
1797 static GIOFuncs win32_channel_fd_funcs
= {
1799 g_io_win32_fd_write
,
1801 g_io_win32_fd_close
,
1802 g_io_win32_fd_create_watch
,
1804 g_io_win32_unimpl_set_flags
,
1805 g_io_win32_fd_get_flags
,
1808 static GIOFuncs win32_channel_sock_funcs
= {
1809 g_io_win32_sock_read
,
1810 g_io_win32_sock_write
,
1812 g_io_win32_sock_close
,
1813 g_io_win32_sock_create_watch
,
1815 g_io_win32_sock_set_flags
,
1816 g_io_win32_sock_get_flags
,
1820 g_io_channel_win32_new_messages (guint hwnd
)
1822 GIOWin32Channel
*win32_channel
= g_new (GIOWin32Channel
, 1);
1823 GIOChannel
*channel
= (GIOChannel
*)win32_channel
;
1825 g_io_channel_init (channel
);
1826 g_io_channel_win32_init (win32_channel
);
1827 if (win32_channel
->debug
)
1828 g_print ("g_io_channel_win32_new_messages: hwnd=%#x\n", hwnd
);
1829 channel
->funcs
= &win32_channel_msg_funcs
;
1830 win32_channel
->type
= G_IO_WIN32_WINDOWS_MESSAGES
;
1831 win32_channel
->hwnd
= (HWND
) hwnd
;
1833 /* XXX: check this. */
1834 channel
->is_readable
= IsWindow (win32_channel
->hwnd
);
1835 channel
->is_writeable
= IsWindow (win32_channel
->hwnd
);
1837 channel
->is_seekable
= FALSE
;
1843 g_io_channel_win32_new_fd_internal (gint fd
,
1846 GIOWin32Channel
*win32_channel
;
1847 GIOChannel
*channel
;
1849 win32_channel
= g_new (GIOWin32Channel
, 1);
1850 channel
= (GIOChannel
*)win32_channel
;
1852 g_io_channel_init (channel
);
1853 g_io_channel_win32_init (win32_channel
);
1854 if (win32_channel
->debug
)
1855 g_print ("g_io_channel_win32_new_fd: %u\n", fd
);
1856 channel
->funcs
= &win32_channel_fd_funcs
;
1857 win32_channel
->type
= G_IO_WIN32_FILE_DESC
;
1858 win32_channel
->fd
= fd
;
1860 g_io_win32_fd_get_flags_internal (channel
, st
);
1866 g_io_channel_win32_new_fd (gint fd
)
1870 if (fstat (fd
, &st
) == -1)
1872 g_warning (G_STRLOC
": %d isn't a C library file descriptor", fd
);
1876 return g_io_channel_win32_new_fd_internal (fd
, &st
);
1880 g_io_channel_win32_get_fd (GIOChannel
*channel
)
1882 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1884 return win32_channel
->fd
;
1888 g_io_channel_win32_new_socket (int socket
)
1890 GIOWin32Channel
*win32_channel
= g_new (GIOWin32Channel
, 1);
1891 GIOChannel
*channel
= (GIOChannel
*)win32_channel
;
1893 g_io_channel_init (channel
);
1894 g_io_channel_win32_init (win32_channel
);
1895 if (win32_channel
->debug
)
1896 g_print ("g_io_channel_win32_new_socket: sockfd=%d\n", socket
);
1897 channel
->funcs
= &win32_channel_sock_funcs
;
1898 win32_channel
->type
= G_IO_WIN32_SOCKET
;
1899 win32_channel
->fd
= socket
;
1901 channel
->is_readable
= TRUE
;
1902 channel
->is_writeable
= TRUE
;
1903 channel
->is_seekable
= FALSE
;
1909 g_io_channel_unix_new (gint fd
)
1911 gboolean is_fd
, is_socket
;
1915 is_fd
= (fstat (fd
, &st
) == 0);
1917 optlen
= sizeof (optval
);
1918 is_socket
= (getsockopt (fd
, SOL_SOCKET
, SO_TYPE
, (char *) &optval
, &optlen
) != SOCKET_ERROR
);
1920 if (is_fd
&& is_socket
)
1921 g_warning (G_STRLOC
": %d is both a file descriptor and a socket, file descriptor interpretation assumed.", fd
);
1924 return g_io_channel_win32_new_fd_internal (fd
, &st
);
1927 return g_io_channel_win32_new_socket(fd
);
1929 g_warning (G_STRLOC
": %d is neither a file descriptor or a socket", fd
);
1935 g_io_channel_unix_get_fd (GIOChannel
*channel
)
1937 return g_io_channel_win32_get_fd (channel
);
1941 g_io_channel_win32_set_debug (GIOChannel
*channel
,
1944 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1946 win32_channel
->debug
= flag
;
1950 g_io_channel_win32_poll (GPollFD
*fds
,
1956 g_return_val_if_fail (n_fds
>= 0, 0);
1958 result
= (*g_main_context_get_poll_func (NULL
)) (fds
, n_fds
, timeout
);
1964 g_io_channel_win32_make_pollfd (GIOChannel
*channel
,
1965 GIOCondition condition
,
1968 GIOWin32Channel
*win32_channel
= (GIOWin32Channel
*)channel
;
1970 switch (win32_channel
->type
)
1972 case G_IO_WIN32_FILE_DESC
:
1973 if (win32_channel
->data_avail_event
== NULL
)
1974 create_events (win32_channel
);
1976 fd
->fd
= (gint
) win32_channel
->data_avail_event
;
1978 if (win32_channel
->thread_id
== 0 && (condition
& G_IO_IN
))
1980 if (condition
& G_IO_IN
)
1981 create_thread (win32_channel
, condition
, read_thread
);
1982 else if (condition
& G_IO_OUT
)
1983 create_thread (win32_channel
, condition
, write_thread
);
1987 case G_IO_WIN32_SOCKET
:
1988 fd
->fd
= (int) WSACreateEvent ();
1991 case G_IO_WIN32_WINDOWS_MESSAGES
:
1992 fd
->fd
= G_WIN32_MSG_HANDLE
;
1996 g_assert_not_reached ();
2000 fd
->events
= condition
;
2003 /* Binary compatibility */
2005 g_io_channel_win32_new_stream_socket (int socket
)
2007 return g_io_channel_win32_new_socket (socket
);
2010 #define __G_IO_WIN32_C__
2011 #include "galiasdef.c"