1#include "syshdrs.h"
2#ifdef PRAGMA_HDRSTOP
3#	pragma hdrstop
4#endif
5
6#ifndef HAVE_RECVMSG
7int
8SRecvmsg(int UNUSED(sfd), void *const UNUSED(msg), int UNUSED(fl), int UNUSED(tlen))
9{
10	LIBSIO_USE_VAR(sfd);
11	LIBSIO_USE_VAR(msg);
12	LIBSIO_USE_VAR(fl);
13	LIBSIO_USE_VAR(tlen);
14#	ifdef ENOSYS
15	errno = ENOSYS;
16#	endif
17	return (-1);
18}
19
20
21#else
22
23int
24SRecvmsg(int sfd, void *const msg, int fl, int tlen)
25{
26	recv_return_t nread;
27	int tleft;
28	time_t done, now;
29	fd_set ss;
30	struct timeval tv;
31	int result;
32	DECL_SIGPIPE_VARS
33
34	if (msg == NULL) {
35		errno = EINVAL;
36		return (-1);
37	}
38
39	if (tlen <= 0) {
40		errno = 0;
41		for (;;) {
42			nread = recvmsg(sfd, (struct msghdr *) msg, fl);
43			if ((nread >= 0) || (errno != EINTR))
44				return ((int) nread);
45		}
46	}
47
48	time(&now);
49	done = now + tlen;
50	tleft = (done > now) ? ((int) (done - now)) : 0;
51	forever {
52
53		for (;;) {
54			errno = 0;
55			MY_FD_ZERO(&ss);
56#if defined(__DECC) || defined(__DECCXX)
57#pragma message save
58#pragma message disable trunclongint
59#endif
60			MY_FD_SET(sfd, &ss);
61#if defined(__DECC) || defined(__DECCXX)
62#pragma message restore
63#endif
64			tv.tv_sec = (tv_sec_t) tleft;
65			tv.tv_usec = 0;
66			result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv);
67			if (result >= 1) {
68				/* ready */
69				break;
70			} else if (result == 0) {
71				/* timeout */
72				errno = ETIMEDOUT;
73				SETWSATIMEOUTERR
74				return (kTimeoutErr);
75			} else if (errno != EINTR) {
76				return (-1);
77			}
78		}
79
80		IGNORE_SIGPIPE
81		nread = recvmsg(sfd, (struct msghdr *) msg, fl);
82		RESTORE_SIGPIPE
83
84		if (nread >= 0)
85			break;
86		if (errno != EINTR)
87			break;		/* Fatal error. */
88		errno = 0;
89		time(&now);
90		tleft = (done > now) ? ((int) (done - now)) : 0;
91		if (tleft < 1) {
92			nread = kTimeoutErr;
93			errno = ETIMEDOUT;
94			SETWSATIMEOUTERR
95			break;
96		}
97	}
98
99	return ((int) nread);
100}	/* SRecvmsg */
101
102#endif
103