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 sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Date: Mon, 29 Oct 2001 15:30:38 -0500 From: Christopher Faylor To: cygwin-developers AT cygwin DOT com Subject: Re: current repository: stat() doesn't set inode number correctly for magic devices Message-ID: <20011029153038.A16987@redhat.com> Reply-To: cygwin-developers AT cygwin DOT com Mail-Followup-To: cygwin-developers AT cygwin DOT com References: <20011029200229 DOT 18162 DOT qmail AT lizard DOT curl DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20011029200229.18162.qmail@lizard.curl.com> User-Agent: Mutt/1.3.21i On Mon, Oct 29, 2001 at 03:02:29PM -0500, Jonathan Kamens wrote: >With the current repository, if you call stat() on a device, e.g., >"/dev/null", the returned stat structure will have st_ino set to 0. >If you open() the same device and then call fstat() on it, the >returned stat structure will have st_ino correctly set to a non-zero >value. This is demonstrated by the program below. > >The problem is that the namehash field of the fhandler structure is >only set when open() is called. It is not set when the various >constructors for magic devices, e.g., >fhandler_dev_null::fhandler_dev_null, are called. > >This bug causes "echo foo > /dev/null" to fail in bash, because bash >stats a file before opening it, fstats it afterwards, and then >compares the inode numbers from before and after to confirm that it >hasn't been swapped out from under it. I don't have any problems typing echo foo >/dev/null. I wonder why this is different for you. Maybe you're doing something with noclobber or something. >When I was thinking about how this might be fixed, I wanted to avoid >adding separate calls to hash_path_name in every one of the >constructors for magic devices, so I thought that the correct place to >fix this would be in build_fhandler_from_name. Unfortunately, it >can't be done there because "namehash" is a private field and there's >no public setter for it. I don't know which is the most appropriate >fix -- adding separate calls to hash_path_name to set the hash in >every one of the device constructors; adding a public setter for the >namehash field so that it can be set from buildhandler_from_name; >making namehash a public field so it can be set directly; or some >other solution I haven't considered. > >This probably needs to be fixed before 1.3.4 is released (sorry!). Yep, it does. But you've analyzed it far enough for a simple fix to be feasible. The change below seems to do the right thing. I think it is even the most correct fix since namehash *should* be changed when the filename changes, so putting the namehash setting in set_name makes sense. Thanks for the analysis, Jonathan. cgf Index: fhandler.cc =================================================================== RCS file: /cvs/uberbaum/winsup/cygwin/fhandler.cc,v retrieving revision 1.99 diff -u -p -r1.99 fhandler.cc --- fhandler.cc 2001/10/24 04:16:45 1.99 +++ fhandler.cc 2001/10/29 20:26:55 @@ -189,6 +189,7 @@ fhandler_base::set_name (const char *uni system_printf ("fatal error. strdup failed"); exit (ENOMEM); } + namehash = hash_path_name (0, win32_path_name); } void @@ -411,7 +412,6 @@ fhandler_base::open (path_conv *, int fl && !allow_ntsec && allow_ntea) set_file_attribute (has_acls (), get_win32_name (), mode); - namehash = hash_path_name (0, get_win32_name ()); set_io_handle (x); int bin; int fmode;