Package: libtag1 Version: 1.3.1-1 Severity: normal Tags: patch When opening a file, taglib uses the access() system call to determine whether a file is writable. It uses this information to decide whether to open it in read-write or read-only mode. access() is not a reliable means of determining the true accessability of a file. It is better to just try opening the file. Basically: don't ask for permission first, just do it, and the system will tell you if you can't.
The following alternate way of doing it is better. Moreover, it is cheaper (the original method always costs two system calls, this method can cost 2 system calls but might cost only 1). This bug manisfested itself to me when opening files with read only modes over an sshfs mount. sshfs does not implement the access() system call so fuse converts it into a no-op that always returns true. taglib then thinks it can open the file for writing, and tries and fails to do so and gives up. If it had tried, it could have opened the file for reading. -Phil -- System Information: Debian Release: 3.1 Architecture: i386 (i686) Kernel: Linux 2.6.8-2-686 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Versions of packages libtag1 depends on: ii libc6 2.3.2.ds1-22sarge4 GNU C Library: Shared libraries an ii libgcc1 1:3.4.3-13sarge1 GCC support library ii libstdc++5 1:3.3.5-13 The GNU Standard C++ Library v3 ii zlib1g 1:1.2.2-4.sarge.2 compression library - runtime -- no debconf information
--- taglib-1.3.1/taglib/toolkit/tfile.cpp 2006/12/19 17:05:58 1.1 +++ taglib-1.3.1/taglib/toolkit/tfile.cpp 2006/12/19 17:07:49 @@ -59,8 +59,12 @@ { d = new FilePrivate(::strdup(file)); - d->readOnly = !isWritable(file); - d->file = fopen(file, d->readOnly ? "r" : "r+"); + d->readOnly = 0; + d->file = fopen(file, "r+"); + if (!d->file) { + d->readOnly = 1; + d->file = fopen(file, "r"); + } if(!d->file) debug("Could not open file " + String(file));