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_set_flags (GIOChannel *channel,
1653 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1655 if (win32_channel->debug)
1657 g_print ("g_io_win32_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_get_flags (GIOChannel *channel)
1741 /* XXX Could do something here. */
1745 static GIOFuncs win32_channel_msg_funcs = {
1746 g_io_win32_msg_read,
1747 g_io_win32_msg_write,
1749 g_io_win32_msg_close,
1750 g_io_win32_msg_create_watch,
1752 g_io_win32_set_flags,
1753 g_io_win32_msg_get_flags,
1756 static GIOFuncs win32_channel_fd_funcs = {
1758 g_io_win32_fd_write,
1760 g_io_win32_fd_close,
1761 g_io_win32_fd_create_watch,
1763 g_io_win32_set_flags,
1764 g_io_win32_fd_get_flags,
1767 static GIOFuncs win32_channel_sock_funcs = {
1768 g_io_win32_sock_read,
1769 g_io_win32_sock_write,
1771 g_io_win32_sock_close,
1772 g_io_win32_sock_create_watch,
1774 g_io_win32_set_flags,
1775 g_io_win32_sock_get_flags,
1779 g_io_channel_win32_new_messages (guint hwnd)
1781 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
1782 GIOChannel *channel = (GIOChannel *)win32_channel;
1784 g_io_channel_init (channel);
1785 g_io_channel_win32_init (win32_channel);
1786 if (win32_channel->debug)
1787 g_print ("g_io_channel_win32_new_messages: hwnd=%#x\n", hwnd);
1788 channel->funcs = &win32_channel_msg_funcs;
1789 win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
1790 win32_channel->hwnd = (HWND) hwnd;
1792 /* XXX: check this. */
1793 channel->is_readable = IsWindow (win32_channel->hwnd);
1794 channel->is_writeable = IsWindow (win32_channel->hwnd);
1796 channel->is_seekable = FALSE;
1802 g_io_channel_win32_new_fd_internal (gint fd,
1805 GIOWin32Channel *win32_channel;
1806 GIOChannel *channel;
1808 win32_channel = g_new (GIOWin32Channel, 1);
1809 channel = (GIOChannel *)win32_channel;
1811 g_io_channel_init (channel);
1812 g_io_channel_win32_init (win32_channel);
1813 if (win32_channel->debug)
1814 g_print ("g_io_channel_win32_new_fd: %u\n", fd);
1815 channel->funcs = &win32_channel_fd_funcs;
1816 win32_channel->type = G_IO_WIN32_FILE_DESC;
1817 win32_channel->fd = fd;
1819 g_io_win32_fd_get_flags_internal (channel, st);
1825 g_io_channel_win32_new_fd (gint fd)
1829 if (fstat (fd, &st) == -1)
1831 g_warning (G_STRLOC ": %d isn't a C library file descriptor", fd);
1835 return g_io_channel_win32_new_fd_internal (fd, &st);
1839 g_io_channel_win32_get_fd (GIOChannel *channel)
1841 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1843 return win32_channel->fd;
1847 g_io_channel_win32_new_socket (int socket)
1849 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
1850 GIOChannel *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_socket: sockfd=%d\n", socket);
1856 channel->funcs = &win32_channel_sock_funcs;
1857 win32_channel->type = G_IO_WIN32_SOCKET;
1858 win32_channel->fd = socket;
1860 channel->is_readable = TRUE;
1861 channel->is_writeable = TRUE;
1862 channel->is_seekable = FALSE;
1868 g_io_channel_unix_new (gint fd)
1870 gboolean is_fd, is_socket;
1874 is_fd = (fstat (fd, &st) == 0);
1876 optlen = sizeof (optval);
1877 is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
1879 if (is_fd && is_socket)
1880 g_warning (G_STRLOC ": %d is both a file descriptor and a socket, file descriptor interpretation assumed.", fd);
1883 return g_io_channel_win32_new_fd_internal (fd, &st);
1886 return g_io_channel_win32_new_socket(fd);
1888 g_warning (G_STRLOC ": %d is neither a file descriptor or a socket", fd);
1894 g_io_channel_unix_get_fd (GIOChannel *channel)
1896 return g_io_channel_win32_get_fd (channel);
1900 g_io_channel_win32_set_debug (GIOChannel *channel,
1903 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1905 win32_channel->debug = flag;
1909 g_io_channel_win32_poll (GPollFD *fds,
1915 g_return_val_if_fail (n_fds >= 0, 0);
1917 result = (*g_main_context_get_poll_func (NULL)) (fds, n_fds, timeout);
1923 g_io_channel_win32_make_pollfd (GIOChannel *channel,
1924 GIOCondition condition,
1927 GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
1929 switch (win32_channel->type)
1931 case G_IO_WIN32_FILE_DESC:
1932 if (win32_channel->data_avail_event == NULL)
1933 create_events (win32_channel);
1935 fd->fd = (gint) win32_channel->data_avail_event;
1937 if (win32_channel->thread_id == 0 && (condition & G_IO_IN))
1939 if (condition & G_IO_IN)
1940 create_thread (win32_channel, condition, read_thread);
1941 else if (condition & G_IO_OUT)
1942 create_thread (win32_channel, condition, write_thread);
1946 case G_IO_WIN32_SOCKET:
1947 fd->fd = (int) WSACreateEvent ();
1950 case G_IO_WIN32_WINDOWS_MESSAGES:
1951 fd->fd = G_WIN32_MSG_HANDLE;
1955 g_assert_not_reached ();
1959 fd->events = condition;
1962 /* Binary compatibility */
1964 g_io_channel_win32_new_stream_socket (int socket)
1966 return g_io_channel_win32_new_socket (socket);
1969 #define __G_IO_WIN32_C__
1970 #include "galiasdef.c"