delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/2001/10/29/15:03:50

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-developers-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-developers-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-developers-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com
Date: 29 Oct 2001 15:02:29 -0500
Message-ID: <20011029200229.18162.qmail@lizard.curl.com>
From: Jonathan Kamens <jik AT curl DOT com>
To: cygwin-developers AT cygwin DOT com
Subject: current repository: stat() doesn't set inode number correctly
for magic devices

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'm not submitting a patch because I've been unable to convince myself
where the correct place to fix this is.  I suspect Corinna has an
opinion, since she just wrote this code, so she should probably be the
one to figure it out :-).

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!).

  jik

                      *************************

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

#define STATFILE "/dev/null"

main()
{
  struct stat buf;
  int r = stat(STATFILE, &buf);
  int fd;

  if (r < 0) {
    perror("stat");
    exit(1);
  }

  printf("inode number of unopened %s is %d\n", STATFILE, buf.st_ino);

  fd = open(STATFILE, O_RDONLY, 0);
  if (fd < 0) {
    perror("open");
    exit(1);
  }

  r = fstat(fd, &buf);
  if (r < 0) {
    perror("fstat");
    exit(1);
  }
  
  printf("inode number of opened %s is %d\n", STATFILE, buf.st_ino);

  exit(0);
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019