Date: Sun, 8 Mar 1998 14:46:29 +0200 (IST) From: Eli Zaretskii To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Making `open' *really* fail under O_EXCL Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk 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