diff --git a/ChangeLog b/ChangeLog index 7372d1abc..891944232 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 7372d1abc..891944232 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 7372d1abc..891944232 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 7372d1abc..891944232 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 7372d1abc..891944232 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 7372d1abc..891944232 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 7372d1abc..891944232 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,46 @@ +2002-12-17 Tor Lillqvist + + Improvement based on suggestion by Thorsten Maerz: + + * glib/giowin32.c (struct _GIOWin32Channel): Don't need thread_handle. + + (create_thread): We can close thread handle right away, it isn't + used for anything. + + (read_thread, select_thread): Thus, don't close it here. + + Fix #57690, partial fix for #57689: + + * glib/giowin32.c (g_io_win32_set_flags): Don't set the GError, + instead call g_warning(). + + (g_io_win32_fd_get_flags_internal): New function, sets the + is_readable, is_writeable and is_seekable flags based on the + actual access modes of the underlying Win32 HANDLE, by trying + Win32 ReadFile() and WriteFile() of zero bytes, and + PeekNamedPipe(). Should work for disk files and pipes. For devices + (consoles) unfortunately not. + + (g_io_win32_fd_get_flags): Don't set the + G_IO_FLAG_IS_{READ,WRITE}ABLE flags, g_io_channel_get_flags() + already does. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_win32_msg_get_flags, g_io_win32_sock_get_flags): Splice the + generic g_io_win32_get_flags() into these specific functions, as + they need to do different things. Not implemented yet, though. + + (g_io_channel_win32_new_fd_internal): New function, to avoid + duplicate fstat() calls. Most code from g_io_channel_win32_new_fd() + moved here. Call g_io_win32_fd_get_flags_internal() to set the + is_* flags. + + (g_io_channel_win32_new_fd, g_io_channel_unix_new): Call + g_io_channel_win32_new_fd_internal(). + + (g_io_win32_no_seek): Remove. Don't set is_seekable for those + channel types. + Mon Dec 16 17:31:50 2002 Owen Taylor * === Released 2.1.5 === diff --git a/glib/giowin32.c b/glib/giowin32.c index 896e8bce5..7d9c0c96d 100644 --- a/glib/giowin32.c +++ b/glib/giowin32.c @@ -87,7 +87,6 @@ struct _GIOWin32Channel { */ guint thread_id; /* If non-NULL has a reader thread, or has * had.*/ - HANDLE thread_handle; HANDLE data_avail_event; gushort revents; @@ -319,8 +318,6 @@ read_thread (void *parameter) * _endthreadex() for us. */ - CloseHandle (channel->thread_handle); - return 0; } @@ -329,12 +326,17 @@ create_thread (GIOWin32Channel *channel, GIOCondition condition, unsigned (__stdcall *thread) (void *parameter)) { - channel->thread_handle = - (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0, - &channel->thread_id); - if (channel->thread_handle == 0) + HANDLE thread_handle; + + thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0, + &channel->thread_id); + if (thread_handle == 0) g_warning (G_STRLOC ": Error creating reader thread: %s", g_strerror (errno)); + else if (!CloseHandle (thread_handle)) + g_warning (G_STRLOC ": Error closing thread handle: %s\n", + g_win32_error_message (GetLastError ())); + WaitForSingleObject (channel->space_avail_event, INFINITE); } @@ -526,8 +528,6 @@ select_thread (void *parameter) * _endthreadex() for us. */ - CloseHandle (channel->thread_handle); - return 0; } @@ -757,17 +757,6 @@ g_io_win32_msg_write (GIOChannel *channel, return G_IO_STATUS_NORMAL; } -static GIOStatus -g_io_win32_no_seek (GIOChannel *channel, - glong offset, - GSeekType type, - GError **err) -{ - g_assert_not_reached (); - - return G_IO_STATUS_ERROR; -} - static GIOStatus g_io_win32_msg_close (GIOChannel *channel, GError **err) @@ -1115,24 +1104,24 @@ g_io_win32_sock_close (GIOChannel *channel, LOCK(win32_channel->mutex); if (win32_channel->running) - { - if (win32_channel->debug) + { + if (win32_channel->debug) g_print ("thread %#x: running, marking for later close\n", win32_channel->thread_id); - win32_channel->running = FALSE; - win32_channel->needs_close = TRUE; - SetEvent(win32_channel->data_avail_noticed_event); - } + win32_channel->running = FALSE; + win32_channel->needs_close = TRUE; + SetEvent(win32_channel->data_avail_noticed_event); + } if (win32_channel->fd != -1) - { - if (win32_channel->debug) - g_print ("thread %#x: closing socket %d\n", - win32_channel->thread_id, - win32_channel->fd); - - closesocket (win32_channel->fd); - win32_channel->fd = -1; - } + { + if (win32_channel->debug) + g_print ("thread %#x: closing socket %d\n", + win32_channel->thread_id, + win32_channel->fd); + + closesocket (win32_channel->fd); + win32_channel->fd = -1; + } UNLOCK(win32_channel->mutex); /* FIXME error detection? */ @@ -1178,7 +1167,7 @@ g_io_channel_new_file (const gchar *filename, mode_num = MODE_A; break; default: - g_warning (G_STRLOC ": Invalid GIOFileMode %s.\n", mode); + g_warning ("Invalid GIOFileMode %s.\n", mode); return NULL; } @@ -1194,7 +1183,7 @@ g_io_channel_new_file (const gchar *filename, } /* Fall through */ default: - g_warning (G_STRLOC ": Invalid GIOFileMode %s.\n", mode); + g_warning ("Invalid GIOFileMode %s.\n", mode); return NULL; } @@ -1254,22 +1243,22 @@ g_io_channel_new_file (const gchar *filename, channel->close_on_unref = TRUE; channel->is_seekable = TRUE; + /* g_io_channel_win32_new_fd sets is_readable and is_writeable to + * correspond to actual readability/writeability. Set to FALSE those + * that mode doesn't allow + */ switch (mode_num) { case MODE_R: - channel->is_readable = TRUE; channel->is_writeable = FALSE; break; case MODE_W: case MODE_A: channel->is_readable = FALSE; - channel->is_writeable = TRUE; break; case MODE_R | MODE_PLUS: case MODE_W | MODE_PLUS: case MODE_A | MODE_PLUS: - channel->is_readable = TRUE; - channel->is_writeable = TRUE; break; default: g_assert_not_reached (); @@ -1279,9 +1268,9 @@ g_io_channel_new_file (const gchar *filename, } static GIOStatus -g_io_win32_set_flags (GIOChannel *channel, - GIOFlags flags, - GError **err) +g_io_win32_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **err) { GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; @@ -1292,60 +1281,95 @@ g_io_win32_set_flags (GIOChannel *channel, g_print ("\n"); } - g_set_error (err, - G_IO_CHANNEL_ERROR, - g_file_error_from_errno (EACCES), - _("Channel set flags unsupported")); - return G_IO_STATUS_ERROR; + g_warning ("g_io_win32_set_flags () not implemented.\n"); + + return G_IO_STATUS_NORMAL; } static GIOFlags -g_io_win32_fd_get_flags (GIOChannel *channel) +g_io_win32_fd_get_flags_internal (GIOChannel *channel, + struct stat *st) { - GIOFlags flags = 0; - struct _stat st; + GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; + gchar c; + DWORD count; + + if (st->st_mode & _S_IFIFO) + { + channel->is_readable = + (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) == 0); + channel->is_writeable = + (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) == 0); + channel->is_seekable = FALSE; + } + else if (st->st_mode & _S_IFCHR) + { + /* XXX Seems there is no way to find out the readability of file + * handles to device files (consoles, mostly) without doing a + * blocking read. So punt, use st->st_mode. + */ + channel->is_readable = !!(st->st_mode & _S_IREAD); + + channel->is_writeable = + (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) == 0); + + /* XXX What about devices that actually *are* seekable? But those would probably + * not be handled using the C runtime anyway, but using Windows-specific code. + */ + channel->is_seekable = FALSE; + } + else + { + channel->is_readable = + (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) == 0); + channel->is_writeable = + (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) == 0); + channel->is_seekable = TRUE; + } + + /* XXX: G_IO_FLAG_APPEND */ + /* XXX: G_IO_FLAG_NONBLOCK */ + + return 0; +} + +static GIOFlags +g_io_win32_fd_get_flags (GIOChannel *channel) +{ + struct stat st; GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; g_return_val_if_fail (win32_channel != NULL, 0); g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0); - if (0 == _fstat (win32_channel->fd, &st)) - { - /* XXX: G_IO_FLAG_APPEND */ - /* XXX: G_IO_FLAG_NONBLOCK */ - if (st.st_mode & _S_IREAD) flags |= G_IO_FLAG_IS_READABLE; - if (st.st_mode & _S_IWRITE) flags |= G_IO_FLAG_IS_WRITEABLE; - /* XXX: */ - if (!(st.st_mode & _S_IFIFO)) flags |= G_IO_FLAG_IS_SEEKABLE; - } - - return flags; + if (0 == fstat (win32_channel->fd, &st)) + return g_io_win32_fd_get_flags_internal (channel, &st); + else + return 0; } -/* - * Generic implementation, just translating createion flags - */ static GIOFlags -g_io_win32_get_flags (GIOChannel *channel) +g_io_win32_msg_get_flags (GIOChannel *channel) { - GIOFlags flags; + return 0; +} - flags = (channel->is_readable ? G_IO_FLAG_IS_READABLE : 0) - | (channel->is_writeable ? G_IO_FLAG_IS_READABLE : 0) - | (channel->is_seekable ? G_IO_FLAG_IS_SEEKABLE : 0); - - return flags; +static GIOFlags +g_io_win32_sock_get_flags (GIOChannel *channel) +{ + /* XXX Could do something here. */ + return 0; } static GIOFuncs win32_channel_msg_funcs = { g_io_win32_msg_read, g_io_win32_msg_write, - g_io_win32_no_seek, + NULL, g_io_win32_msg_close, g_io_win32_msg_create_watch, g_io_win32_free, g_io_win32_set_flags, - g_io_win32_get_flags, + g_io_win32_msg_get_flags, }; static GIOFuncs win32_channel_fd_funcs = { @@ -1362,12 +1386,12 @@ static GIOFuncs win32_channel_fd_funcs = { static GIOFuncs win32_channel_sock_funcs = { g_io_win32_sock_read, g_io_win32_sock_write, - g_io_win32_no_seek, + NULL, g_io_win32_sock_close, g_io_win32_sock_create_watch, g_io_win32_free, g_io_win32_set_flags, - g_io_win32_get_flags, + g_io_win32_sock_get_flags, }; GIOChannel * @@ -1393,18 +1417,12 @@ g_io_channel_win32_new_messages (guint hwnd) return channel; } -GIOChannel * -g_io_channel_win32_new_fd (gint fd) +static GIOChannel * +g_io_channel_win32_new_fd_internal (gint fd, + struct stat *st) { GIOWin32Channel *win32_channel; GIOChannel *channel; - struct stat st; - - if (fstat (fd, &st) == -1) - { - g_warning (G_STRLOC ": %d isn't a (emulated) file descriptor", fd); - return NULL; - } win32_channel = g_new (GIOWin32Channel, 1); channel = (GIOChannel *)win32_channel; @@ -1417,27 +1435,25 @@ g_io_channel_win32_new_fd (gint fd) win32_channel->type = G_IO_WIN32_FILE_DESC; win32_channel->fd = fd; - - /* fstat doesn't deliver senseful values, but - * fcntl isn't available, so guess ... - */ - if (st.st_mode & _S_IFIFO) - { - channel->is_readable = TRUE; - channel->is_writeable = TRUE; - channel->is_seekable = FALSE; - } - else - { - channel->is_readable = !!(st.st_mode & _S_IREAD); - channel->is_writeable = !!(st.st_mode & _S_IWRITE); - /* XXX What about "device files" (COM1: and the like) */ - channel->is_seekable = TRUE; - } - + g_io_win32_fd_get_flags_internal (channel, st); + return channel; } +GIOChannel * +g_io_channel_win32_new_fd (gint fd) +{ + struct stat st; + + if (fstat (fd, &st) == -1) + { + g_warning (G_STRLOC ": %d isn't a C library file descriptor", fd); + return NULL; + } + + return g_io_channel_win32_new_fd_internal (fd, &st); +} + gint g_io_channel_win32_get_fd (GIOChannel *channel) { @@ -1463,6 +1479,7 @@ g_io_channel_win32_new_socket (int socket) /* XXX: check this */ channel->is_readable = TRUE; channel->is_writeable = TRUE; + channel->is_seekable = FALSE; return channel; @@ -1474,7 +1491,7 @@ g_io_channel_unix_new (gint fd) struct stat st; if (fstat (fd, &st) == 0) - return g_io_channel_win32_new_fd (fd); + return g_io_channel_win32_new_fd_internal (fd, &st); if (getsockopt (fd, SOL_SOCKET, SO_TYPE, NULL, NULL) != SO_ERROR) return g_io_channel_win32_new_socket(fd);