mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 23:43:39 +02:00
GUnixInput/OutputStream: fix blocking methods to always block
Previously, if you created a GUnixInputStream or GUnixOutputStream from a non-blocking file descriptor, it might sometimes return G_IO_ERROR_WOULD_BLOCK from g_input_stream_read/g_output_stream_write, which is wrong. Fix that. (Use the GPollableInput/OutputStream methods if you want non-blocking I/O.) Also, add a test for this to gio/tests/unix-streams. Also, fix the GError messages to say "Error reading from file descriptor", etc instead of "Error reading from unix" (which was presumably from a bad search and replace job). https://bugzilla.gnome.org/show_bug.cgi?id=626866
This commit is contained in:
@@ -346,56 +346,64 @@ g_unix_output_stream_write (GOutputStream *stream,
|
||||
GError **error)
|
||||
{
|
||||
GUnixOutputStream *unix_stream;
|
||||
gssize res;
|
||||
gssize res = -1;
|
||||
GPollFD poll_fds[2];
|
||||
int nfds;
|
||||
int poll_ret;
|
||||
|
||||
unix_stream = G_UNIX_OUTPUT_STREAM (stream);
|
||||
|
||||
poll_fds[0].fd = unix_stream->priv->fd;
|
||||
poll_fds[0].events = G_IO_OUT;
|
||||
|
||||
if (unix_stream->priv->is_pipe_or_socket &&
|
||||
g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
|
||||
nfds = 2;
|
||||
else
|
||||
nfds = 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
poll_fds[0].fd = unix_stream->priv->fd;
|
||||
poll_fds[0].events = G_IO_OUT;
|
||||
poll_fds[0].revents = poll_fds[1].revents = 0;
|
||||
do
|
||||
poll_ret = g_poll (poll_fds, 2, -1);
|
||||
poll_ret = g_poll (poll_fds, nfds, -1);
|
||||
while (poll_ret == -1 && errno == EINTR);
|
||||
g_cancellable_release_fd (cancellable);
|
||||
|
||||
|
||||
if (poll_ret == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error writing to unix: %s"),
|
||||
_("Error writing to file descriptor: %s"),
|
||||
g_strerror (errsv));
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
if (!poll_fds[0].revents)
|
||||
continue;
|
||||
|
||||
res = write (unix_stream->priv->fd, buffer, count);
|
||||
if (res == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
|
||||
if (errsv == EINTR)
|
||||
if (errsv == EINTR || errsv == EAGAIN)
|
||||
continue;
|
||||
|
||||
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error writing to unix: %s"),
|
||||
_("Error writing to file descriptor: %s"),
|
||||
g_strerror (errsv));
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
g_cancellable_release_fd (cancellable);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -422,7 +430,7 @@ g_unix_output_stream_close (GOutputStream *stream,
|
||||
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error closing unix: %s"),
|
||||
_("Error closing file descriptor: %s"),
|
||||
g_strerror (errsv));
|
||||
}
|
||||
break;
|
||||
@@ -462,12 +470,12 @@ write_async_cb (int fd,
|
||||
{
|
||||
int errsv = errno;
|
||||
|
||||
if (errsv == EINTR)
|
||||
continue;
|
||||
if (errsv == EINTR || errsv == EAGAIN)
|
||||
return TRUE;
|
||||
|
||||
g_set_error (&error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error writing to unix: %s"),
|
||||
_("Error writing to file descriptor: %s"),
|
||||
g_strerror (errsv));
|
||||
}
|
||||
break;
|
||||
@@ -586,7 +594,7 @@ close_async_cb (CloseAsyncData *data)
|
||||
|
||||
g_set_error (&error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error closing unix: %s"),
|
||||
_("Error closing file descriptor: %s"),
|
||||
g_strerror (errsv));
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user