00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <string.h>
00032 #include <errno.h>
00033 #include <sys/poll.h>
00034
00035 #include <sys/types.h>
00036 #include <sys/socket.h>
00037 #include <sys/uio.h>
00038
00039 #include "dprint.h"
00040
00041
00042 #define TSEND_INIT \
00043 int n; \
00044 struct pollfd pf; \
00045 pf.fd=fd; \
00046 pf.events=POLLOUT
00047
00048 #define TSEND_POLL(f_name) \
00049 poll_loop: \
00050 while(1){ \
00051 n=poll(&pf, 1, timeout); \
00052 if (n<0){ \
00053 if (errno==EINTR) continue; \
00054 LM_ERR(f_name ": poll failed: %s [%d]\n", \
00055 strerror(errno), errno); \
00056 goto error; \
00057 }else if (n==0){ \
00058 \
00059 LM_ERR(f_name ": send timeout (%d)\n", timeout); \
00060 goto error; \
00061 } \
00062 if (pf.revents&POLLOUT){ \
00063 \
00064 goto again; \
00065 }else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){ \
00066 LM_ERR(f_name ": bad poll flags %x\n", \
00067 pf.revents); \
00068 goto error; \
00069 } \
00070
00071
00072 \
00073 }
00074
00075
00076 #define TSEND_ERR_CHECK(f_name)\
00077 if (n<0){ \
00078 if (errno==EINTR) goto again; \
00079 else if (errno!=EAGAIN && errno!=EWOULDBLOCK){ \
00080 LM_ERR(f_name ": failed to send: (%d) %s\n", \
00081 errno, strerror(errno)); \
00082 goto error; \
00083 }else goto poll_loop; \
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 int tsend_stream(int fd, char* buf, unsigned int len, int timeout)
00095 {
00096 int written;
00097 TSEND_INIT;
00098
00099 written=0;
00100 again:
00101 n=send(fd, buf, len,
00102 #ifdef HAVE_MSG_NOSIGNAL
00103 MSG_NOSIGNAL
00104 #else
00105 0
00106 #endif
00107 );
00108 TSEND_ERR_CHECK("tsend_stream");
00109 written+=n;
00110 if ((unsigned int)n<len){
00111
00112 buf+=n;
00113 len-=n;
00114 }else{
00115
00116 return written;
00117 }
00118 TSEND_POLL("tsend_stream");
00119 error:
00120 return -1;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 int tsend_dgram(int fd, char* buf, unsigned int len,
00132 const struct sockaddr* to, socklen_t tolen, int timeout)
00133 {
00134 TSEND_INIT;
00135 again:
00136 n=sendto(fd, buf, len, 0, to, tolen);
00137 TSEND_ERR_CHECK("tsend_dgram");
00138
00139
00140 return n;
00141 TSEND_POLL("tsend_datagram");
00142 error:
00143 return -1;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 int tsend_dgram_ev(int fd, const struct iovec* v, int count, int timeout)
00154 {
00155 TSEND_INIT;
00156 again:
00157 n=writev(fd, v, count);
00158 TSEND_ERR_CHECK("tsend_datagram_ev");
00159 return n;
00160 TSEND_POLL("tsend_datagram_ev");
00161 error:
00162 return -1;
00163 }
00164