From 070a51bf7c00f49bb82d26e889b88906a9b2fd0c Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Thu, 2 Jun 2016 22:10:06 +0300 Subject: Implement internal abstraction for iostreams fopencookie/funclose is a non-standard API and should not be used in portable software. Additionally, the way FILE's fd is used in non-blocking mode is undefined behaviour and cannot be relied on. This introduces internal abstraction for io streams, that allows implementing the desired virtualization of read/write operations with necessary timeout handling. ASTERISK-24515 #close ASTERISK-24517 #close Change-Id: Id916aef418b665ced6a7489aef74908b6e376e85 --- main/utils.c | 62 ------------------------------------------------------------ 1 file changed, 62 deletions(-) (limited to 'main/utils.c') diff --git a/main/utils.c b/main/utils.c index 775fae3af..2c56af3cd 100644 --- a/main/utils.c +++ b/main/utils.c @@ -1462,68 +1462,6 @@ int ast_carefulwrite(int fd, char *s, int len, int timeoutms) return res; } -int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms) -{ - struct timeval start = ast_tvnow(); - int n = 0; - int elapsed = 0; - - while (len) { - if (wait_for_output(fd, timeoutms - elapsed)) { - /* poll returned a fatal error, so bail out immediately. */ - return -1; - } - - /* Clear any errors from a previous write */ - clearerr(f); - - n = fwrite(src, 1, len, f); - - if (ferror(f) && errno != EINTR && errno != EAGAIN) { - /* fatal error from fwrite() */ - if (!feof(f)) { - /* Don't spam the logs if it was just that the connection is closed. */ - ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno)); - } - n = -1; - break; - } - - /* Update for data already written to the socket */ - len -= n; - src += n; - - elapsed = ast_tvdiff_ms(ast_tvnow(), start); - if (elapsed >= timeoutms) { - /* We've taken too long to write - * This is only an error condition if we haven't finished writing. */ - n = len ? -1 : 0; - break; - } - } - - errno = 0; - while (fflush(f)) { - if (errno == EAGAIN || errno == EINTR) { - /* fflush() does not appear to reset errno if it flushes - * and reaches EOF at the same time. It returns EOF with - * the last seen value of errno, causing a possible loop. - * Also usleep() to reduce CPU eating if it does loop */ - errno = 0; - usleep(1); - continue; - } - if (errno && !feof(f)) { - /* Don't spam the logs if it was just that the connection is closed. */ - ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno)); - } - n = -1; - break; - } - - return n < 0 ? -1 : 0; -} - char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes) { char *e; -- cgit v1.2.3