Browse code

- added tsend_dgram_ev (== writev+timeout) - changed parameter order for tsend_dgram

Andrei Pelinescu-Onciul authored on 03/03/2004 11:13:25
Showing 2 changed files
... ...
@@ -30,6 +30,7 @@
30 30
  * History:
31 31
  * --------
32 32
  *  2004-02-26  created by andrei
33
+ *  2003-03-03  switched to heavy macro use, added tsend_dgram_ev (andrei) 
33 34
  */
34 35
 
35 36
 #include <string.h>
... ...
@@ -38,9 +39,56 @@
38 38
 
39 39
 #include <sys/types.h>
40 40
 #include <sys/socket.h>
41
+#include <sys/uio.h>
41 42
 
42 43
 #include "dprint.h"
43 44
 
45
+/* the functions below are very similar => some generic macros */
46
+#define TSEND_INIT \
47
+	int n; \
48
+	struct pollfd pf; \
49
+	pf.fd=fd; \
50
+	pf.events=POLLOUT
51
+
52
+#define TSEND_POLL(f_name) \
53
+poll_loop: \
54
+	while(1){ \
55
+		n=poll(&pf, 1, timeout); \
56
+		if (n<0){ \
57
+			if (errno==EINTR) continue; /* signal, ignore */ \
58
+			LOG(L_ERR, "ERROR: " f_name ": poll failed: %s [%d]\n", \
59
+					strerror(errno), errno); \
60
+			goto error; \
61
+		}else if (n==0){ \
62
+			/* timeout */ \
63
+			LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout); \
64
+			goto error; \
65
+		} \
66
+		if (pf.revents&POLLOUT){ \
67
+			/* we can write again */ \
68
+			goto again; \
69
+		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){ \
70
+			LOG(L_ERR, "ERROR: " f_name ": bad poll flags %x\n", \
71
+					pf.revents); \
72
+			goto error; \
73
+		} \
74
+		/* if POLLIN or POLLPRI or other non-harmfull events happened,    \
75
+		 * continue ( although poll should never signal them since we're  \
76
+		 * not interested in them => we should never reach this point) */ \
77
+	} 
78
+
79
+
80
+#define TSEND_ERR_CHECK(f_name)\
81
+	if (n<0){ \
82
+		if (errno==EINTR) goto again; \
83
+		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){ \
84
+			LOG(L_ERR, "ERROR: " f_name ": failed to send: (%d) %s\n", \
85
+					errno, strerror(errno)); \
86
+			goto error; \
87
+		}else goto poll_loop; \
88
+	}
89
+	
90
+
44 91
 
45 92
 /* sends on fd (which must be O_NONBLOCK); if it cannot send any data
46 93
  * in timeout miliseconds it will return ERROR
... ...
@@ -50,17 +98,10 @@
50 50
  */
51 51
 int tsend_stream(int fd, char* buf, unsigned int len, int timeout)
52 52
 {
53
-	int n;
54 53
 	int written;
55
-	int initial_len;
56
-	struct pollfd pf;
54
+	TSEND_INIT;
57 55
 	
58 56
 	written=0;
59
-	initial_len=len;
60
-	pf.fd=fd;
61
-	pf.events=POLLOUT;
62
-	
63
-	
64 57
 again:
65 58
 	n=send(fd, buf, len,
66 59
 #ifdef HAVE_MSG_NOSIGNAL
... ...
@@ -69,121 +110,61 @@ again:
69 69
 			0
70 70
 #endif
71 71
 		);
72
-	if (n<0){
73
-		if (errno==EINTR) goto again;
74
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
75
-			LOG(L_ERR, "ERROR: tsend_stream: failed to send: (%d) %s\n",
76
-						errno, strerror(errno));
77
-			goto error;
78
-		}
79
-	}
80
-	written+=n;
81
-	if (n<len){
82
-		/* partial write */
83
-		buf+=n;
84
-		len-=n;
85
-	}else{
86
-		/* succesfull full write */
87
-		goto end;
88
-	}
89
-	while(1){
90
-		n=poll(&pf, 1, timeout);
91
-		if (n<0){
92
-			if (errno==EINTR) continue; /* signal, ignore */
93
-			LOG(L_ERR, "ERROR: tsend_stream: poll failed: %s [%d]\n",
94
-					strerror(errno), errno);
95
-			goto error;
96
-		}else if (n==0){
97
-			/* timeout */
98
-			LOG(L_ERR, "ERROR: tsend_stream: send timeout (%d)\n", timeout);
99
-			goto error;
100
-		}
101
-		if (pf.revents&POLLOUT){
102
-			/* we can write again */
103
-			goto again;
104
-		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
105
-			LOG(L_ERR, "ERROR: tsend_stream: bad poll flags %x\n", 
106
-					pf.revents);
107
-			goto error;
108
-		}
109
-		/* if POLLIN or POLLPRI or other non-harmfull events happened,
110
-		 * continue ( although poll should never signal them since we're
111
-		 * not interested in them => we should never reach this point) */
72
+	TSEND_ERR_CHECK("tsend_stream");
73
+	written+=n; 
74
+	if (n<len){ 
75
+		/* partial write */ 
76
+		buf+=n; 
77
+		len-=n; 
78
+	}else{ 
79
+		/* succesfull full write */ 
80
+		return written;
112 81
 	}
82
+	TSEND_POLL("tsend_stream");
113 83
 error:
114 84
 	return -1;
115
-end:
116
-	return written;
117 85
 }
118 86
 
119 87
 
120 88
 
121
-/* sends on dram fd (which must be O_NONBLOCK); if it cannot send any data
89
+/* sends on dgram fd (which must be O_NONBLOCK); if it cannot send any data
122 90
  * in timeout miliseconds it will return ERROR
123 91
  * returns: -1 on error, or number of bytes written
124 92
  *  (if less than len => couldn't send all)
125 93
  *  bugs: signals will reset the timer
126 94
  */
127
-int tsend_dgram(int fd, char* buf, unsigned int len, int timeout,
128
-				const struct sockaddr* to, socklen_t tolen)
95
+int tsend_dgram(int fd, char* buf, unsigned int len, 
96
+				const struct sockaddr* to, socklen_t tolen, int timeout)
129 97
 {
130
-	int n;
131
-	int written;
132
-	int initial_len;
133
-	struct pollfd pf;
134
-	
135
-	written=0;
136
-	initial_len=len;
137
-	pf.fd=fd;
138
-	pf.events=POLLOUT;
139
-	
98
+	TSEND_INIT;
140 99
 again:
141 100
 	n=sendto(fd, buf, len, 0, to, tolen);
142
-	if (n<0){
143
-		if (errno==EINTR) goto again;
144
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
145
-			LOG(L_ERR, "ERROR: tsend_dgram: failed to send: (%d) %s\n",
146
-						errno, strerror(errno));
147
-			goto error;
148
-		}
149
-	}
150
-	written+=n;
151
-	if (n<len){
152
-		/* partial write */
153
-		LOG(L_CRIT, "BUG: tsend_dgram: partial write on datagram socket\n");
154
-		goto error;
155
-	}else{
156
-		/* succesfull full write */
157
-		goto end;
158
-	}
159
-	while(1){
160
-		n=poll(&pf, 1, timeout);
161
-		if (n<0){
162
-			if (errno==EINTR) continue; /* signal, ignore */
163
-			LOG(L_ERR, "ERROR: tsend_dgram: poll failed: %s [%d]\n",
164
-					strerror(errno), errno);
165
-			goto error;
166
-		}else if (n==0){
167
-			/* timeout */
168
-			LOG(L_ERR, "ERROR: tsend_dgram: send timeout (%d)\n", timeout);
169
-			goto error;
170
-		}
171
-		if (pf.revents&POLLOUT){
172
-			/* we can write again */
173
-			goto again;
174
-		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
175
-			LOG(L_ERR, "ERROR: tsend_dgram: bad poll flags %x\n", 
176
-					pf.revents);
177
-			goto error;
178
-		}
179
-		/* if POLLIN or POLLPRI or other non-harmfull events happened,
180
-		 * continue ( although poll should never signal them since we're
181
-		 * not interested in them => we should never reach this point) */
182
-	}
101
+	TSEND_ERR_CHECK("tsend_dgram");
102
+	/* we don't care about partial writes: they shouln't happen on 
103
+	 * a datagram socket */
104
+	return n;
105
+	TSEND_POLL("tsend_datagram");
183 106
 error:
184 107
 	return -1;
185
-end:
186
-	return written;
187 108
 }
188 109
 
189 110
 	
111
+/* sends on connected datagram fd (which must be O_NONBLOCK); 
112
+ * if it cannot send any data in timeout miliseconds it will return ERROR
113
+ * returns: -1 on error, or number of bytes written
114
+ *  (if less than len => couldn't send all)
115
+ *  bugs: signals will reset the timer
116
+ */
117
+
118
+int tsend_dgram_ev(int fd, const struct iovec* v, int count, int timeout)
119
+{
120
+	TSEND_INIT;
121
+again:
122
+	n=writev(fd, v, count);
123
+	TSEND_ERR_CHECK("tsend_datagram_ev");
124
+	return n;
125
+	TSEND_POLL("tsend_datagram_ev");
126
+error:
127
+	return -1;
128
+}
129
+
... ...
@@ -35,8 +35,9 @@
35 35
 
36 36
 
37 37
 int tsend_stream(int fd, char* buf, unsigned int len, int timeout);
38
-int tsend_dgram(int fd, char* buf, unsigned int len, int timeout,
39
-				const struct sockaddr* to, socklen_t tolen);
38
+int tsend_dgram(int fd, char* buf, unsigned int len, 
39
+				const struct sockaddr* to, socklen_t tolen, int timeout);
40
+int tsend_dgram_ev(int fd, const struct iovec* v, int count, int timeout);
40 41
 
41 42
 
42 43