diff options
author | Jenkins2 <jenkins2@gerrit.asterisk.org> | 2017-12-22 07:26:22 -0600 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-12-22 07:26:22 -0600 |
commit | 29b10b42bbf0541f938ef7fe266ccb5b1de53de2 (patch) | |
tree | a3e66ae1ce8cc82b9300ac40f21f5ca8be7de865 | |
parent | d85290ca48c3d95cbf464967b83f06c118dc0010 (diff) | |
parent | 719e8eee03e8d62c20c8378a8324778fcaa19788 (diff) |
Merge "app_voicemail: Fix file copy error handling." into 13
-rw-r--r-- | apps/app_voicemail.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 229c00d9e..1e0ccdf2d 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -4630,49 +4630,56 @@ static int copy(char *infile, char *outfile) { int ifd; int ofd; - int res; + int res = -1; int len; char buf[4096]; #ifdef HARDLINK_WHEN_POSSIBLE /* Hard link if possible; saves disk space & is faster */ - if (link(infile, outfile)) { + if (!link(infile, outfile)) { + return 0; + } #endif - if ((ifd = open(infile, O_RDONLY)) < 0) { - ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); - return -1; + + if ((ifd = open(infile, O_RDONLY)) < 0) { + ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); + return -1; + } + + if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { + ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); + close(ifd); + return -1; + } + + for (;;) { + int wrlen; + + len = read(ifd, buf, sizeof(buf)); + if (!len) { + res = 0; + break; } - if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { - ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); - close(ifd); - return -1; + + if (len < 0) { + ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); + break; + } + + wrlen = write(ofd, buf, len); + if (errno == ENOMEM || errno == ENOSPC || wrlen != len) { + ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, wrlen, len, strerror(errno)); + break; } - do { - len = read(ifd, buf, sizeof(buf)); - if (len < 0) { - ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); - close(ifd); - close(ofd); - unlink(outfile); - } else if (len) { - res = write(ofd, buf, len); - if (errno == ENOMEM || errno == ENOSPC || res != len) { - ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); - close(ifd); - close(ofd); - unlink(outfile); - } - } - } while (len); - close(ifd); - close(ofd); - return 0; -#ifdef HARDLINK_WHEN_POSSIBLE - } else { - /* Hard link succeeded */ - return 0; } -#endif + + close(ifd); + close(ofd); + if (res) { + unlink(outfile); + } + + return res; } /*! |