aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-18 21:44:47 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-18 21:44:47 +0000
commit1dd1e401221e5567e6e8a4d956d7b611187b484b (patch)
treeb060cbdf4c25c26ec68a6625c3961b5811308aca /main
parent50bf92cfd8d858ee2805b882615367fd568d69b1 (diff)
Merged revisions 165796 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r165796 | russell | 2008-12-18 15:39:25 -0600 (Thu, 18 Dec 2008) | 11 lines Make ast_carefulwrite() be more careful. This patch handles some additional cases that could result in partial writes to the file description. This was done to address complaints about partial writes on AMI. (issue #13546) (more changes needed to address potential problems in 1.6) Reported by: srt Tested by: russell Review: http://reviewboard.digium.com/r/99/ ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@165801 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/utils.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/main/utils.c b/main/utils.c
index 64a547526..0fb0e0265 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -1074,29 +1074,54 @@ int ast_wait_for_input(int fd, int ms)
*/
int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
{
- /* Try to write string, but wait no more than ms milliseconds
- before timing out */
int res = 0;
- struct pollfd fds[1];
+
while (len) {
+ struct pollfd pfd = {
+ .fd = fd,
+ .events = POLLOUT,
+ };
+
+ /* poll() until the fd is writable without blocking */
+ while ((res = poll(&pfd, 1, timeoutms)) <= 0) {
+ if (res == 0) {
+ /* timed out. */
+ ast_log(LOG_NOTICE, "Timed out trying to write\n");
+ return -1;
+ } else if (res == -1) {
+ /* poll() returned an error, check to see if it was fatal */
+
+ if (errno == EINTR || errno == EAGAIN) {
+ /* This was an acceptable error, go back into poll() */
+ continue;
+ }
+
+ /* Fatal error, bail. */
+ ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
+
+ return -1;
+ }
+ }
+
res = write(fd, s, len);
- if ((res < 0) && (errno != EAGAIN)) {
+
+ if (res < 0 && errno != EAGAIN && errno != EINTR) {
+ /* fatal error from write() */
+ ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
return -1;
}
- if (res < 0)
+
+ if (res < 0) {
+ /* It was an acceptable error */
res = 0;
+ }
+
+ /* Update how much data we have left to write */
len -= res;
s += res;
res = 0;
- if (len) {
- fds[0].fd = fd;
- fds[0].events = POLLOUT;
- /* Wait until writable again */
- res = poll(fds, 1, timeoutms);
- if (res < 1)
- return -1;
- }
}
+
return res;
}