mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-22 13:25:17 +00:00
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
This commit is contained in:
51
main/utils.c
51
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)
|
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;
|
int res = 0;
|
||||||
struct pollfd fds[1];
|
|
||||||
while (len) {
|
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);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
if (res < 0)
|
|
||||||
|
if (res < 0) {
|
||||||
|
/* It was an acceptable error */
|
||||||
res = 0;
|
res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update how much data we have left to write */
|
||||||
len -= res;
|
len -= res;
|
||||||
s += res;
|
s += res;
|
||||||
res = 0;
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user