- gchar *emsg;
-
- if (errsv == ERROR_HANDLE_EOF ||
- errsv == ERROR_BROKEN_PIPE)
- return 0;
-
- emsg = g_win32_error_message (errsv);
- g_set_error (error, G_IO_ERROR,
- g_io_error_from_win32_error (errsv),
- _("Error reading from handle: %s"),
- emsg);
- g_free (emsg);
- return -1;
+
+ if (errsv == ERROR_IO_PENDING &&
+ _g_win32_overlap_wait_result (win32_stream->priv->handle,
+ &overlap, &nread, cancellable))
+ {
+ retval = nread;
+ goto end;
+ }
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ goto end;
+
+ errsv = GetLastError ();
+ if (errsv == ERROR_MORE_DATA)
+ {
+ /* If a named pipe is being read in message mode and the
+ * next message is longer than the nNumberOfBytesToRead
+ * parameter specifies, ReadFile returns FALSE and
+ * GetLastError returns ERROR_MORE_DATA */
+ retval = nread;
+ goto end;
+ }
+ else if (errsv == ERROR_HANDLE_EOF ||
+ errsv == ERROR_BROKEN_PIPE)
+ {
+ /* TODO: the other end of a pipe may call the WriteFile
+ * function with nNumberOfBytesToWrite set to zero. In this
+ * case, it's not possible for the caller to know if it's
+ * broken pipe or a read of 0. Perhaps we should add a
+ * is_broken flag for this win32 case.. */
+ 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 reading from handle: %s"),
+ emsg);
+ g_free (emsg);
+ }