125184Sjkh/* 225184Sjkh * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD 366830Sobrien * All rights reserved. 466830Sobrien * 566830Sobrien * Redistribution and use in source and binary forms, with or without 666830Sobrien * modification, are permitted provided that the following conditions 766830Sobrien * are met: 866830Sobrien * 1. Redistributions of source code must retain the above copyright 966830Sobrien * notice(s), this list of conditions and the following disclaimer as 1066830Sobrien * the first lines of this file unmodified other than the possible 1166830Sobrien * addition of one or more copyright notices. 1266830Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1366830Sobrien * notice(s), this list of conditions and the following disclaimer in 1466830Sobrien * the documentation and/or other materials provided with the 1566830Sobrien * distribution. 1666830Sobrien * 1766830Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 1866830Sobrien * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1966830Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2066830Sobrien * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 2166830Sobrien * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2266830Sobrien * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2366830Sobrien * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2466830Sobrien * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2566830Sobrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 2666830Sobrien * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 2750472Speter * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2825184Sjkh */ 2966830Sobrien 3025184Sjkh#include <sys/cdefs.h> 3151231Ssheldonh__FBSDID("$FreeBSD: releng/11.0/lib/libc/gen/recvmmsg.c 295039 2016-01-29 14:12:12Z kib $"); 3251231Ssheldonh 3325184Sjkh#include <sys/types.h> 3425184Sjkh#include <sys/socket.h> 3525184Sjkh#include <errno.h> 3625184Sjkh#include <poll.h> 3751231Ssheldonh#include <stddef.h> 3825184Sjkh#include "libc_private.h" 3951231Ssheldonh 4025184Sjkhssize_t 4165532Snectarrecvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags, 4265532Snectar const struct timespec *__restrict timeout) 4370108Sdougb{ 4470108Sdougb struct pollfd pfd[1]; 4565532Snectar size_t i, rcvd; 4670108Sdougb ssize_t ret; 4765532Snectar int res; 4870108Sdougb short ev; 4965532Snectar 5065532Snectar if (timeout != NULL) { 5165532Snectar pfd[0].fd = s; 5265532Snectar pfd[0].revents = 0; 5351231Ssheldonh pfd[0].events = ev = POLLIN | POLLRDNORM | POLLRDBAND | 5451231Ssheldonh POLLPRI; 5551231Ssheldonh res = ppoll(&pfd[0], 1, timeout, NULL); 5651231Ssheldonh if (res == -1 || res == 0) 5751231Ssheldonh return (res); 5851231Ssheldonh if (pfd[0].revents & POLLNVAL) { 5925184Sjkh errno = EBADF; 6066745Sdarrenr return (-1); 6166745Sdarrenr } 6266745Sdarrenr if ((pfd[0].revents & ev) == 0) { 6366745Sdarrenr errno = ETIMEDOUT; 6466745Sdarrenr return (-1); 6566745Sdarrenr } 6666745Sdarrenr } 6770129Sdougb 6870129Sdougb ret = __sys_recvmsg(s, &msgvec[0].msg_hdr, flags); 6966745Sdarrenr if (ret == -1) 7066745Sdarrenr return (ret); 7166745Sdarrenr 7270129Sdougb /* 7366745Sdarrenr * Do non-blocking receive for second and later messages if 7466745Sdarrenr * WAITFORONE is set. 7566745Sdarrenr */ 7666745Sdarrenr if (flags & MSG_WAITFORONE) 7766745Sdarrenr flags |= MSG_DONTWAIT; 7866745Sdarrenr 7970129Sdougb rcvd = 1; 8070129Sdougb for (i = rcvd; i < vlen; i++, rcvd++) { 8166745Sdarrenr ret = __sys_recvmsg(s, &msgvec[i].msg_hdr, flags); 8266745Sdarrenr if (ret == -1) { 8366745Sdarrenr /* We have received messages. Let caller know 8466745Sdarrenr * about the data received, socket 8566745Sdarrenr * error is returned on next 8666745Sdarrenr * invocation. 8766745Sdarrenr */ 8866745Sdarrenr return (rcvd); 8966745Sdarrenr } 9066745Sdarrenr 9166745Sdarrenr /* Save received bytes. */ 9266745Sdarrenr msgvec[i].msg_len = ret; 9351231Ssheldonh } 9451231Ssheldonh 9551231Ssheldonh return (rcvd); 9651231Ssheldonh} 9751231Ssheldonh