X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgwin32outputstream.c;h=f69212b10ec76a4b889f756987a95d6528a9a20b;hb=e55a953642a9e402f4363f9fa347b6061dd78990;hp=609e4f4239a3e418d89ddcc2cef96aeabd5be120;hpb=d85b722734a6fcfe94032f6113de9e5c190fd7c3;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gwin32outputstream.c b/gio/gwin32outputstream.c index 609e4f4..f69212b 100644 --- a/gio/gwin32outputstream.c +++ b/gio/gwin32outputstream.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: Alexander Larsson * Author: Tor Lillqvist @@ -31,6 +29,7 @@ #include #include "gioerror.h" #include "gwin32outputstream.h" +#include "giowin32-priv.h" #include "gcancellable.h" #include "gsimpleasyncresult.h" #include "gasynchelper.h" @@ -46,9 +45,9 @@ * #GWin32OutputStream implements #GOutputStream for writing to a * Windows file handle. * - * Note that <gio/gwin32outputstream.h> belongs - * to the Windows-specific GIO interfaces, thus you have to use the - * gio-windows-2.0.pc pkg-config file when using it. + * Note that `` belongs to the Windows-specific GIO + * interfaces, thus you have to use the `gio-windows-2.0.pc` pkg-config file + * when using it. */ enum { @@ -57,14 +56,14 @@ enum { PROP_CLOSE_HANDLE }; -G_DEFINE_TYPE (GWin32OutputStream, g_win32_output_stream, G_TYPE_OUTPUT_STREAM); - - struct _GWin32OutputStreamPrivate { HANDLE handle; gboolean close_handle; + gint fd; }; +G_DEFINE_TYPE_WITH_PRIVATE (GWin32OutputStream, g_win32_output_stream, G_TYPE_OUTPUT_STREAM) + static void g_win32_output_stream_set_property (GObject *object, guint prop_id, const GValue *value, @@ -84,22 +83,13 @@ static gboolean g_win32_output_stream_close (GOutputStream *stream static void -g_win32_output_stream_finalize (GObject *object) -{ - G_OBJECT_CLASS (g_win32_output_stream_parent_class)->finalize (object); -} - -static void g_win32_output_stream_class_init (GWin32OutputStreamClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); - g_type_class_add_private (klass, sizeof (GWin32OutputStreamPrivate)); - gobject_class->get_property = g_win32_output_stream_get_property; gobject_class->set_property = g_win32_output_stream_set_property; - gobject_class->finalize = g_win32_output_stream_finalize; stream_class->write_fn = g_win32_output_stream_write; stream_class->close_fn = g_win32_output_stream_close; @@ -184,12 +174,10 @@ g_win32_output_stream_get_property (GObject *object, static void g_win32_output_stream_init (GWin32OutputStream *win32_stream) { - win32_stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (win32_stream, - G_TYPE_WIN32_OUTPUT_STREAM, - GWin32OutputStreamPrivate); - + win32_stream->priv = g_win32_output_stream_get_instance_private (win32_stream); win32_stream->priv->handle = NULL; win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; } /** @@ -253,7 +241,7 @@ g_win32_output_stream_set_close_handle (GWin32OutputStream *stream, * Returns whether the handle of @stream will be closed when the * stream is closed. * - * Return value: %TRUE if the handle is closed when done + * Returns: %TRUE if the handle is closed when done * * Since: 2.26 */ @@ -271,7 +259,7 @@ g_win32_output_stream_get_close_handle (GWin32OutputStream *stream) * * Return the Windows handle that the stream writes to. * - * Return value: The handle descriptor of @stream + * Returns: The handle descriptor of @stream * * Since: 2.26 */ @@ -293,6 +281,8 @@ g_win32_output_stream_write (GOutputStream *stream, GWin32OutputStream *win32_stream; BOOL res; DWORD nbytes, nwritten; + OVERLAPPED overlap = { 0, }; + gssize retval = -1; win32_stream = G_WIN32_OUTPUT_STREAM (stream); @@ -304,24 +294,49 @@ g_win32_output_stream_write (GOutputStream *stream, else nbytes = count; - res = WriteFile (win32_stream->priv->handle, buffer, nbytes, &nwritten, NULL); - if (!res) + overlap.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + g_return_val_if_fail (overlap.hEvent != NULL, -1); + + res = WriteFile (win32_stream->priv->handle, buffer, nbytes, &nwritten, &overlap); + if (res) + retval = nwritten; + else { int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - if (errsv == ERROR_HANDLE_EOF) - return 0; - g_set_error (error, G_IO_ERROR, - g_io_error_from_win32_error (errsv), - _("Error writing to handle: %s"), - emsg); - g_free (emsg); - return -1; + if (errsv == ERROR_IO_PENDING && + _g_win32_overlap_wait_result (win32_stream->priv->handle, + &overlap, &nwritten, cancellable)) + { + retval = nwritten; + goto end; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto end; + + errsv = GetLastError (); + if (errsv == ERROR_HANDLE_EOF || + errsv == ERROR_BROKEN_PIPE) + { + retval = 0; + } + else + { + gchar *emsg; + + emsg = g_win32_error_message (errsv); + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error writing to handle: %s"), + emsg); + g_free (emsg); + } } - return nwritten; +end: + CloseHandle (overlap.hEvent); + return retval; } static gboolean @@ -337,19 +352,44 @@ g_win32_output_stream_close (GOutputStream *stream, if (!win32_stream->priv->close_handle) return TRUE; - res = CloseHandle (win32_stream->priv->handle); - if (!res) + if (win32_stream->priv->fd != -1) { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_set_error (error, G_IO_ERROR, - g_io_error_from_win32_error (errsv), - _("Error closing handle: %s"), - emsg); - g_free (emsg); - return FALSE; + if (close (win32_stream->priv->fd) < 0) + { + g_set_error_literal (error, G_IO_ERROR, + g_io_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + } + else + { + res = CloseHandle (win32_stream->priv->handle); + if (!res) + { + int errsv = GetLastError (); + gchar *emsg = g_win32_error_message (errsv); + + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error closing handle: %s"), + emsg); + g_free (emsg); + return FALSE; + } } return TRUE; } + +GOutputStream * +g_win32_output_stream_new_from_fd (gint fd, + gboolean close_fd) +{ + GWin32OutputStream *win32_stream; + + win32_stream = G_WIN32_OUTPUT_STREAM (g_win32_output_stream_new ((HANDLE) _get_osfhandle (fd), close_fd)); + win32_stream->priv->fd = fd; + + return (GOutputStream*)win32_stream; +}