Skip to content

[Windows] O_EXCL should override O_TRUNC #2505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 13, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CoreFoundation/Base.subproj/CFPlatform.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,15 +906,16 @@ CF_EXPORT int _NS_open(const char *name, int oflag, int pmode) {

DWORD dwCreationDisposition;
switch (oflag & (O_CREAT | O_EXCL | O_TRUNC)) {
case O_CREAT | O_EXCL | O_TRUNC:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that O_TRUNC is interesting, the behaviour between these two is different I believe.

Copy link
Contributor Author

@gmittert gmittert Sep 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is different, referencing https://pubs.opengroup.org/onlinepubs/9699919799/:

O_EXCL
If O_CREAT and O_EXCL are set, open() shall fail if the file exists. The check for the existence of the file and the creation of the file if it does not exist shall be atomic with respect to other threads executing open() naming the same filename in the same directory with O_EXCL and O_CREAT set. If O_EXCL and O_CREAT are set, and path names a symbolic link, open() shall fail and set errno to [EEXIST], regardless of the contents of the symbolic link. If O_EXCL is set and O_CREAT is not set, the result is undefined.

and

O_TRUNC
If the file exists and is a regular file, and the file is successfully opened O_RDWR or O_WRONLY, its length shall be truncated to 0, and the mode and owner shall be unchanged. It shall have no effect on FIFO special files or terminal device files. Its effect on other file types is implementation-defined. The result of using O_TRUNC without either O_RDWR or O_WRONLY is undefined.

In the case of O_CREAT | O_EXCL | O_TRUNC, if a file exists, then O_EXCL causes open to fail regardless of O_TRUNC. If the file doesn't exist, then O_TRUNC doesn't do anything and is the same as O_CREAT | O_EXCL.

case O_CREAT | O_EXCL:
dwCreationDisposition = CREATE_NEW;
break;
case O_CREAT | O_TRUNC:
dwCreationDisposition = CREATE_ALWAYS;
break;
case O_CREAT:
dwCreationDisposition = OPEN_ALWAYS;
break;
case O_EXCL:
dwCreationDisposition = CREATE_NEW;
break;
case O_TRUNC:
dwCreationDisposition = TRUNCATE_EXISTING;
break;
Expand Down