diff options
author | Russell Bryant <russell@russellbryant.com> | 2008-12-18 21:44:47 +0000 |
---|---|---|
committer | Russell Bryant <russell@russellbryant.com> | 2008-12-18 21:44:47 +0000 |
commit | 1cb4baade2f9a5d9b314d6bf0b2f16a42717f75b (patch) | |
tree | b060cbdf4c25c26ec68a6625c3961b5811308aca /main/utils.c | |
parent | 4e4093ab4855afb55d7a7db17e94f8d2d175febe (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: https://origsvn.digium.com/svn/asterisk/trunk@165801 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/utils.c')
-rw-r--r-- | main/utils.c | 51 |
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; } |