Merge branch 'writev-max-num-vectors' into 'master'

Clamp number of vectors to IOV_MAX / UIO_MAXIOV for GOutputStream writev()...

See merge request GNOME/glib!874
This commit is contained in:
Sebastian Dröge 2019-05-31 10:04:57 +00:00
commit c1a15894e4
5 changed files with 47 additions and 32 deletions

View File

@ -35,6 +35,23 @@ gboolean g_output_stream_async_close_is_via_threads (GOutputStream *stream);
void g_socket_connection_set_cached_remote_address (GSocketConnection *connection,
GSocketAddress *address);
/* POSIX defines IOV_MAX/UIO_MAXIOV as the maximum number of iovecs that can
* be sent in one go. We define our own version of it here as there are two
* possible names, and also define a fall-back value if none of the constants
* are defined */
#if defined(IOV_MAX)
#define G_IOV_MAX IOV_MAX
#elif defined(UIO_MAXIOV)
#define G_IOV_MAX UIO_MAXIOV
#else
/* 16 is the minimum value required by POSIX */
#define G_IOV_MAX 16
#endif
/* The various functions taking iovecs as parameter use a plain int
* for the number of vectors. Limit it to G_MAXINT for this reason.
*/
G_STATIC_ASSERT (G_IOV_MAX <= G_MAXINT);
G_END_DECLS

View File

@ -42,6 +42,7 @@
#endif
#include "glib-private.h"
#include "gioprivate.h"
#ifdef G_OS_WIN32
#include <io.h>
@ -243,11 +244,11 @@ g_local_file_output_stream_writev (GOutputStream *stream,
if (bytes_written)
*bytes_written = 0;
/* Clamp to G_MAXINT as writev() takes an integer for the number of vectors.
* We handle this like a short write in this case
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (n_vectors > G_MAXINT)
n_vectors = G_MAXINT;
if (n_vectors > G_IOV_MAX)
n_vectors = G_IOV_MAX;
file = G_LOCAL_FILE_OUTPUT_STREAM (stream);

View File

@ -74,6 +74,7 @@
#include "gcredentials.h"
#include "gcredentialsprivate.h"
#include "glibintl.h"
#include "gioprivate.h"
#ifdef G_OS_WIN32
/* For Windows XP runtime compatibility, but use the system's if_nametoindex() if available */
@ -4960,14 +4961,11 @@ g_socket_send_messages_with_timeout (GSocket *socket,
struct mmsghdr *msgvec;
gint i, num_sent;
#ifdef UIO_MAXIOV
#define MAX_NUM_MESSAGES UIO_MAXIOV
#else
#define MAX_NUM_MESSAGES 1024
#endif
if (num_messages > MAX_NUM_MESSAGES)
num_messages = MAX_NUM_MESSAGES;
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (num_messages > G_IOV_MAX)
num_messages = G_IOV_MAX;
msgvec = g_newa (struct mmsghdr, num_messages);
@ -5482,14 +5480,11 @@ g_socket_receive_messages_with_timeout (GSocket *socket,
struct mmsghdr *msgvec;
guint i, num_received;
#ifdef UIO_MAXIOV
#define MAX_NUM_MESSAGES UIO_MAXIOV
#else
#define MAX_NUM_MESSAGES 1024
#endif
if (num_messages > MAX_NUM_MESSAGES)
num_messages = MAX_NUM_MESSAGES;
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (num_messages > G_IOV_MAX)
num_messages = G_IOV_MAX;
msgvec = g_newa (struct mmsghdr, num_messages);

View File

@ -33,6 +33,7 @@
#include "gioerror.h"
#include "glibintl.h"
#include "gfiledescriptorbased.h"
#include "gioprivate.h"
struct _GSocketOutputStreamPrivate
{
@ -146,8 +147,8 @@ g_socket_output_stream_writev (GOutputStream *stream,
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (n_vectors > G_MAXINT)
n_vectors = G_MAXINT;
if (n_vectors > G_IOV_MAX)
n_vectors = G_IOV_MAX;
res = g_socket_send_message_with_timeout (output_stream->priv->socket, NULL,
vectors, n_vectors,
@ -194,8 +195,8 @@ g_socket_output_stream_pollable_writev_nonblocking (GPollableOutputStream *poll
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (n_vectors > G_MAXINT)
n_vectors = G_MAXINT;
if (n_vectors > G_IOV_MAX)
n_vectors = G_IOV_MAX;
return g_socket_send_message_with_timeout (output_stream->priv->socket,
NULL, vectors, n_vectors,

View File

@ -37,6 +37,7 @@
#include "gasynchelper.h"
#include "gfiledescriptorbased.h"
#include "glibintl.h"
#include "gioprivate.h"
/**
@ -425,11 +426,11 @@ g_unix_output_stream_writev (GOutputStream *stream,
if (bytes_written)
*bytes_written = 0;
/* Clamp to G_MAXINT as writev() takes an integer for the number of vectors.
* We handle this like a short write in this case
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (n_vectors > G_MAXINT)
n_vectors = G_MAXINT;
if (n_vectors > G_IOV_MAX)
n_vectors = G_IOV_MAX;
unix_stream = G_UNIX_OUTPUT_STREAM (stream);
@ -635,11 +636,11 @@ g_unix_output_stream_pollable_writev_nonblocking (GPollableOutputStream *stream
return G_POLLABLE_RETURN_WOULD_BLOCK;
}
/* Clamp to G_MAXINT as writev() takes an integer for the number of vectors.
* We handle this like a short write in this case
/* Clamp the number of vectors if more given than we can write in one go.
* The caller has to handle short writes anyway.
*/
if (n_vectors > G_MAXINT)
n_vectors = G_MAXINT;
if (n_vectors > G_IOV_MAX)
n_vectors = G_IOV_MAX;
if (G_OUTPUT_VECTOR_IS_IOVEC)
{