Mail Archives: djgpp-workers/1998/03/08/07:47:48
There is a small window of opportunity for `open' to not fail under
O_EXCL, if some other process creates while `open' runs. Here's a patch
to close that window.
*** src/libc/posix/fcntl/open.c~0 Sun Nov 16 19:05:00 1997
--- src/libc/posix/fcntl/open.c Fri Mar 6 19:12:28 1998
*************** int
*** 17,25 ****
open(const char* filename, int oflag, ...)
{
int fd, dmode, bintext;
/* Check this up front, to reduce cost and minimize effect */
! if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
if (__file_exists(filename))
{
/* file exists and we didn't want it to */
--- 17,26 ----
open(const char* filename, int oflag, ...)
{
int fd, dmode, bintext;
+ int should_create = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
/* Check this up front, to reduce cost and minimize effect */
! if (should_create)
if (__file_exists(filename))
{
/* file exists and we didn't want it to */
*************** open(const char* filename, int oflag, ..
*** 39,60 ****
dmode = (*((&oflag)+1) & S_IWUSR) ? 0 : 1;
! fd = _open(filename, oflag);
!
! /* Under multi-taskers, such as Windows, our file might be open
! by some other program with DENY-NONE sharing bit, which fails
! the `_open' call above. Try again with DENY-NONE bit set,
! unless some sharing bits were already set in the initial call. */
! if (fd == -1
! && ((oflag & (SH_DENYNO | SH_DENYRW | SH_DENYRD | SH_DENYWR)) == 0))
! fd = _open(filename, oflag | SH_DENYNO);
! if (fd == -1 && oflag & O_CREAT)
! fd = _creat(filename, dmode);
if (fd == -1)
return fd; /* errno already set by _open or _creat */
! if (oflag & O_TRUNC)
if (_write(fd, 0, 0) < 0)
return -1;
--- 40,66 ----
dmode = (*((&oflag)+1) & S_IWUSR) ? 0 : 1;
! if (should_create)
! fd = _creatnew(filename, dmode, oflag & 0xff);
! else
! {
! fd = _open(filename, oflag);
!
! /* Under multi-taskers, such as Windows, our file might be open
! by some other program with DENY-NONE sharing bit, which fails
! the `_open' call above. Try again with DENY-NONE bit set,
! unless some sharing bits were already set in the initial call. */
! if (fd == -1
! && ((oflag & (SH_DENYNO | SH_DENYRW | SH_DENYRD | SH_DENYWR)) == 0))
! fd = _open(filename, oflag | SH_DENYNO);
! if (fd == -1 && oflag & O_CREAT)
! fd = _creat(filename, dmode);
! }
if (fd == -1)
return fd; /* errno already set by _open or _creat */
! if ((oflag & O_TRUNC) && !should_create)
if (_write(fd, 0, 0) < 0)
return -1;
*** src/docs/kb/wc202.t~4 Fri Mar 6 19:31:56 1998
--- src/docs/kb/wc202.txi Fri Mar 6 19:37:42 1998
***************
*** 340,342 ****
--- 340,348 ----
that no other process can neither read from nor write to it. In case of
a failure, @code{tmpfile} does not leak memory anymore.
@findex tmpfile
+
+ Previously, there was a small probability that a call to @code{open}
+ with the @code{O_CREAT} and @code{O_EXCL} bits set would succeed even
+ though the named file already existed (created by another process).
+ This window is now closed.
+ @findex open
- Raw text -