/ncftp-3.2.5/sio/SRecvmsg.c
C | 102 lines | 88 code | 12 blank | 2 comment | 21 complexity | 86424e395425f6e1a464c3d9a4d939b0 MD5 | raw file
Possible License(s): AGPL-3.0
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