]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Updated filestream destructor to block until move is complete when cache is used
authorMatthew Jordan <mjordan@digium.com>
Tue, 5 Jul 2011 13:23:57 +0000 (13:23 +0000)
committerMatthew Jordan <mjordan@digium.com>
Tue, 5 Jul 2011 13:23:57 +0000 (13:23 +0000)
When a cache directory is used, the process is forked and a mv command is executed to move the temporary file to the permanent location.  This caused issues with voicemail, where a race condition occurred when the parent expected the file to be in the permanent location prior to the mv command completing.  The parent process is now blocked until the mv command completes.

(closes issue ASTERISK-17724)
Reported by: Adiren P.
Tested by: mjordan

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@326209 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/file.c

index 9195748af46ece9bf4932fc06a32d30e5dd3b4ad..7b01646e5e70e8b40a0fd11ccbc99f894c5ded4c 100644 (file)
@@ -29,6 +29,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include <dirent.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <math.h>
 
 #include "asterisk/_private.h" /* declare ast_file_init() */
@@ -291,6 +292,8 @@ static int exts_compare(const char *exts, const char *type)
 static void filestream_destructor(void *arg)
 {
        struct ast_filestream *f = arg;
+       int status;
+       int pid = -1;
 
        /* Stop a running stream if there is one */
        if (f->owner) {
@@ -308,8 +311,14 @@ static void filestream_destructor(void *arg)
                ast_translator_free_path(f->trans);
 
        if (f->realfilename && f->filename) {
-               if (ast_safe_fork(0) == 0) {
+               pid = ast_safe_fork(0);
+               if (!pid) {
                        execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
+                       _exit(1);
+               }
+               else if (pid > 0) {
+                       /* Block the parent until the move is complete.*/
+                       waitpid(pid, &status, 0);
                }
        }