diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclIOUtil.c | 34 | ||||
-rw-r--r-- | tests/ioUtil.test | 23 |
3 files changed, 49 insertions, 14 deletions
@@ -1,3 +1,9 @@ +2007-08-15 Donal K. Fellows <donal.k.fellows@man.ac.uk> + + * generic/tclIOUtil.c (TclGetOpenModeEx): Only set the O_APPEND flag + * tests/ioUtil.test (ioUtil-4.1): on a channel for the 'a' + mode and not for 'a+'. [Bug 1773127] + 2007-08-14 Miguel Sofer <msofer@users.sf.net> * generic/tclExecute.c (INST_INVOKE*): peephole opt, do not get diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 5725e45..90cc2c4 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -17,7 +17,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIOUtil.c,v 1.145 2007/04/25 19:09:03 kennykb Exp $ + * RCS: @(#) $Id: tclIOUtil.c,v 1.146 2007/08/15 17:43:58 dkf Exp $ */ #include "tclInt.h" @@ -1569,22 +1569,16 @@ TclGetOpenModeEx( mode = O_WRONLY|O_CREAT|O_TRUNC; break; case 'a': - /* [Bug 680143]. - * Added O_APPEND for proper automatic - * seek-to-end-on-write by the OS. + /* + * Added O_APPEND for proper automatic seek-to-end-on-write by the + * OS. [Bug 680143] */ + mode = O_WRONLY|O_CREAT|O_APPEND; *seekFlagPtr = 1; break; default: - error: - *seekFlagPtr = 0; - *binaryPtr = 0; - if (interp != NULL) { - Tcl_AppendResult(interp, "illegal access mode \"", modeString, - "\"", NULL); - } - return -1; + goto error; } i=1; while (i<3 && modeString[i]) { @@ -1593,7 +1587,12 @@ TclGetOpenModeEx( } switch (modeString[i++]) { case '+': - mode &= ~(O_RDONLY|O_WRONLY); + /* + * Must remove the O_APPEND flag so that the seek command + * works. [Bug 1773127] + */ + + mode &= ~(O_RDONLY|O_WRONLY|O_APPEND); mode |= O_RDWR; break; case 'b': @@ -1607,6 +1606,15 @@ TclGetOpenModeEx( goto error; } return mode; + + error: + *seekFlagPtr = 0; + *binaryPtr = 0; + if (interp != NULL) { + Tcl_AppendResult(interp, "illegal access mode \"", modeString, + "\"", NULL); + } + return -1; } /* diff --git a/tests/ioUtil.test b/tests/ioUtil.test index c2894ce..8165a2e 100644 --- a/tests/ioUtil.test +++ b/tests/ioUtil.test @@ -8,7 +8,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: ioUtil.test,v 1.17 2006/11/03 00:34:53 hobbs Exp $ +# RCS: @(#) $Id: ioUtil.test,v 1.18 2007/08/15 17:43:59 dkf Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 @@ -301,6 +301,27 @@ test ioUtil-3.8 {TclOpenFileChannelDeleteProc: Verify that all procs have been d list $err9 $err10 $err11 } {{"TestOpenFileChannelProc1": could not be deleteed} {"TestOpenFileChannelProc2": could not be deleteed} {"TestOpenFileChannelProc3": could not be deleteed}} +test ioUtil-4.1 {open ... a+ must not use O_APPEND: Bug 1773127} -setup { + set f [tcltest::makeFile {} ioutil41.tmp] + set fid [open $f wb] + puts -nonewline $fid 123 + close $fid +} -body { + set fid [open $f ab+] + puts -nonewline $fid 456 + seek $fid 2 + set d [read $fid 2] + seek $fid 4 + puts -nonewline $fid x + close $fid + set fid [open $f rb] + append d [read $fid] + close $fid + return $d +} -cleanup { + tcltest::removeFile $f +} -result 341234x6 + cd $oldpwd # cleanup |