Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com Message-ID: <779F20BCCE5AD31186A50008C75D9979171703@SILLDN_MAIL1> From: "Fifer, Eric" To: "'cygwin-developers AT sourceware DOT cygnus DOT com'" Subject: Problem with open() and O_CREAT Date: Fri, 17 Mar 2000 10:25:32 -0000 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2448.0) Content-Type: text/plain; charset="iso-8859-1" I originally sent the message below to Chris Faylor directly and he replied: >Could you forward your patch to the cygwin-developers mailing list? >I'd like Corrinna to look at it and approve it. It looks ok to >me but she understands what is going on there a little better. So ... -- I was looking over Charles Wilson's patches to gdbm and couldn't understand why they were necessary. Anyway, it turned out that he was working around a bug with the handling of O_CREAT when used with ntea/ntsec. According to my open() docs with O_CREAT: If the file exists, this flag has no effect except as noted under O_EXCL [...] And, MSDN CreateFile() has this to say: If the specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS (even though the function has succeeded). If the file does not exist before the call, GetLastError returns zero. Currently the file attributes are set regardless of whether the file already exists. Something like this should correct the behavior: diff -urp winsup.orig/cygwin/fhandler.cc winsup/cygwin/fhandler.cc --- winsup.orig/cygwin/fhandler.cc Wed Mar 15 04:55:13 2000 +++ winsup/cygwin/fhandler.cc Wed Mar 15 15:23:06 2000 @@ -388,7 +388,10 @@ fhandler_base::open (int flags, mode_t m goto done; } - if (flags & O_CREAT && get_device () == FH_DISK) + if (flags & O_CREAT && get_device () == FH_DISK && + !((creation_distribution == CREATE_ALWAYS || + creation_distribution == OPEN_ALWAYS) && + GetLastError () == ERROR_ALREADY_EXISTS)) set_file_attribute (has_acls (), get_win32_name (), mode); namehash_ = hash_path_name (0, get_win32_name ()); Here is an example of the current incorrect behavior: #include main() { int fd = open("creat.test", O_RDWR|O_CREAT, 0); } $ touch creat.test $ ls -l creat.test -rw-rw-rw- 1 fifere SIL_Equi 0 Mar 15 14:04 creat.test $ creat.exe $ ls -l creat.test ---------- 1 fifere SIL_Equi 0 Mar 15 14:04 creat.test Regards, Eric