Opened 14 years ago
Last modified 7 years ago
#230 assigned defect
chmod() fails on HPFS386 in UnixEAs mode if the file is read-only
Reported by: | dmik | Owned by: | bird |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | libc-backend | Version: | 0.6 |
Severity: | normal | Keywords: | chmod hpfs386 |
Cc: |
Description
The following test cases shows the problem:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> int main() { int fd = open("test", O_RDONLY | O_CREAT | O_EXCL, S_IRUSR | S_IRGRP | S_IROTH); if (fd == -1) { perror("open"); return 1; } close(fd); if (chmod("test", S_IRUSR | S_IRGRP | S_IROTH) == -1) perror("chmod"); return 0; }
This does not happen on HPFS or on JFS (e.g. chmod() succeeds in this case).
Attachments (1)
Change History (8)
comment:1 by , 14 years ago
by , 14 years ago
Attachment: | chmod_HPFS386.diff added |
---|
comment:2 by , 14 years ago
Component: | baselayout → libc-backend |
---|---|
Keywords: | chmod hpfs386 added |
Milestone: | → libc-0.6.4 |
Note to self: Add a hpfs386 check to the fs.c code as well.
comment:3 by , 14 years ago
JFYI, there is a bunch of similar problems. For example, DosQueryFileInfo(FIL_QUERYEASIZE) on a file opened with OPEN_ACCESS_WRITEONLY will also return ERROR_ACCESS_DENIED on HPFS386. The logic of the people who did that is understandable (they treat EAs as part of file data) but questionable. IMHO, EAs is the extension to the the standard attributes (DOS attributes, size, time, etc.) that can be read and modified regardless of whether the file is opened in read-only or write-only mode, and that makes more sense.
comment:4 by , 14 years ago
Status: | new → assigned |
---|
comment:5 by , 11 years ago
Milestone: | libc-0.6.6 |
---|
comment:6 by , 7 years ago
Note that there is also another related problem: calling DosQueryPathInfo(FIL_QUERYEASIZE)
on a file which is open will fail with ERROR_SHARING_VIOLATION (32) on any file system, not only HPFS386. This breaks the following code which is perfectly valid on Linux:
int fd = open("foobar", O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0666); // sometime later while fd is still open... chmod("foobar", 0777);
Under kLIBC this expectedly fails with EACCESS. There is a workaround that may be applied in kLIBC: use DosQUeryFileInfo
which succeeds in such a case. But in order to do so chmod
needs to walk through the open file descriptor list to see if there is an open file for the given file path in the current process. Until then, the original Linux source needs to be changed to explicitly use fchmod
that takes a file descriptor instead of a path as an argument (which is of course the proper way to do such a thing even on Linux since it's obviously faster).
Attached is a trivial fix that resets the FILE_READONLY bit before doing EAs.