Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / glib / giowin32.c
blobd5e467e3df926fca4f966b1ca90790d4144c7da4
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
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GLib Team and others 1997-1999. See the AUTHORS
25 * file for a list of people on the GLib Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GLib at ftp://ftp.gtk.org/pub/gtk/.
31 #include "config.h"
32 #include "glib.h"
33 #include <windows.h>
34 #include <winsock.h> /* Not everybody has winsock2 */
35 #include <fcntl.h>
36 #include <io.h>
37 #include <errno.h>
38 #include <sys/types.h>
40 #include <stdio.h>
42 typedef struct _GIOWin32Channel GIOWin32Channel;
43 typedef struct _GIOWin32Watch GIOWin32Watch;
45 guint g_pipe_readable_msg;
47 typedef enum {
48 G_IO_WINDOWS_MESSAGES, /* Windows messages */
49 G_IO_FILE_DESC, /* Unix-like file descriptors from _open*/
50 G_IO_PIPE, /* pipe, with windows messages for signalling */
51 G_IO_STREAM_SOCKET /* Stream sockets */
52 } GIOWin32ChannelType;
54 struct _GIOWin32Channel {
55 GIOChannel channel;
56 gint fd; /* Either a Unix-like file handle as provided
57 * by the Microsoft C runtime, or a SOCKET
58 * as provided by WinSock.
60 GIOWin32ChannelType type;
62 /* This is used by G_IO_WINDOWS_MESSAGES channels */
63 HWND hwnd; /* handle of window, or NULL */
65 /* This is used by G_IO_PIPE channels */
66 guint peer; /* thread id of reader */
67 guint peer_fd; /* fd in the reader */
68 guint offset; /* counter of accumulated bytes */
69 guint need_wakeups; /* in output channels whether the
70 * reader needs wakeups
74 struct _GIOWin32Watch {
75 GPollFD pollfd;
76 GIOChannel *channel;
77 GIOCondition condition;
78 GIOFunc callback;
81 static gboolean g_io_win32_msg_prepare (gpointer source_data,
82 GTimeVal *current_time,
83 gint *timeout);
84 static gboolean g_io_win32_msg_check (gpointer source_data,
85 GTimeVal *current_time);
86 static gboolean g_io_win32_msg_dispatch (gpointer source_data,
87 GTimeVal *current_time,
88 gpointer user_data);
90 static gboolean g_io_win32_fd_prepare (gpointer source_data,
91 GTimeVal *current_time,
92 gint *timeout);
93 static gboolean g_io_win32_fd_check (gpointer source_data,
94 GTimeVal *current_time);
95 static gboolean g_io_win32_fd_dispatch (gpointer source_data,
96 GTimeVal *current_time,
97 gpointer user_data);
99 static gboolean g_io_win32_pipe_prepare (gpointer source_data,
100 GTimeVal *current_time,
101 gint *timeout);
102 static gboolean g_io_win32_pipe_check (gpointer source_data,
103 GTimeVal *current_time);
104 static gboolean g_io_win32_pipe_dispatch (gpointer source_data,
105 GTimeVal *current_time,
106 gpointer user_data);
107 static void g_io_win32_pipe_destroy (gpointer source_data);
109 static gboolean g_io_win32_sock_prepare (gpointer source_data,
110 GTimeVal *current_time,
111 gint *timeout);
112 static gboolean g_io_win32_sock_check (gpointer source_data,
113 GTimeVal *current_time);
114 static gboolean g_io_win32_sock_dispatch (gpointer source_data,
115 GTimeVal *current_time,
116 gpointer user_data);
118 static void g_io_win32_destroy (gpointer source_data);
120 static GIOError g_io_win32_msg_read (GIOChannel *channel,
121 gchar *buf,
122 guint count,
123 guint *bytes_written);
125 static GIOError g_io_win32_msg_write(GIOChannel *channel,
126 gchar *buf,
127 guint count,
128 guint *bytes_written);
129 static GIOError g_io_win32_msg_seek (GIOChannel *channel,
130 gint offset,
131 GSeekType type);
132 static void g_io_win32_msg_close (GIOChannel *channel);
133 static guint g_io_win32_msg_add_watch (GIOChannel *channel,
134 gint priority,
135 GIOCondition condition,
136 GIOFunc func,
137 gpointer user_data,
138 GDestroyNotify notify);
140 static GIOError g_io_win32_fd_read (GIOChannel *channel,
141 gchar *buf,
142 guint count,
143 guint *bytes_written);
144 static GIOError g_io_win32_fd_write(GIOChannel *channel,
145 gchar *buf,
146 guint count,
147 guint *bytes_written);
148 static GIOError g_io_win32_fd_seek (GIOChannel *channel,
149 gint offset,
150 GSeekType type);
151 static void g_io_win32_fd_close (GIOChannel *channel);
153 static void g_io_win32_free (GIOChannel *channel);
155 static guint g_io_win32_fd_add_watch (GIOChannel *channel,
156 gint priority,
157 GIOCondition condition,
158 GIOFunc func,
159 gpointer user_data,
160 GDestroyNotify notify);
162 static GIOError g_io_win32_no_seek (GIOChannel *channel,
163 gint offset,
164 GSeekType type);
166 static GIOError g_io_win32_pipe_read (GIOChannel *channel,
167 gchar *buf,
168 guint count,
169 guint *bytes_written);
170 static GIOError g_io_win32_pipe_write (GIOChannel *channel,
171 gchar *buf,
172 guint count,
173 guint *bytes_written);
174 static void g_io_win32_pipe_close (GIOChannel *channel);
175 static guint g_io_win32_pipe_add_watch (GIOChannel *channel,
176 gint priority,
177 GIOCondition condition,
178 GIOFunc func,
179 gpointer user_data,
180 GDestroyNotify notify);
181 static void g_io_win32_pipe_free (GIOChannel *channel);
183 static GIOError g_io_win32_sock_read (GIOChannel *channel,
184 gchar *buf,
185 guint count,
186 guint *bytes_written);
187 static GIOError g_io_win32_sock_write(GIOChannel *channel,
188 gchar *buf,
189 guint count,
190 guint *bytes_written);
191 static void g_io_win32_sock_close (GIOChannel *channel);
192 static guint g_io_win32_sock_add_watch (GIOChannel *channel,
193 gint priority,
194 GIOCondition condition,
195 GIOFunc func,
196 gpointer user_data,
197 GDestroyNotify notify);
199 GSourceFuncs win32_watch_msg_funcs = {
200 g_io_win32_msg_prepare,
201 g_io_win32_msg_check,
202 g_io_win32_msg_dispatch,
203 g_io_win32_destroy
206 GSourceFuncs win32_watch_fd_funcs = {
207 g_io_win32_fd_prepare,
208 g_io_win32_fd_check,
209 g_io_win32_fd_dispatch,
210 g_io_win32_destroy
213 GSourceFuncs win32_watch_pipe_funcs = {
214 g_io_win32_pipe_prepare,
215 g_io_win32_pipe_check,
216 g_io_win32_pipe_dispatch,
217 g_io_win32_pipe_destroy
220 GSourceFuncs win32_watch_sock_funcs = {
221 g_io_win32_sock_prepare,
222 g_io_win32_sock_check,
223 g_io_win32_sock_dispatch,
224 g_io_win32_destroy
227 GIOFuncs win32_channel_msg_funcs = {
228 g_io_win32_msg_read,
229 g_io_win32_msg_write,
230 g_io_win32_no_seek,
231 g_io_win32_msg_close,
232 g_io_win32_msg_add_watch,
233 g_io_win32_free
236 GIOFuncs win32_channel_fd_funcs = {
237 g_io_win32_fd_read,
238 g_io_win32_fd_write,
239 g_io_win32_fd_seek,
240 g_io_win32_fd_close,
241 g_io_win32_fd_add_watch,
242 g_io_win32_free
245 GIOFuncs win32_channel_pipe_funcs = {
246 g_io_win32_pipe_read,
247 g_io_win32_pipe_write,
248 g_io_win32_no_seek,
249 g_io_win32_pipe_close,
250 g_io_win32_pipe_add_watch,
251 g_io_win32_pipe_free
254 GIOFuncs win32_channel_sock_funcs = {
255 g_io_win32_sock_read,
256 g_io_win32_sock_write,
257 g_io_win32_no_seek,
258 g_io_win32_sock_close,
259 g_io_win32_sock_add_watch,
260 g_io_win32_free
263 #define N_WATCHED_PIPES 4
265 static struct {
266 gint fd;
267 GIOWin32Watch *watch;
268 GIOWin32Channel *channel;
269 gpointer user_data;
270 } watched_pipes[N_WATCHED_PIPES];
272 static gint n_watched_pipes = 0;
274 static gboolean
275 g_io_win32_msg_prepare (gpointer source_data,
276 GTimeVal *current_time,
277 gint *timeout)
279 GIOWin32Watch *data = source_data;
280 GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
281 MSG msg;
283 *timeout = -1;
285 return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
288 static gboolean
289 g_io_win32_msg_check (gpointer source_data,
290 GTimeVal *current_time)
292 GIOWin32Watch *data = source_data;
293 GIOWin32Channel *win32_channel = (GIOWin32Channel *) data->channel;
294 MSG msg;
296 return PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_NOREMOVE) == TRUE;
299 static gboolean
300 g_io_win32_msg_dispatch (gpointer source_data,
301 GTimeVal *current_time,
302 gpointer user_data)
305 GIOWin32Watch *data = source_data;
307 return (*data->callback)(data->channel,
308 data->pollfd.revents & data->condition,
309 user_data);
312 static void
313 g_io_win32_destroy (gpointer source_data)
315 GIOWin32Watch *data = source_data;
317 g_main_remove_poll (&data->pollfd);
318 g_io_channel_unref (data->channel);
319 g_free (data);
322 static gboolean
323 g_io_win32_fd_prepare (gpointer source_data,
324 GTimeVal *current_time,
325 gint *timeout)
327 *timeout = -1;
329 return FALSE;
332 static gboolean
333 g_io_win32_fd_check (gpointer source_data,
334 GTimeVal *current_time)
336 GIOWin32Watch *data = source_data;
338 return (data->pollfd.revents & data->condition);
341 static gboolean
342 g_io_win32_fd_dispatch (gpointer source_data,
343 GTimeVal *current_time,
344 gpointer user_data)
347 GIOWin32Watch *data = source_data;
349 return (*data->callback)(data->channel,
350 data->pollfd.revents & data->condition,
351 user_data);
354 static GIOError
355 g_io_win32_msg_read (GIOChannel *channel,
356 gchar *buf,
357 guint count,
358 guint *bytes_read)
360 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
361 MSG msg; /* In case of alignment problems */
363 if (count < sizeof (MSG))
364 return G_IO_ERROR_INVAL;
366 if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
367 return G_IO_ERROR_AGAIN;
369 memmove (buf, &msg, sizeof (MSG));
370 *bytes_read = sizeof (MSG);
371 return G_IO_ERROR_NONE;
374 static GIOError
375 g_io_win32_msg_write(GIOChannel *channel,
376 gchar *buf,
377 guint count,
378 guint *bytes_written)
380 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
381 MSG msg;
382 gint result;
384 if (count != sizeof (MSG))
385 return G_IO_ERROR_INVAL;
387 /* In case of alignment problems */
388 memmove (&msg, buf, sizeof (MSG));
389 if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
390 return G_IO_ERROR_UNKNOWN;
392 *bytes_written = sizeof (MSG);
393 return G_IO_ERROR_NONE;
396 static GIOError
397 g_io_win32_no_seek (GIOChannel *channel,
398 gint offset,
399 GSeekType type)
401 g_warning ("g_io_win32_no_seek: unseekable IO channel type");
402 return G_IO_ERROR_UNKNOWN;
406 static void
407 g_io_win32_msg_close (GIOChannel *channel)
409 /* Nothing to be done. Or should we set hwnd to some invalid value? */
412 static void
413 g_io_win32_free (GIOChannel *channel)
415 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
417 g_free (win32_channel);
420 static guint
421 g_io_win32_msg_add_watch (GIOChannel *channel,
422 gint priority,
423 GIOCondition condition,
424 GIOFunc func,
425 gpointer user_data,
426 GDestroyNotify notify)
428 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
429 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
431 watch->channel = channel;
432 g_io_channel_ref (channel);
434 watch->callback = func;
435 watch->condition = condition;
437 watch->pollfd.fd = G_WIN32_MSG_HANDLE;
438 watch->pollfd.events = condition;
440 g_main_add_poll (&watch->pollfd, priority);
442 return g_source_add (priority, TRUE, &win32_watch_msg_funcs,
443 watch, user_data, notify);
446 static gboolean
447 g_io_win32_pipe_prepare (gpointer source_data,
448 GTimeVal *current_time,
449 gint *timeout)
451 *timeout = -1;
453 return FALSE;
456 static gboolean
457 g_io_win32_pipe_check (gpointer source_data,
458 GTimeVal *current_time)
460 GIOWin32Watch *data = source_data;
461 return FALSE;
464 static gboolean
465 g_io_win32_pipe_dispatch (gpointer source_data,
466 GTimeVal *current_time,
467 gpointer user_data)
470 GIOWin32Watch *data = source_data;
472 return (*data->callback)(data->channel,
473 data->pollfd.revents & data->condition,
474 user_data);
477 static void
478 g_io_win32_pipe_destroy (gpointer source_data)
480 GIOWin32Watch *data = source_data;
482 g_io_channel_unref (data->channel);
483 g_free (data);
486 static gboolean
487 g_io_win32_sock_prepare (gpointer source_data,
488 GTimeVal *current_time,
489 gint *timeout)
491 *timeout = -1;
493 return FALSE;
496 static gboolean
497 g_io_win32_sock_check (gpointer source_data,
498 GTimeVal *current_time)
500 GIOWin32Watch *data = source_data;
502 return (data->pollfd.revents & data->condition);
505 static gboolean
506 g_io_win32_sock_dispatch (gpointer source_data,
507 GTimeVal *current_time,
508 gpointer user_data)
511 GIOWin32Watch *data = source_data;
513 return (*data->callback)(data->channel,
514 data->pollfd.revents & data->condition,
515 user_data);
518 static GIOError
519 g_io_win32_fd_read (GIOChannel *channel,
520 gchar *buf,
521 guint count,
522 guint *bytes_read)
524 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
525 gint result;
527 result = read (win32_channel->fd, buf, count);
528 if (result < 0)
530 *bytes_read = 0;
531 switch (errno)
533 case EINVAL:
534 return G_IO_ERROR_INVAL;
535 case EAGAIN:
536 return G_IO_ERROR_AGAIN;
537 default:
538 return G_IO_ERROR_UNKNOWN;
541 else
543 *bytes_read = result;
544 return G_IO_ERROR_NONE;
548 static GIOError
549 g_io_win32_fd_write(GIOChannel *channel,
550 gchar *buf,
551 guint count,
552 guint *bytes_written)
554 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
555 gint result;
557 result = write (win32_channel->fd, buf, count);
559 if (result < 0)
561 *bytes_written = 0;
562 switch (errno)
564 case EINVAL:
565 return G_IO_ERROR_INVAL;
566 case EAGAIN:
567 return G_IO_ERROR_AGAIN;
568 default:
569 return G_IO_ERROR_UNKNOWN;
572 else
574 *bytes_written = result;
575 return G_IO_ERROR_NONE;
579 static GIOError
580 g_io_win32_fd_seek (GIOChannel *channel,
581 gint offset,
582 GSeekType type)
584 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
585 int whence;
586 off_t result;
588 switch (type)
590 case G_SEEK_SET:
591 whence = SEEK_SET;
592 break;
593 case G_SEEK_CUR:
594 whence = SEEK_CUR;
595 break;
596 case G_SEEK_END:
597 whence = SEEK_END;
598 break;
599 default:
600 g_warning ("g_io_win32_fd_seek: unknown seek type");
601 return G_IO_ERROR_UNKNOWN;
604 result = lseek (win32_channel->fd, offset, whence);
606 if (result < 0)
608 switch (errno)
610 case EINVAL:
611 return G_IO_ERROR_INVAL;
612 default:
613 return G_IO_ERROR_UNKNOWN;
616 else
617 return G_IO_ERROR_NONE;
620 static void
621 g_io_win32_fd_close (GIOChannel *channel)
623 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
625 close (win32_channel->fd);
626 return;
629 static guint
630 g_io_win32_fd_add_watch (GIOChannel *channel,
631 gint priority,
632 GIOCondition condition,
633 GIOFunc func,
634 gpointer user_data,
635 GDestroyNotify notify)
637 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
638 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
640 watch->channel = channel;
641 g_io_channel_ref (channel);
643 watch->callback = func;
644 watch->condition = condition;
646 /* This probably does not work, except for CONIN$. */
647 watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
648 watch->pollfd.events = condition;
650 g_main_add_poll (&watch->pollfd, priority);
652 return g_source_add (priority, TRUE, &win32_watch_fd_funcs,
653 watch, user_data, notify);
656 static GIOError
657 g_io_win32_pipe_read (GIOChannel *channel,
658 gchar *buf,
659 guint count,
660 guint *bytes_read)
662 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
663 HANDLE handle;
664 DWORD avail;
665 gint result;
667 handle = (HANDLE) _get_osfhandle (win32_channel->fd);
668 if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL))
670 return G_IO_ERROR_UNKNOWN;
673 count = MIN (count, avail);
675 count = MAX (count, 1); /* Must read at least one byte, or
676 * caller will think it's EOF.
678 /* g_print ("g_io_win32_pipe_read: %d %d\n", win32_channel->fd, count); */
679 if (count == 0)
680 result = 0;
681 else
682 result = read (win32_channel->fd, buf, count);
683 if (result < 0)
685 *bytes_read = 0;
686 switch (errno)
688 case EINVAL:
689 return G_IO_ERROR_INVAL;
690 case EAGAIN:
691 return G_IO_ERROR_AGAIN;
692 default:
693 return G_IO_ERROR_UNKNOWN;
696 else
698 *bytes_read = result;
699 win32_channel->offset += result;
700 /* g_print ("=%d (%d)\n", result, win32_channel->offset); */
701 return G_IO_ERROR_NONE;
705 static GIOError
706 g_io_win32_pipe_write(GIOChannel *channel,
707 gchar *buf,
708 guint count,
709 guint *bytes_written)
711 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
712 LONG prevcnt;
713 gint result;
715 /* g_print ("g_io_win32_pipe_write: %d %d\n", win32_channel->fd, count); */
716 result = write (win32_channel->fd, buf, count);
717 if (result < 0)
719 *bytes_written = 0;
720 switch (errno)
722 case EINVAL:
723 return G_IO_ERROR_INVAL;
724 case EAGAIN:
725 return G_IO_ERROR_AGAIN;
726 default:
727 return G_IO_ERROR_UNKNOWN;
730 else
732 if (g_pipe_readable_msg == 0)
733 g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
735 win32_channel->offset += result;
736 /* g_print ("=%d (%d)\n", result, win32_channel->offset); */
737 if (win32_channel->need_wakeups)
739 PostThreadMessage (win32_channel->peer,
740 g_pipe_readable_msg,
741 win32_channel->peer_fd,
742 win32_channel->offset);
744 *bytes_written = result;
745 return G_IO_ERROR_NONE;
749 static void
750 g_io_win32_pipe_close (GIOChannel *channel)
752 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
754 /* g_print ("g_io_win32_pipe_close: %#x %d\n", channel, win32_channel->fd); */
756 close (win32_channel->fd);
757 return;
760 static guint
761 g_io_win32_pipe_add_watch (GIOChannel *channel,
762 gint priority,
763 GIOCondition condition,
764 GIOFunc func,
765 gpointer user_data,
766 GDestroyNotify notify)
768 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
769 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
770 gint i;
772 /* g_print ("g_io_win32_pipe_add_watch: %d\n", win32_channel->fd); */
774 watch->channel = channel;
775 g_io_channel_ref (channel);
777 watch->callback = func;
778 watch->condition = condition;
780 watch->pollfd.fd = win32_channel->fd;
781 watch->pollfd.events = condition;
783 for (i = 0; i < n_watched_pipes; i++)
784 if (watched_pipes[i].fd == -1)
785 break;
786 if (i == N_WATCHED_PIPES)
787 g_error ("Too many watched pipes");
788 else
790 watched_pipes[i].fd = win32_channel->fd;
791 watched_pipes[i].watch = watch;
792 watched_pipes[i].channel = win32_channel;
793 watched_pipes[i].user_data = user_data;
794 n_watched_pipes = MAX (i + 1, n_watched_pipes);
796 return g_source_add (priority, FALSE, &win32_watch_pipe_funcs, watch, user_data, notify);
799 static void
800 g_io_win32_pipe_free (GIOChannel *channel)
802 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
803 gint i;
805 /* g_print ("g_io_win32_pipe_free: %#x %#x\n", channel, channel->channel_data); */
807 for (i = 0; i < n_watched_pipes; i++)
808 if (watched_pipes[i].fd == win32_channel->fd)
810 watched_pipes[i].fd = -1;
811 break;
813 g_io_win32_free (channel);
816 static GIOError
817 g_io_win32_sock_read (GIOChannel *channel,
818 gchar *buf,
819 guint count,
820 guint *bytes_read)
822 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
823 gint result;
825 result = recv (win32_channel->fd, buf, count, 0);
826 if (result == SOCKET_ERROR)
828 *bytes_read = 0;
829 switch (WSAGetLastError ())
831 case WSAEINVAL:
832 return G_IO_ERROR_INVAL;
833 case WSAEWOULDBLOCK:
834 case WSAEINTR:
835 return G_IO_ERROR_AGAIN;
836 default:
837 return G_IO_ERROR_UNKNOWN;
840 else
842 *bytes_read = result;
843 return G_IO_ERROR_NONE;
847 static GIOError
848 g_io_win32_sock_write(GIOChannel *channel,
849 gchar *buf,
850 guint count,
851 guint *bytes_written)
853 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
854 gint result;
856 result = send (win32_channel->fd, buf, count, 0);
858 if (result == SOCKET_ERROR)
860 *bytes_written = 0;
861 switch (WSAGetLastError ())
863 case WSAEINVAL:
864 return G_IO_ERROR_INVAL;
865 case WSAEWOULDBLOCK:
866 case WSAEINTR:
867 return G_IO_ERROR_AGAIN;
868 default:
869 return G_IO_ERROR_UNKNOWN;
872 else
874 *bytes_written = result;
875 return G_IO_ERROR_NONE;
879 static void
880 g_io_win32_sock_close (GIOChannel *channel)
882 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
884 closesocket (win32_channel->fd);
885 return;
888 static guint
889 g_io_win32_sock_add_watch (GIOChannel *channel,
890 gint priority,
891 GIOCondition condition,
892 GIOFunc func,
893 gpointer user_data,
894 GDestroyNotify notify)
896 GIOWin32Watch *watch = g_new (GIOWin32Watch, 1);
897 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
899 watch->channel = channel;
900 g_io_channel_ref (channel);
902 watch->callback = func;
903 watch->condition = condition;
905 watch->pollfd.fd = win32_channel->fd;
906 watch->pollfd.events = condition;
908 g_main_add_poll (&watch->pollfd, priority);
910 return g_source_add (priority, TRUE, &win32_watch_sock_funcs, watch, user_data, notify);
913 GIOChannel *
914 g_io_channel_win32_new_messages (guint hwnd)
916 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
917 GIOChannel *channel = (GIOChannel *) win32_channel;
919 g_io_channel_init (channel);
920 channel->funcs = &win32_channel_msg_funcs;
921 win32_channel->fd = -1;
922 win32_channel->type = G_IO_WINDOWS_MESSAGES;
923 win32_channel->hwnd = (HWND) hwnd;
925 return channel;
928 GIOChannel *
929 g_io_channel_unix_new (gint fd)
931 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
932 GIOChannel *channel = (GIOChannel *) win32_channel;
934 g_io_channel_init (channel);
935 channel->funcs = &win32_channel_fd_funcs;
936 win32_channel->fd = fd;
937 win32_channel->type = G_IO_FILE_DESC;
939 return channel;
942 gint
943 g_io_channel_unix_get_fd (GIOChannel *channel)
945 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
947 return win32_channel->fd;
950 GIOChannel *
951 g_io_channel_win32_new_pipe_with_wakeups (int fd,
952 guint peer,
953 int peer_fd)
955 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
956 GIOChannel *channel = (GIOChannel *) win32_channel;
958 /* g_print ("g_io_channel_win32_new_pipe_with_wakeups %d %#x %d\n", fd, peer, peer_fd); */
960 g_io_channel_init (channel);
961 channel->funcs = &win32_channel_pipe_funcs;
962 win32_channel->fd = fd;
963 win32_channel->type = G_IO_PIPE;
964 win32_channel->peer = peer;
965 win32_channel->peer_fd = peer_fd;
966 win32_channel->offset = 0;
967 win32_channel->need_wakeups = TRUE;
969 return channel;
972 GIOChannel *
973 g_io_channel_win32_new_pipe (int fd)
975 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
976 GIOChannel *channel = (GIOChannel *) win32_channel;
978 g_io_channel_init (channel);
979 channel->funcs = &win32_channel_pipe_funcs;
980 win32_channel->fd = fd;
981 win32_channel->type = G_IO_PIPE;
982 win32_channel->offset = 0;
983 win32_channel->need_wakeups = FALSE;
985 return channel;
988 GIOChannel *
989 g_io_channel_win32_new_stream_socket (int socket)
991 GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
992 GIOChannel *channel = (GIOChannel *) win32_channel;
994 g_io_channel_init (channel);
995 channel->funcs = &win32_channel_sock_funcs;
996 win32_channel->fd = socket;
997 win32_channel->type = G_IO_STREAM_SOCKET;
999 return channel;
1002 gint
1003 g_io_channel_win32_get_fd (GIOChannel *channel)
1005 return g_io_channel_unix_get_fd (channel);
1008 void
1009 g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
1010 guint peer,
1011 int peer_fd)
1013 GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
1015 win32_channel->peer = peer;
1016 win32_channel->peer_fd = peer_fd;
1017 win32_channel->need_wakeups = TRUE;
1020 void
1021 g_io_channel_win32_pipe_readable (gint fd,
1022 guint offset)
1024 gint i;
1026 for (i = 0; i < n_watched_pipes; i++)
1027 if (watched_pipes[i].fd == fd)
1029 if (watched_pipes[i].channel->offset < offset)
1030 (*watched_pipes[i].watch->callback) (watched_pipes[i].watch->channel,
1031 G_IO_IN,
1032 watched_pipes[i].user_data);
1033 break;