[Asterisk-Dev] behaviour of ast_writefile (file.c) and wav_rewrite (format_wav.c)

Steven Critchfield critch at basesys.com
Wed Feb 2 12:08:30 MST 2005


On Thu, 2005-01-13 at 14:28 -0500, Todd wrote:
> Hi all,
> 
> (I'm working with an asterisk that's a few months old - sorry if this is
> out of date.)
> 
> A while back I needed to resume a recording from an application.  I called
> ast_writefile with the O_APPEND flag thinking that would do the trick. 
> That, unfortunately, caused the header to be written to the middle of the
> file because append treats all writes as relative to where the end of the
> file used to be.  So I opened up format_wav.c and wrapped
> 
> if(comment!=NULL) {
>     ...
> }
> 
> around
> 
> if (write_header(fd)) {
>     free(tmp);
>     return NULL;
> }
> 
> in wav_rewrite.  (I'm only using wav files.)  Now, if I set comment to
> NULL in ast_writefile, the header is no longer written where it shouldn't
> be, but  the file gets truncated.  I thought maybe the trunc function
> wasn't working relative to where the end of the file was in append mode,
> but I'm not sure.  Finally, I commented the following in ast_writefile:
> 
> /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
> //if (!(flags & O_APPEND))
> //  myflags = O_TRUNC;
> fd = open(fn, /*flags |*/ myflags, mode);
> 
> I had to do this so it wasn't forced into O_TRUNC or O_APPEND mode.  And I
> can just set flags to 0.  Now it works, but I'd like to do it without the
> kludge and without making any code changes.


I finally made time to look at this problem.

It seems I hadn't been to bugged by this problem as I used gsm for most
of my testing. In gsm, I once we truncated to length the O_APPEND didn't
hurt as we then just wrote to the end. Wav files though need the header
updated at the beginning and O_APPEND can't be used to get that
functionality.

So I took a stab at hacking it a little bit cleaner. Since wav files are
harmed by O_APPEND, but there isn't really any other flag we could
harmlessly use here to turn off the otherwise expected O_TRUNC, I am
still using O_APPEND from AGI to signal appending to a file, but I
remove the O_APPEND before it goes to the open command. 

Here is my diff, line numbers don't match with current CVS but the diff
is valid for it as well.
pbx:/usr/src/asterisk# cvs diff -u file.c
Index: file.c
===================================================================
RCS file: /usr/cvsroot/asterisk/file.c,v
retrieving revision 1.39
diff -u -r1.39 file.c
--- file.c      6 Apr 2004 22:17:31 -0000       1.39
+++ file.c      2 Feb 2005 18:32:04 -0000
@@ -812,8 +812,12 @@
                return NULL;
        }
        /* set the O_TRUNC flag if and only if there is no O_APPEND
specified */
-       if (!(flags & O_APPEND)) 
+       if (flags & O_APPEND){ 
+               /* We really can't use O_APPEND as it will break WAV
header updates */
+               flags -= O_APPEND;
+       }else{
                myflags = O_TRUNC;
+       }
 
        myflags |= O_WRONLY | O_CREAT;

 
-- 
Steven Critchfield <critch at basesys.com>




More information about the asterisk-dev mailing list