mirror of https://github.com/mkerrisk/man-pages
250 lines
6.6 KiB
Groff
250 lines
6.6 KiB
Groff
.\" Copyright (c) 2012 by Michael Kerrisk <mtk.manpages@gmail.com>
|
|
.\" with some material from a draft by
|
|
.\" Stephan Mueller <stephan.mueller@atsec.com>
|
|
.\" in turn based on Andi Kleen's recvmmsg.2 page.
|
|
.\"
|
|
.\" %%%LICENSE_START(VERBATIM)
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
.\" preserved on all copies.
|
|
.\"
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
.\" permission notice identical to this one.
|
|
.\"
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
.\" have taken the same level of care in the production of this manual,
|
|
.\" which is licensed free of charge, as they might when working
|
|
.\" professionally.
|
|
.\"
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
.\" %%%LICENSE_END
|
|
.\"
|
|
.TH SENDMMSG 2 2020-06-09 "Linux" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
sendmmsg \- send multiple messages on a socket
|
|
.SH SYNOPSIS
|
|
.nf
|
|
.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
|
|
.BI "#include <sys/socket.h>"
|
|
.PP
|
|
.BI "int sendmmsg(int " sockfd ", struct mmsghdr *" msgvec \
|
|
", unsigned int " vlen ","
|
|
.BI " int " flags ");"
|
|
.fi
|
|
.SH DESCRIPTION
|
|
The
|
|
.BR sendmmsg ()
|
|
system call is an extension of
|
|
.BR sendmsg (2)
|
|
that allows the caller to transmit multiple messages on a socket
|
|
using a single system call.
|
|
(This has performance benefits for some applications.)
|
|
.\" See commit 228e548e602061b08ee8e8966f567c12aa079682
|
|
.PP
|
|
The
|
|
.I sockfd
|
|
argument is the file descriptor of the socket
|
|
on which data is to be transmitted.
|
|
.PP
|
|
The
|
|
.I msgvec
|
|
argument is a pointer to an array of
|
|
.I mmsghdr
|
|
structures.
|
|
The size of this array is specified in
|
|
.IR vlen .
|
|
.PP
|
|
The
|
|
.I mmsghdr
|
|
structure is defined in
|
|
.I <sys/socket.h>
|
|
as:
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
struct mmsghdr {
|
|
struct msghdr msg_hdr; /* Message header */
|
|
unsigned int msg_len; /* Number of bytes transmitted */
|
|
};
|
|
.EE
|
|
.in
|
|
.PP
|
|
The
|
|
.I msg_hdr
|
|
field is a
|
|
.I msghdr
|
|
structure, as described in
|
|
.BR sendmsg (2).
|
|
The
|
|
.I msg_len
|
|
field is used to return the number of bytes sent from the message in
|
|
.IR msg_hdr
|
|
(i.e., the same as the return value from a single
|
|
.BR sendmsg (2)
|
|
call).
|
|
.PP
|
|
The
|
|
.I flags
|
|
argument contains flags ORed together.
|
|
The flags are the same as for
|
|
.BR sendmsg (2).
|
|
.PP
|
|
A blocking
|
|
.BR sendmmsg ()
|
|
call blocks until
|
|
.I vlen
|
|
messages have been sent.
|
|
A nonblocking call sends as many messages as possible
|
|
(up to the limit specified by
|
|
.IR vlen )
|
|
and returns immediately.
|
|
.PP
|
|
On return from
|
|
.BR sendmmsg (),
|
|
the
|
|
.I msg_len
|
|
fields of successive elements of
|
|
.IR msgvec
|
|
are updated to contain the number of bytes transmitted from the corresponding
|
|
.IR msg_hdr .
|
|
The return value of the call indicates the number of elements of
|
|
.I msgvec
|
|
that have been updated.
|
|
.SH RETURN VALUE
|
|
On success,
|
|
.BR sendmmsg ()
|
|
returns the number of messages sent from
|
|
.IR msgvec ;
|
|
if this is less than
|
|
.IR vlen ,
|
|
the caller can retry with a further
|
|
.BR sendmmsg ()
|
|
call to send the remaining messages.
|
|
.PP
|
|
On error, \-1 is returned, and
|
|
.I errno
|
|
is set to indicate the error.
|
|
.SH ERRORS
|
|
Errors are as for
|
|
.BR sendmsg (2).
|
|
An error is returned only if no datagrams could be sent.
|
|
See also BUGS.
|
|
.\" commit 728ffb86f10873aaf4abd26dde691ee40ae731fe
|
|
.\" ... only return an error if no datagrams could be sent.
|
|
.\" If less than the requested number of messages were sent, the application
|
|
.\" must retry starting at the first failed one and if the problem is
|
|
.\" persistent the error will be returned.
|
|
.\"
|
|
.\" This matches the behavior of other syscalls like read/write - it
|
|
.\" is not an error if less than the requested number of elements are sent.
|
|
.SH VERSIONS
|
|
The
|
|
.BR sendmmsg ()
|
|
system call was added in Linux 3.0.
|
|
Support in glibc was added in version 2.14.
|
|
.SH CONFORMING TO
|
|
.BR sendmmsg ()
|
|
is Linux-specific.
|
|
.SH NOTES
|
|
The value specified in
|
|
.I vlen
|
|
is capped to
|
|
.B UIO_MAXIOV
|
|
(1024).
|
|
.\" commit 98382f419f32d2c12d021943b87dea555677144b
|
|
.\" net: Cap number of elements for sendmmsg
|
|
.\"
|
|
.\" To limit the amount of time we can spend in sendmmsg, cap the
|
|
.\" number of elements to UIO_MAXIOV (currently 1024).
|
|
.\"
|
|
.\" For error handling an application using sendmmsg needs to retry at
|
|
.\" the first unsent message, so capping is simpler and requires less
|
|
.\" application logic than returning EINVAL.
|
|
.SH BUGS
|
|
If an error occurs after at least one message has been sent,
|
|
the call succeeds, and returns the number of messages sent.
|
|
The error code is lost.
|
|
The caller can retry the transmission,
|
|
starting at the first failed message, but there is no guarantee that,
|
|
if an error is returned, it will be the same as the one that was lost
|
|
on the previous call.
|
|
.SH EXAMPLES
|
|
The example below uses
|
|
.BR sendmmsg ()
|
|
to send
|
|
.I onetwo
|
|
and
|
|
.I three
|
|
in two distinct UDP datagrams using one system call.
|
|
The contents of the first datagram originates from a pair of buffers.
|
|
.PP
|
|
.EX
|
|
#define _GNU_SOURCE
|
|
#include <netinet/ip.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
int sockfd;
|
|
struct sockaddr_in addr;
|
|
struct mmsghdr msg[2];
|
|
struct iovec msg1[2], msg2;
|
|
int retval;
|
|
|
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (sockfd == \-1) {
|
|
perror("socket()");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
addr.sin_port = htons(1234);
|
|
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) {
|
|
perror("connect()");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
memset(msg1, 0, sizeof(msg1));
|
|
msg1[0].iov_base = "one";
|
|
msg1[0].iov_len = 3;
|
|
msg1[1].iov_base = "two";
|
|
msg1[1].iov_len = 3;
|
|
|
|
memset(&msg2, 0, sizeof(msg2));
|
|
msg2.iov_base = "three";
|
|
msg2.iov_len = 5;
|
|
|
|
memset(msg, 0, sizeof(msg));
|
|
msg[0].msg_hdr.msg_iov = msg1;
|
|
msg[0].msg_hdr.msg_iovlen = 2;
|
|
|
|
msg[1].msg_hdr.msg_iov = &msg2;
|
|
msg[1].msg_hdr.msg_iovlen = 1;
|
|
|
|
retval = sendmmsg(sockfd, msg, 2, 0);
|
|
if (retval == \-1)
|
|
perror("sendmmsg()");
|
|
else
|
|
printf("%d messages sent\en", retval);
|
|
|
|
exit(0);
|
|
}
|
|
.EE
|
|
.SH SEE ALSO
|
|
.BR recvmmsg (2),
|
|
.BR sendmsg (2),
|
|
.BR socket (2),
|
|
.BR socket (7)
|