This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: fdopen() not guaranteed to have Python semantics
Type: Stage:
Components: Library (Lib) Versions: Python 2.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: georg.brandl, movement, titty
Priority: normal Keywords:

Created on 2006-03-31 04:37 by movement, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (5)
msg27970 - (view) Author: John Levon (movement) Date: 2006-03-31 04:37
The specification for seek() says:

 seek(  	offset[, whence])
    Note that if the file is opened for appending (mode
'a' or 'a+'), any seek() operations will be undone at
the next write.

Consider operating on an fdopen()ed file. The Python
source simply calls into the OS-provided fdopen():

http://pxr.openlook.org/pxr/source/Modules/posixmodule.c#3530

However, the POSIX standard

http://www.opengroup.org/onlinepubs/009695399/functions/fdopen.html

says:

"Although not explicitly required by this volume of
IEEE Std 1003.1-2001, a good implementation of append
(a) mode would cause the O_APPEND flag to be set."

Thus, to ensure Python semantics, Python's fdopen()
must perform an fcntl() to ensure O_APPEND is set.

For example, on Solaris, this optional O_APPEND
behaviour is not applied:

http://cvs.opensolaris.org/source/xref/on/usr/src/lib/libc/port/stdio/fdopen.c?r=1.22#97

This has recently caused serious problems with the
Mercurial SCM.
msg27971 - (view) Author: Ralf Schmitt (titty) Date: 2006-03-31 16:20
Logged In: YES 
user_id=17929

freebsd 4.11 shows the same behaviour.

import fcntl
import os

def test_fdopen_append():
    
    def is_append(fd):
        return bool(fcntl.fcntl(fd, fcntl.F_GETFL) &
os.O_APPEND)


    fd = os.open("foo.txt", os.O_RDWR | os.O_CREAT)
    assert fd != -1
    
    print "is_append:", is_append(fd)
    
    f=os.fdopen(fd, 'a')
    print "after fdopen is_append:", is_append(fd)

    assert is_append(fd)

test_fdopen_append()
msg27972 - (view) Author: Ralf Schmitt (titty) Date: 2006-03-31 17:02
Logged In: YES 
user_id=17929

patch here:
http://sourceforge.net/tracker/index.php?func=detail&aid=1462227&group_id=5470&atid=305470
msg27973 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-03-31 20:00
Logged In: YES 
user_id=849994

Applied patch in rev. 43501, 43502.
msg27974 - (view) Author: John Levon (movement) Date: 2006-03-31 20:15
Logged In: YES 
user_id=53034

Shouldn't the documentation now state this change in
behaviour? i.e. if fdopen() fails, O_APPEND may still have
become set.

This behaviour seems a little odd to me in fact. Can't we set
fcntl after a successful fdopen()[1]? Also wouldn't it be
useful to point to the standards sentence I quote above?

[1] not sure what the ALLOW_THREAD thing does?
History
Date User Action Args
2022-04-11 14:56:16adminsetgithub: 43117
2006-03-31 04:37:58movementcreate