[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